mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2026-02-03 12:03:44 +01:00
232
.cproject
232
.cproject
@@ -1,352 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.602829827" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.default" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNClient/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.debugging.sanitleak.778932189" name="Sanitize memory leak (-fsanitize=leak)" superClass="gnu.cpp.compiler.option.debugging.sanitleak" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.cpp.compiler.option.debugging.sanitpointers.435146187" name="Sanitize pointer operations (-fsanitize=pointer-compare -fsanitize=pointer-subtract)" superClass="gnu.cpp.compiler.option.debugging.sanitpointers" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.cpp.compiler.option.debugging.sanitaddress.501742254" name="Sanitize address (-fsanitize=address)" superClass="gnu.cpp.compiler.option.debugging.sanitaddress" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.1354093543" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DTLS"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.798283837" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="OPENSSL_API_COMPAT=30000"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1870583388" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="ssl"/>
|
||||
<listOptionValue builtIn="false" value="crypto"/>
|
||||
<listOptionValue builtIn="false" value="pthread"/>
|
||||
<listOptionValue builtIn="false" value="bluetooth"/>
|
||||
</option>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.170974409" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.link.option.shared.1648098307" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="MQTTSNGateway/src/linux/loralink|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNGateway/src/linux/udp6|MQTTSNClient|MQTTSNGateway/src/MQTTSNGWProxy.cpp|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/src/linux/xbee|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src/tests|MQTTSNGateway/src/tests/mainTestProcessFramework.cpp|ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
|
||||
<entry excluding="GatewayTester|src/linux/udp6|src/linux/udp|src/linux/dtls/SensorNetSubTask.cpp|GatewayTester/samples/ClientSub|GatewayTester/samples/ClientPubQoS-1|GatewayTester/samples/ClientPub|src/linux/rfcomm|src/tests|src/linux/xbee|src/mainLogmonitor.cpp|src/linux/loralink" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway"/>
|
||||
<entry excluding="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||
<entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.216116103" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1094525037" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.162341902" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.456127079" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1623573602" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.68366124" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1879517971" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
|
||||
</option>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNPacket/src|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNClient|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
|
||||
<entry excluding="udp6|xbee|loralink" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src/linux"/>
|
||||
|
||||
<entry excluding="MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/ClientPub|MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNGateway|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/GatewayTester/samples/ClientSub|MQTTSNClient|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src|MQTTSNPacket/src|MQTTSNGateway/GatewayTester|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
<entry excluding="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug"/>
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -5,8 +5,15 @@
|
||||
*.pyc
|
||||
/doc/MQTTSNClient/
|
||||
/doc/MQTTSNPacket/
|
||||
/rbmutex.key
|
||||
/ringbuffer.key
|
||||
rbmutex.key
|
||||
ringbuffer.key
|
||||
/Release/
|
||||
/Debug/
|
||||
/core
|
||||
Build/
|
||||
*.a
|
||||
CMakeFiles/
|
||||
*.cmake
|
||||
CMakeCache.txt
|
||||
bin/
|
||||
/build.gateway/
|
||||
@@ -1,48 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176156747064280842" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176157551606184930" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
</project>
|
||||
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
@@ -0,0 +1,77 @@
|
||||
eclipse.preferences.version=1
|
||||
fr.ac6.mcu.ide.source.checker.libnano.problem=Error
|
||||
fr.ac6.mcu.ide.source.checker.libnano.problem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Float formatting support\\")"}
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
|
||||
org.eclipse.cdt.qt.core.qtproblem=Warning
|
||||
org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>null}
|
||||
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_settings_version=1
|
||||
12
.travis.yml
12
.travis.yml
@@ -13,20 +13,12 @@ addons:
|
||||
- g++-4.8
|
||||
- cmake
|
||||
- cmake-data
|
||||
- bluez
|
||||
- libbluetooth-dev
|
||||
|
||||
script:
|
||||
- ./travis-build.sh
|
||||
|
||||
- cd MQTTSNGateway
|
||||
- make SENSORNET="xbee"
|
||||
- make SENSORNET="udp"
|
||||
- make SENSORNET="udp6"
|
||||
|
||||
- make test
|
||||
|
||||
- cd GatewayTester
|
||||
- make
|
||||
|
||||
notifications:
|
||||
emails:
|
||||
- tomoaki@tomy-tech.com
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# Ian Craggs - initial version
|
||||
#*******************************************************************************/
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
|
||||
PROJECT("paho-mqttsn" CXX)
|
||||
MESSAGE(STATUS "CMake version: " ${CMAKE_VERSION})
|
||||
MESSAGE(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME})
|
||||
@@ -39,3 +39,4 @@ INCLUDE(CPack)
|
||||
ENABLE_TESTING()
|
||||
|
||||
ADD_SUBDIRECTORY(MQTTSNPacket)
|
||||
ADD_SUBDIRECTORY(MQTTSNGateway)
|
||||
16
MQTTSNGateway/CMakeLists.txt
Normal file
16
MQTTSNGateway/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2022 a1lu
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# Contributors:
|
||||
# a1lu - initial version
|
||||
#*******************************************************************************/
|
||||
ADD_SUBDIRECTORY(src)
|
||||
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
Binary file not shown.
@@ -20,6 +20,10 @@ CPPSRCS := \
|
||||
$(SUBDIR)/LGwProxy.cpp \
|
||||
$(SUBDIR)/LMqttsnClient.cpp \
|
||||
$(SUBDIR)/LNetworkUdp.cpp \
|
||||
$(SUBDIR)/LNetworkUdp6.cpp \
|
||||
$(SUBDIR)/LNetworkRfcomm.cpp \
|
||||
$(SUBDIR)/LNetworkDtls.cpp \
|
||||
$(SUBDIR)/LNetworkDtls6.cpp \
|
||||
$(SUBDIR)/LPublishManager.cpp \
|
||||
$(SUBDIR)/LRegisterManager.cpp \
|
||||
$(SUBDIR)/LSubscribeManager.cpp \
|
||||
@@ -36,12 +40,14 @@ $(SUBDIR)/Util.cpp \
|
||||
CXX := g++
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDES += -I$(SUBDIR)
|
||||
DEFS :=
|
||||
LIBS +=
|
||||
INCLUDES += -I$(SUBDIR) -I/usr/local/opt/openssl/include
|
||||
DEF1 :=
|
||||
DEF2 :=
|
||||
DEFS := -D$(SN) $(DEF1) $(DEF2)
|
||||
LIBS += -L/usr/local/lib -L/usr/local/opt/openssl/lib
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD :=
|
||||
LDADD := -lssl -lcrypto $(LDADDBLT)
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGTEST)
|
||||
@@ -75,23 +81,23 @@ $(PROGQOS): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/$(QOSAPPL).o
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
###Gateway Test Program.
|
||||
# Gateway Test Program.
|
||||
**sample/mainTest.cpp** is a Test sample coading.
|
||||
Each test is described as one function. test1(), test2()...
|
||||
````
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*
|
||||
* you can use 4 commands in Test functions
|
||||
*
|
||||
* 1) PUBLISH(const char* topicName,
|
||||
* uint8_t* payload,
|
||||
* uint16_t len,
|
||||
* uint8_t qos,
|
||||
* bool retain = false);
|
||||
*
|
||||
* 2) SUBSCRIBE(const char* topicName,
|
||||
* TopicCallback onPublish,
|
||||
* uint8_t qos);
|
||||
*
|
||||
* 3) UNSUBSCRIBE(const char* topicName);
|
||||
*
|
||||
* 4) DISCONNECT(uint16_t sleepInSecs);
|
||||
*
|
||||
*------------------------------------------------------*/
|
||||
|
||||
```
|
||||
void test1(void)
|
||||
{
|
||||
char payload[300];
|
||||
@@ -36,9 +15,35 @@ void test2(void)
|
||||
uint8_t qos = 1;
|
||||
SUBSCRIBE(topic2, on_publish02, qos);
|
||||
}
|
||||
````
|
||||
**TEST_LIST** is a test senario. Test functions are executed one by one.
|
||||
````
|
||||
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* MQTT-SN GATEWAY TEST CLIENT
|
||||
*
|
||||
* Supported functions.
|
||||
*
|
||||
* void PUBLISH ( const char* topicName, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void PUBLISH ( uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void SUBSCRIBE ( const char* topicName, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void UNSUBSCRIBE ( const char* topicName );
|
||||
*
|
||||
* void UNSUBSCRIBE ( uint16_t topicId );
|
||||
*
|
||||
* void DISCONNECT ( uint16_t sleepInSecs );
|
||||
*
|
||||
* void CONNECT ( void );
|
||||
*
|
||||
* void DISPLAY( format, .....); <== instead of printf()
|
||||
*--------------------------------------------------------------------------
|
||||
|
||||
```
|
||||
**TEST_LIST** is a test senario. Test functions are executed interactively.
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* A List of Test Tasks
|
||||
*------------------------------------------------------*/
|
||||
@@ -52,68 +57,61 @@ TEST_LIST = {// e.g. TEST( Label, Test),
|
||||
TEST("Disconnect", test5),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
````
|
||||
|
||||
### **step1. Build **
|
||||
````
|
||||
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
|
||||
$ make
|
||||
$ make install
|
||||
$ make clean
|
||||
```
|
||||
MQTT-SNGatewayTester program is copied into ../../../ directory.
|
||||
|
||||
**UDP**, **DTLS**, **UDP6**, **DTLS6** or **Bluetooth** is available as a sensor network.
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* UDP, DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6, DTLS6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||
"ff12::feed:caca:dead", // Multicast group IP
|
||||
"wlp4s0",
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
### **step2. Execute Gateway Tester.**
|
||||
## How to Build
|
||||
```
|
||||
copy codes from the github.
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
|
||||
$ ./build.sh [udp | udp6 | dtls | dtls6 | rfcomm]
|
||||
```
|
||||
|
||||
````
|
||||
$ cd ../../..
|
||||
$ ./MQTT-SNGatewayTester
|
||||
|
||||
## Execute Gateway Tester
|
||||
```
|
||||
$ ./Build/MQTT-SNGatewayTester
|
||||
|
||||
***************************************************************************
|
||||
* MQTT-SN Gateway Tester
|
||||
* MQTT-SN Gateway Tester DTLS
|
||||
* Part of Project Paho in Eclipse
|
||||
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
|
||||
*
|
||||
* Author : Tomoaki YAMAGUCHI
|
||||
* Version: 0.0.0
|
||||
* Version: 2.0.0
|
||||
***************************************************************************
|
||||
|
||||
Attempting to Connect the Broker.....
|
||||
Execute "Step0:Connect" ? ( y/n ) :
|
||||
|
||||
sendto 225.1.1.1 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.5 :1883 03 01 00
|
||||
sendto 225.1.1.1 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.5 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.17 :10000 03 02 01
|
||||
sendto 192.168.11.17 :10000 13 04 0c 01 03 84 47 61 74 65 77 61 79 54 65 73 74 65 72
|
||||
|
||||
recved 192.168.11.17 :10000 02 06
|
||||
sendto 192.168.11.17 :10000 0c 07 00 77 69 6c 6c 54 6f 70 69 63
|
||||
|
||||
recved 192.168.11.17 :10000 02 08
|
||||
sendto 192.168.11.17 :10000 0d 09 77 69 6c 6c 4d 65 73 73 61 67 65
|
||||
|
||||
recved 192.168.11.17 :10000 03 05 00
|
||||
|
||||
|
||||
Connected to the Broker
|
||||
|
||||
Attempting OnConnect.....
|
||||
sendto 192.168.11.17 :10000 13 12 20 00 01 74 79 34 74 77 2f 63 6c 69 65 6e 74 49 64
|
||||
|
||||
recved 192.168.11.17 :10000 08 13 20 00 01 00 01 00
|
||||
|
||||
|
||||
SUBSCRIBE complete. ty4tw/clientId
|
||||
|
||||
OnConnect complete
|
||||
Test Ready.
|
||||
|
||||
Execute Publish topic1 Test ? ( Y/N ) :
|
||||
|
||||
````
|
||||
```
|
||||
|
||||
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEF1="DEF1=${2}"
|
||||
DEF2="DEF2=${3}"
|
||||
|
||||
if [ $1 == "udp" ] ; then
|
||||
make SN=UDP $DEF1 $DEF2
|
||||
elif [ $1 == "udp6" ] ; then
|
||||
make SN=UDP6 $DEF1 $DEF2
|
||||
elif [ $1 == "rfcomm" ] ; then
|
||||
export LDADDBLT=-lbluetooth
|
||||
make SN=RFCOMM $DEF1 $DEF2
|
||||
elif [ $1 == "dtls" ] ; then
|
||||
make SN=DTLS $DEF1 $DEF2
|
||||
elif [ $1 == "dtls6" ] ; then
|
||||
make SN=DTLS6 $DEF1 $DEF2
|
||||
elif [ $1 == "clean" ] ; then
|
||||
make clean
|
||||
else
|
||||
echo "Usage: build.sh [ udp | udp6 | rfcomm | dtls | dtls6 | clean]"
|
||||
fi
|
||||
|
||||
|
||||
@@ -51,13 +51,30 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"ClientPUB", // ClientId
|
||||
UDPCONF = { "ClientPUB", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20010, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "ClientPUB", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "ClientPUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
*------------------------------------------------------*/
|
||||
@@ -117,7 +134,7 @@ void publishTopic57(void)
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic57\" \n");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos);
|
||||
PUBLISH(topic57, (uint8_t* )payload, strlen(payload), qos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,13 +51,30 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"QoS-1_Client01", // ClientId
|
||||
UDPCONF = { "QoS-1_Client01", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20001, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "QoS-1_Client01", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "QoS-1_Client01", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
*------------------------------------------------------*/
|
||||
|
||||
@@ -51,13 +51,30 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"ClientSUB", // ClientId
|
||||
UDPCONF = { "ClientSUB", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20011, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "ClientSUB", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "ClientSUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
*------------------------------------------------------*/
|
||||
|
||||
@@ -49,20 +49,36 @@ extern LMqttsnClient* theClient;
|
||||
extern LScreen* theScreen;
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
* UDP,DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"GatewayTestClient", // ClientId
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6, DTLS6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
*------------------------------------------------------*/
|
||||
MQTTSNCONF = {
|
||||
60, //KeepAlive [seconds]
|
||||
MQTTSNCONF = { 60, //KeepAlive [seconds]
|
||||
true, //Clean session
|
||||
300, //Sleep duration [seconds]
|
||||
"", //WillTopic
|
||||
@@ -78,12 +94,12 @@ const char* topic1 = "ty4tw/topic1";
|
||||
const char* topic2 = "ty4tw/topic2";
|
||||
const char* topic3 = "ty4tw/topic3";
|
||||
const char* topic4 = "ty4tw/topic4";
|
||||
const char* topic40 = "ty4tw/#";
|
||||
const char* topic51 = "ty4tw/topic5/1";
|
||||
const char* topic52 = "ty4tw/topic5/2";
|
||||
const char* topic53 = "ty4tw/topic5/3";
|
||||
const char* topic50 = "ty4tw/topic5/+";
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Callback routines for Subscribed Topics
|
||||
*------------------------------------------------------*/
|
||||
@@ -112,37 +128,40 @@ int on_Topic03(uint8_t* pload, uint16_t ploadlen)
|
||||
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
|
||||
*------------------------------------------------------*/
|
||||
|
||||
SUBSCRIBE_LIST = {// e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||
SUBSCRIBE_LIST =
|
||||
{ // e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
|
||||
END_OF_SUBSCRIBE_LIST
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*------------------------------------------------------*/
|
||||
void subscribePredefTopic1(void)
|
||||
{
|
||||
SUBSCRIBE(1, on_Topic03, QoS1);
|
||||
SUBSCRIBE_PREDEF(1, on_Topic03, QoS1);
|
||||
}
|
||||
|
||||
void publishTopic1(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/Topic1\" \n");
|
||||
sprintf(payload, "publish \"ty4tw/topic1\" \n");
|
||||
PUBLISH(topic1, (uint8_t* )payload, strlen(payload), QoS0);
|
||||
}
|
||||
|
||||
void subscribeTopic10(void)
|
||||
{
|
||||
SUBSCRIBE(10, on_Topic02, QoS1);
|
||||
}
|
||||
|
||||
void publishTopic2(void)
|
||||
{
|
||||
char payload[300];
|
||||
@@ -150,6 +169,22 @@ void publishTopic2(void)
|
||||
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)
|
||||
@@ -180,41 +215,70 @@ void asleep(void)
|
||||
DISCONNECT(theMqcon.sleepDuration);
|
||||
}
|
||||
|
||||
void onconnect(void)
|
||||
{
|
||||
ONCONNECT();
|
||||
}
|
||||
|
||||
void connect(void)
|
||||
{
|
||||
CONNECT();
|
||||
}
|
||||
|
||||
void DisableAutoPingreq(void)
|
||||
{
|
||||
SetAutoPingReqMode(false);
|
||||
}
|
||||
|
||||
void CleanSessionOff(void)
|
||||
{
|
||||
SetCleanSession(false);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------
|
||||
* A List of Test functions is valid in case of
|
||||
* line 23 of LMqttsnClientApp.h is commented out.
|
||||
* //#define CLIENT_MODE
|
||||
*------------------------------------------------------*/
|
||||
|
||||
TEST_LIST = {// e.g. TEST( Label, Test),
|
||||
TEST("Step0:Subscribe predef topic1", subscribePredefTopic1),
|
||||
TEST("Step1:Publish topic1", publishTopic1),
|
||||
TEST("Step2:Publish topic2", publishTopic2),
|
||||
TEST("Step3:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||
TEST_LIST =
|
||||
{ // e.g. TEST( Label, Test),
|
||||
TEST("Step0:Connect", connect),
|
||||
TEST("Step1:Subscribe list", onconnect),
|
||||
TEST("Step2:Subscribe predef topic1", subscribePredefTopic1),
|
||||
TEST("Step3:Publish topic1", publishTopic1),
|
||||
TEST("Step4:Publish topic2", publishTopic2),
|
||||
TEST("Step5:Unsubscribe topic2", unsubscribe),
|
||||
TEST("Step5:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||
TEST("Step6:Publish topic2", publishTopic2),
|
||||
TEST("Step7:subscribe again", subscribechangeCallback),
|
||||
TEST("Step7:Unsubscribe topic2", unsubscribe),
|
||||
TEST("Step8:Publish topic2", publishTopic2),
|
||||
TEST("Step9:Sleep ", asleep),
|
||||
TEST("Step10:Publish topic1", publishTopic1),
|
||||
TEST("Step11:Disconnect", disconnect),
|
||||
TEST("Step9:subscribe again", subscribechangeCallback),
|
||||
TEST("Step10:Publish topic2", publishTopic2),
|
||||
|
||||
TEST("Step11:Sleep ", asleep),
|
||||
TEST("Step12:Publish topic1", publishTopic1),
|
||||
TEST("Step13:Disconnect", disconnect),
|
||||
TEST("Step14:Publish topic2", publishTopic1),
|
||||
TEST("Step15:Connect", connect),
|
||||
TEST("Step16:Publish topic2", publishTopic2),
|
||||
TEST("Step17:Auto Pingreq mode off", DisableAutoPingreq),
|
||||
TEST("Step18:Publish topic2", publishTopic1),
|
||||
TEST("Step19:Disconnect", disconnect),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* List of tasks is valid in case of line23 of
|
||||
* LMqttsnClientApp.h is uncommented.
|
||||
* #define CLIENT_MODE
|
||||
*------------------------------------------------------*/
|
||||
TASK_LIST = {// e.g. TASK( task, executing duration in second),
|
||||
TASK_LIST =
|
||||
{ // e.g. TASK( task, executing duration in second),
|
||||
TASK(publishTopic1, 4),// publishTopic1() is executed every 4 seconds
|
||||
TASK(publishTopic2, 7),// publishTopic2() is executed every 7 seconds
|
||||
END_OF_TASK_LIST
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Initialize function
|
||||
*------------------------------------------------------*/
|
||||
@@ -223,5 +287,4 @@ void setup(void)
|
||||
SetForwarderMode(false);
|
||||
}
|
||||
|
||||
|
||||
/***************** END OF PROGRAM ********************/
|
||||
|
||||
@@ -57,6 +57,8 @@ LGwProxy::LGwProxy()
|
||||
_initialized = 0;
|
||||
_isForwarderMode = false;
|
||||
_isQoSMinus1Mode = false;
|
||||
_isPingReqMode = true;
|
||||
_isAutoConnectMode = true;
|
||||
}
|
||||
|
||||
LGwProxy::~LGwProxy()
|
||||
@@ -64,16 +66,20 @@ LGwProxy::~LGwProxy()
|
||||
_topicTbl.clearTopic();
|
||||
}
|
||||
|
||||
void LGwProxy::initialize(LUdpConfig netconf, LMqttsnConfig mqconf)
|
||||
void LGwProxy::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
|
||||
{
|
||||
_network.initialize(netconf);
|
||||
_clientId = netconf.clientId;
|
||||
_willTopic = mqconf.willTopic;
|
||||
_willMsg = mqconf.willMsg;
|
||||
_qosWill = mqconf.willQos;
|
||||
_retainWill = mqconf.willRetain;
|
||||
_cleanSession = mqconf.cleanSession;
|
||||
_tkeepAlive = mqconf.keepAlive;
|
||||
if (_network.initialize(netconf) == false)
|
||||
{
|
||||
DISPLAY("Can't open SensorNetwork\n");
|
||||
exit(-1);
|
||||
}
|
||||
_clientId = netconf->clientId;
|
||||
_willTopic = mqconf->willTopic;
|
||||
_willMsg = mqconf->willMsg;
|
||||
_qosWill = mqconf->willQos;
|
||||
_retainWill = mqconf->willRetain;
|
||||
_cleanSession = mqconf->cleanSession;
|
||||
_tkeepAlive = mqconf->keepAlive;
|
||||
_initialized = 1;
|
||||
}
|
||||
|
||||
@@ -85,6 +91,12 @@ void LGwProxy::connect()
|
||||
{
|
||||
pos = _msg;
|
||||
|
||||
if (!_network.isBroadcastable() && _status == GW_LOST)
|
||||
{
|
||||
_status = GW_CONNECTING;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_status == GW_LOST)
|
||||
{
|
||||
|
||||
@@ -188,7 +200,24 @@ int LGwProxy::getConnectResponce(void)
|
||||
{
|
||||
_network.setGwAddress();
|
||||
_gwId = _mqttsnMsg[1];
|
||||
|
||||
#if defined(DTLS) || defined(DTLS6)
|
||||
for (int i = 0; i < MQTTSN_RETRY_COUNT; i++)
|
||||
{
|
||||
if (_network.sslConnect() > 0)
|
||||
{
|
||||
_status = GW_CONNECTING;
|
||||
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection established.\033[0m\033[0;37m\n\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection failed.\033[0m\033[0;37m\n\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
_status = GW_CONNECTING;
|
||||
#endif
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
|
||||
{
|
||||
@@ -230,11 +259,14 @@ int LGwProxy::getConnectResponce(void)
|
||||
}
|
||||
|
||||
void LGwProxy::reconnect(void)
|
||||
{
|
||||
if (_isAutoConnectMode)
|
||||
{
|
||||
D_MQTTLOG("...Gateway reconnect\r\n");
|
||||
_status = GW_DISCONNECTED;
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
void LGwProxy::disconnect(uint16_t secs)
|
||||
{
|
||||
@@ -395,7 +427,7 @@ int LGwProxy::getMessage(void)
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_DISCONNECT)
|
||||
{
|
||||
_status = GW_LOST;
|
||||
_status = GW_DISCONNECTED;
|
||||
_gwAliveTimer.stop();
|
||||
_keepAliveTimer.stop();
|
||||
}
|
||||
@@ -586,7 +618,7 @@ uint16_t LGwProxy::getNextMsgId(void)
|
||||
|
||||
void LGwProxy::checkPingReq(void)
|
||||
{
|
||||
if ( _isQoSMinus1Mode )
|
||||
if (_isQoSMinus1Mode || _isPingReqMode == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -671,3 +703,23 @@ void LGwProxy::setQoSMinus1Mode(bool valid)
|
||||
{
|
||||
_isQoSMinus1Mode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setPingReqMode(bool valid)
|
||||
{
|
||||
_isPingReqMode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setAutoConnectMode(bool valid)
|
||||
{
|
||||
_isAutoConnectMode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setSessionMode(bool valid)
|
||||
{
|
||||
_cleanSession = valid;
|
||||
}
|
||||
|
||||
uint8_t LGwProxy::getStatus(void)
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LRegisterManager.h"
|
||||
#include "LTimer.h"
|
||||
#include "LTopicTable.h"
|
||||
@@ -42,6 +46,7 @@ using namespace std;
|
||||
#define GW_SLEEPING 10
|
||||
#define GW_DISCONNECTED 11
|
||||
#define GW_SLEPT 12
|
||||
#define SSL_CONNECTING 13
|
||||
|
||||
#define GW_WAIT_PINGRESP 1
|
||||
|
||||
@@ -54,7 +59,7 @@ public:
|
||||
LGwProxy();
|
||||
~LGwProxy();
|
||||
|
||||
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf);
|
||||
void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
|
||||
void connect(void);
|
||||
void disconnect(uint16_t sec = 0);
|
||||
int getMessage(void);
|
||||
@@ -67,6 +72,9 @@ public:
|
||||
void setAdvertiseDuration(uint16_t duration);
|
||||
void setForwarderMode(bool valid);
|
||||
void setQoSMinus1Mode(bool valid);
|
||||
void setPingReqMode(bool valid);
|
||||
void setAutoConnectMode(bool valid);
|
||||
void setSessionMode(bool valid);
|
||||
void reconnect(void);
|
||||
int writeMsg(const uint8_t* msg);
|
||||
void setPingReqTimer(void);
|
||||
@@ -74,6 +82,7 @@ public:
|
||||
LTopicTable* getTopicTable(void);
|
||||
LRegisterManager* getRegisterManager(void);
|
||||
const char* getClientId(void);
|
||||
uint8_t getStatus(void);
|
||||
private:
|
||||
int readMsg(void);
|
||||
void writeGwMsg(void);
|
||||
@@ -111,6 +120,8 @@ private:
|
||||
uint16_t _tWake;
|
||||
bool _isForwarderMode;
|
||||
bool _isQoSMinus1Mode;
|
||||
bool _isPingReqMode;
|
||||
bool _isAutoConnectMode;
|
||||
char _msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ extern TaskList theTaskList[];
|
||||
extern TestList theTestList[];
|
||||
extern OnPublishList theOnPublishList[];
|
||||
extern MQTTSNCONF;
|
||||
extern UDPCONF;
|
||||
extern SENSORNET_CONFIG_t theNetcon;
|
||||
extern void setup(void);
|
||||
|
||||
/*=====================================
|
||||
@@ -50,7 +50,20 @@ int main(int argc, char** argv)
|
||||
#ifndef CLIENT_MODE
|
||||
char c = 0;
|
||||
printf("\n%s", PAHO_COPYRIGHT4);
|
||||
printf("\n%s\n", PAHO_COPYRIGHT0);
|
||||
printf("\n%s", PAHO_COPYRIGHT0);
|
||||
#if defined(UDP)
|
||||
printf("UDP ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(UDP6)
|
||||
printf("UDP6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(DTLS)
|
||||
printf("DTLS ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(DTLS6)
|
||||
printf("DTLS6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(RFCOMM)
|
||||
printf("RFCOMM ClientId:%s channel:%d\n", theNetcon.clientId, theNetcon.channel);
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
printf("%s\n", PAHO_COPYRIGHT1);
|
||||
printf("%s\n", PAHO_COPYRIGHT2);
|
||||
printf(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
@@ -77,11 +90,13 @@ int main(int argc, char** argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
theClient->setAutoConnectMode(false);
|
||||
theClient->getPublishManager()->setAutoConnectMode(false);
|
||||
#endif
|
||||
|
||||
setup();
|
||||
theClient->addTask(theClientMode);
|
||||
theClient->initialize( theNetcon, theMqcon);
|
||||
theClient->initialize( &theNetcon, &theMqcon);
|
||||
do
|
||||
{
|
||||
theClient->run();
|
||||
@@ -98,7 +113,7 @@ int main(int argc, char** argv)
|
||||
======================================*/
|
||||
LMqttsnClient::LMqttsnClient()
|
||||
{
|
||||
|
||||
_isAutoConnect = true;
|
||||
}
|
||||
|
||||
LMqttsnClient::~LMqttsnClient()
|
||||
@@ -106,10 +121,10 @@ LMqttsnClient::~LMqttsnClient()
|
||||
|
||||
}
|
||||
|
||||
void LMqttsnClient::initialize(LUdpConfig netconf, LMqttsnConfig mqconf)
|
||||
void LMqttsnClient::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
|
||||
{
|
||||
_gwProxy.initialize(netconf, mqconf);
|
||||
setSleepDuration(mqconf.sleepDuration);
|
||||
setSleepDuration(mqconf->sleepDuration);
|
||||
}
|
||||
|
||||
void LMqttsnClient::addTask(bool clientMode)
|
||||
@@ -183,9 +198,10 @@ void LMqttsnClient::subscribe(const char* topicName, TopicCallback onPublish, ui
|
||||
_subMgr.subscribe(topicName, onPublish, qos);
|
||||
}
|
||||
|
||||
void LMqttsnClient::subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
void LMqttsnClient::subscribePredefinedId(uint16_t topicId, TopicCallback onPublish,
|
||||
uint8_t qos)
|
||||
{
|
||||
_subMgr.subscribe(topicId, onPublish, qos);
|
||||
_subMgr.subscribePredefinedId(topicId, onPublish, qos);
|
||||
}
|
||||
|
||||
void LMqttsnClient::unsubscribe(const char* topicName)
|
||||
@@ -204,11 +220,21 @@ void LMqttsnClient::disconnect(uint16_t sleepInSecs)
|
||||
}
|
||||
|
||||
void LMqttsnClient::run()
|
||||
{
|
||||
if (_isAutoConnect)
|
||||
{
|
||||
_gwProxy.connect();
|
||||
}
|
||||
_taskMgr.run();
|
||||
}
|
||||
|
||||
void LMqttsnClient::setAutoConnectMode(uint8_t flg)
|
||||
{
|
||||
_isAutoConnect = flg;
|
||||
_pubMgr.setAutoConnectMode(flg);
|
||||
_gwProxy.setAutoConnectMode(flg);
|
||||
}
|
||||
|
||||
void LMqttsnClient::setSleepMode(uint32_t duration)
|
||||
{
|
||||
// ToDo: set WDT and sleep mode
|
||||
@@ -226,9 +252,12 @@ void LMqttsnClient::setSleepDuration(uint32_t duration)
|
||||
}
|
||||
|
||||
void LMqttsnClient::onConnect(void)
|
||||
{
|
||||
if (_isAutoConnect)
|
||||
{
|
||||
_subMgr.onConnect();
|
||||
}
|
||||
}
|
||||
|
||||
const char* LMqttsnClient::getClientId(void)
|
||||
{
|
||||
|
||||
@@ -54,15 +54,16 @@ public:
|
||||
void publish(uint16_t topicId, Payload* payload, uint8_t qos, bool retain = false);
|
||||
void publish(uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false);
|
||||
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void unsubscribe(const char* topicName);
|
||||
void unsubscribe(const uint16_t topicId);
|
||||
void disconnect(uint16_t sleepInSecs);
|
||||
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf);
|
||||
void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
|
||||
void run(void);
|
||||
void addTask(bool test);
|
||||
void setSleepDuration(uint32_t duration);
|
||||
void setSleepMode(uint32_t duration);
|
||||
void setAutoConnectMode(uint8_t flg);
|
||||
void sleep(void);
|
||||
const char* getClientId(void);
|
||||
uint16_t getTopicId(const char* topicName);
|
||||
@@ -78,6 +79,7 @@ private:
|
||||
LSubscribeManager _subMgr;
|
||||
LGwProxy _gwProxy;
|
||||
uint32_t _sleepDuration;
|
||||
uint8_t _isAutoConnect;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
#ifndef MQTTSNCLIENTAPP_H_
|
||||
#define MQTTSNCLIENTAPP_H_
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
|
||||
/*======================================
|
||||
* Debug Flag
|
||||
======================================*/
|
||||
//#define DEBUG_NW
|
||||
//#define DEBUG_MQTTSN
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
|
||||
/****************************************
|
||||
MQTT-SN Parameters
|
||||
*****************************************/
|
||||
@@ -55,7 +55,8 @@ typedef signed int int32_t;
|
||||
Application config structures
|
||||
*****************************************/
|
||||
|
||||
struct LMqttsnConfig{
|
||||
struct LMqttsnConfig
|
||||
{
|
||||
uint16_t keepAlive;
|
||||
bool cleanSession;
|
||||
uint32_t sleepDuration;
|
||||
@@ -65,13 +66,30 @@ struct LMqttsnConfig{
|
||||
bool willRetain;
|
||||
};
|
||||
|
||||
struct LUdpConfig{
|
||||
struct LUdpConfig
|
||||
{
|
||||
const char* clientId;
|
||||
uint8_t ipAddress[4];
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LUdp6Config
|
||||
{
|
||||
const char* clientId;
|
||||
const char* ipAddress;
|
||||
const char *interface;
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LRfcommConfig
|
||||
{
|
||||
const char* clientId;
|
||||
const char* gwAddress;
|
||||
uint8_t channel;
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -85,13 +103,50 @@ typedef enum
|
||||
MACROs for Application
|
||||
=======================================*/
|
||||
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig
|
||||
#define NETWORK_CONFIG UdpConfig theNetworkConfig
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
#if defined(UDP)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(UDP6)
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
|
||||
#elif defined(RFCOMM)
|
||||
#define RFCOMMCONF LRfcommConfig theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define SENSORNET_CONFIG_t LRfcommConfig
|
||||
|
||||
#elif defined(DTLS)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(DTLS6)
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
#else
|
||||
#error "UDP, UDP6, DTLS, DTLS6 or RFCOMM is not defined in LMqttsnClientApp.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
|
||||
#define PUBLISH(...) theClient->publish(__VA_ARGS__)
|
||||
#define SUBSCRIBE(...) theClient->subscribe(__VA_ARGS__)
|
||||
#define SUBSCRIBE_PREDEF(...) theClient->subscribePredefinedId(__VA_ARGS__)
|
||||
#define UNSUBSCRIBE(...) theClient->unsubscribe(__VA_ARGS__)
|
||||
#define DISCONNECT(...) theClient->disconnect(__VA_ARGS__)
|
||||
#define ONCONNECT() theClient->getSubscribeManager()->onConnect()
|
||||
|
||||
#define TASK_LIST TaskList theTaskList[]
|
||||
#define TASK(...) {__VA_ARGS__, 0, 0}
|
||||
@@ -102,11 +157,13 @@ typedef enum
|
||||
#define SUBSCRIBE_LIST OnPublishList theOnPublishList[]
|
||||
#define SUB(...) {__VA_ARGS__}
|
||||
#define END_OF_SUBSCRIBE_LIST {MQTTSN_TOPIC_TYPE_NORMAL,0,0,0, 0}
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
|
||||
#define SetForwarderMode(...) theClient->getGwProxy()->setForwarderMode(__VA_ARGS__)
|
||||
#define SetQoSMinus1Mode(...) theClient->getGwProxy()->setQoSMinus1Mode(__VA_ARGS__)
|
||||
|
||||
#define SetAutoConnectMode(...) theClient->setAutoConnectMode(__VA_ARGS__)
|
||||
#define SetAutoPingReqMode(...) theClient->getGwProxy()->setPingReqMode(__VA_ARGS__)
|
||||
#define SetCleanSession(...) theClient->getGwProxy()->setSessionMode(__VA_ARGS__)
|
||||
#ifdef CLIENT_MODE
|
||||
#define DISPLAY(...)
|
||||
#define PROMPT(...)
|
||||
@@ -195,11 +252,11 @@ typedef enum
|
||||
/*=================================
|
||||
* Starting prompt
|
||||
==================================*/
|
||||
#define TESTER_VERSION " * Version: 2.0.0"
|
||||
#define TESTER_VERSION " * Version: 2.1.0"
|
||||
|
||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway Tester"
|
||||
#define PAHO_COPYRIGHT0 " * "
|
||||
#define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse"
|
||||
#define PAHO_COPYRIGHT2 " * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)"
|
||||
#define PAHO_COPYRIGHT2 " * (https://github.com/eclipse/paho.mqtt-sn.embedded-c.git)"
|
||||
#define PAHO_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI"
|
||||
#define PAHO_COPYRIGHT4 " ***************************************************************************"
|
||||
|
||||
|
||||
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef DTLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
|
||||
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtlsPort::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtlsPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
uint16_t recvLen = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
recvLen = LDtlsPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
|
||||
bool LNetwork::initialize(LUdpConfig *config)
|
||||
{
|
||||
return LDtlsPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int LNetwork::sslConnect(void)
|
||||
{
|
||||
return LDtlsPort::sslConnect(_gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class DtlsPort
|
||||
=========================================*/
|
||||
LDtlsPort::LDtlsPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdMcast = 0;
|
||||
_sockfdSsl = 0;
|
||||
_castStat = 0;
|
||||
}
|
||||
|
||||
LDtlsPort::~LDtlsPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LDtlsPort::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = 0;
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtlsPort::open(LUdpConfig *config)
|
||||
{
|
||||
char errmsg[256];
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Client certification and cookie are not required */
|
||||
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||
|
||||
/* setup Multicast socket */
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
ip_mreq mreq;
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LDtlsPort::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
|
||||
int LDtlsPort::unicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
int status = SSL_write(_ssl, buf, length);
|
||||
if (status <= 0)
|
||||
{
|
||||
int rc = 0;
|
||||
SSL_get_error(_ssl, rc);
|
||||
DISPLAY("errno == %d in LDtlsPort::unicast\n", rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto gateway via DTLS ");
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int LDtlsPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
DISPLAY(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool LDtlsPort::checkRecvBuf()
|
||||
{
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
if (_sockfdMcast)
|
||||
{
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
}
|
||||
if (_sockfdSsl)
|
||||
{
|
||||
FD_SET(_sockfdSsl, &recvfds);
|
||||
}
|
||||
|
||||
if (_sockfdMcast > _sockfdSsl)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdSsl;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_SSL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = STAT_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LDtlsPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LDtlsPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in sender;
|
||||
int status = 0;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
if (_castStat == STAT_SSL)
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
if (SSL_read(_ssl, buf, length) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
|
||||
D_NWLOG("recved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo)
|
||||
{
|
||||
int reuse = 1;
|
||||
if (_ssl != 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect SSL exists.\n");
|
||||
SSL_shutdown(_ssl);
|
||||
SSL_free(_ssl);
|
||||
_sockfdSsl = 0;
|
||||
_ssl = 0;
|
||||
}
|
||||
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect socket exists.\n");
|
||||
::close(_sockfdSsl);
|
||||
}
|
||||
|
||||
_sockfdSsl = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdSsl < 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't create a socket\n");
|
||||
return -1;
|
||||
}
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = portNo;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
int rc = 0;
|
||||
errno = 0;
|
||||
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||
connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in));
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest);
|
||||
_ssl = SSL_new(_ctx);
|
||||
SSL_set_bio(_ssl, cbio, cbio);
|
||||
|
||||
D_NWLOG("LDtlsPort::sslConnect connect to %-15s:%-6u\n", inet_ntoa(dest.sin_addr), htons(dest.sin_port));
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||
|
||||
int stat = SSL_connect(_ssl);
|
||||
if (stat != 1)
|
||||
{
|
||||
rc = -1;
|
||||
D_NWLOG("SSL fail to connect\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
D_NWLOG("SSL connected\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKDTLS_H_
|
||||
#define NETWORKDTLS_H_
|
||||
|
||||
#ifdef DTLS
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
#define STAT_NONE 0
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
#define STAT_SSL 3
|
||||
/*========================================
|
||||
Class LDtlsPort
|
||||
=======================================*/
|
||||
class LDtlsPort
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LDtlsPort();
|
||||
virtual ~LDtlsPort();
|
||||
|
||||
bool open(LUdpConfig* config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock, uint32_t* ipaddress, in_port_t* port );
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
SSL* getSSL(void);
|
||||
int sslConnect(uint32_t ipAddress, in_port_t port);
|
||||
private:
|
||||
void close();
|
||||
int recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipaddress, in_port_t* port );
|
||||
|
||||
int _sockfdMcast;
|
||||
int _sockfdSsl;
|
||||
SSL_CTX *_ctx;
|
||||
SSL *_ssl;
|
||||
in_port_t _gPortNo;
|
||||
in_port_t _uPortNo;
|
||||
uint32_t _gIpAddr;
|
||||
uint8_t _castStat;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LDtlsPort
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdpConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
int sslConnect(void);
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
uint32_t _gwIpAddress;
|
||||
uint32_t _ipAddress;
|
||||
in_port_t _gwPortNo;
|
||||
in_port_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* DTLS */
|
||||
#endif /* NETWORKDTLS_H_ */
|
||||
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef DTLS6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <termios.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <poll.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
|
||||
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtls6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtls6Port::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LDtls6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int addrFlg = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && addrFlg && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
memcpy(&_gwIpAddress.s6_addr, &_ipAddress.s6_addr, sizeof(_ipAddress.s6_addr));
|
||||
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(&_gwIpAddress, 0, sizeof(_gwIpAddress));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LDtls6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int LNetwork::sslConnect(void)
|
||||
{
|
||||
return LDtls6Port::sslConnect(_gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class Dtls6Port
|
||||
=========================================*/
|
||||
LDtls6Port::LDtls6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
_castStat = STAT_NONE;
|
||||
_ifIndex = 0;
|
||||
_gIpAddrStr = nullptr;
|
||||
_sockfdMcast = 0;
|
||||
_sockfdSsl = 0;
|
||||
_ctx = nullptr;
|
||||
_ssl = nullptr;
|
||||
_gPortNo = _uPortNo = 0;
|
||||
}
|
||||
|
||||
LDtls6Port::~LDtls6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
}
|
||||
|
||||
void LDtls6Port::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = 0;
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtls6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
sockaddr_in6 addr6;
|
||||
char errmsg[256];
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Client certification and cookie are not required */
|
||||
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
_ifIndex = if_nametoindex(config->interface);
|
||||
_interfaceName = config->interface;
|
||||
}
|
||||
|
||||
/* create a multicast socket */
|
||||
_sockfdMcast = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(_sockfdMcast, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = _ifIndex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LDtls6Port::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
int LDtls6Port::unicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
int status = SSL_write(_ssl, buf, length);
|
||||
if (status <= 0)
|
||||
{
|
||||
int rc = 0;
|
||||
SSL_get_error(_ssl, rc);
|
||||
DISPLAY("errno == %d in LDtls6Port::unicast\n", rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto gateway via DTLS6 ");
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtls6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gIpAddr.sin6_port));
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtls6Port::checkRecvBuf()
|
||||
{
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
if (_sockfdMcast)
|
||||
{
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
}
|
||||
if (_sockfdSsl)
|
||||
{
|
||||
FD_SET(_sockfdSsl, &recvfds);
|
||||
}
|
||||
|
||||
if (_sockfdMcast > _sockfdSsl)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdSsl;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_SSL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = STAT_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LDtls6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LDtls6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
sockaddr_in6 sender;
|
||||
int status = 0;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (_castStat == STAT_SSL)
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
if (SSL_read(_ssl, buf, length) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||
*portPtr = sender.sin6_port;
|
||||
|
||||
D_NWLOG("recved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtls6Port::sslConnect(in6_addr ipAddress, in_port_t portNo)
|
||||
{
|
||||
int optval = 1;
|
||||
|
||||
if (_ssl != 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect SSL exists.\n");
|
||||
SSL_shutdown(_ssl);
|
||||
SSL_free(_ssl);
|
||||
_sockfdSsl = 0;
|
||||
_ssl = 0;
|
||||
}
|
||||
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect socket exists.\n");
|
||||
::close(_sockfdSsl);
|
||||
}
|
||||
|
||||
_sockfdSsl = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (_sockfdSsl <= 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect Can't create a socket\n");
|
||||
return -1;
|
||||
}
|
||||
optval = 1;
|
||||
setsockopt(_sockfdSsl, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR || SO_REUSEPORT, &optval, sizeof(optval));
|
||||
|
||||
if (_ifIndex > 0)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
setsockopt(_sockfdSsl, IPPROTO_IP, IP_BOUND_IF, &_ifIndex, sizeof(_ifIndex));
|
||||
#else
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_BINDTODEVICE, _interfaceName.c_str(), _interfaceName.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
sockaddr_in6 addr;
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = _uPortNo;
|
||||
addr.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Destination is a gateway address and portNo
|
||||
int rc = 0;
|
||||
sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = portNo;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||
if (connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in6)) < 0)
|
||||
{
|
||||
D_NWLOG("socket can't connect %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest) <0)
|
||||
{
|
||||
D_NWLOG("BIO_ctrl %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
_ssl = SSL_new(_ctx);
|
||||
if (_ssl == nullptr)
|
||||
{
|
||||
D_NWLOG("SSL_new %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
SSL_set_bio(_ssl, cbio, cbio);
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("connect to %-15s:%-6u\n", addrBuf, ntohs(dest.sin6_port));
|
||||
#endif
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||
errno = 0;
|
||||
|
||||
int stat = SSL_connect(_ssl);
|
||||
if (stat != 1)
|
||||
{
|
||||
rc = -1;
|
||||
D_NWLOG("SSL fail to connect %s\n",strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
D_NWLOG("SSL connected\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKDTLS6_H_
|
||||
#define NETWORKDTLS6_H_
|
||||
|
||||
#ifdef DTLS6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <poll.h>
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_NONE 0
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
#define STAT_SSL 3
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LDtls6Port
|
||||
=======================================*/
|
||||
class LDtls6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LDtls6Port();
|
||||
virtual ~LDtls6Port();
|
||||
|
||||
bool open(LUdp6Config* config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock, in6_addr* ipaddress, in_port_t* port );
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
SSL* getSSL(void);
|
||||
int sslConnect(in6_addr ipAddress, uint16_t port);
|
||||
private:
|
||||
void close();
|
||||
int recvfrom ( uint8_t* buf, uint16_t len, int flags, in6_addr* ipaddress, in_port_t* port );
|
||||
|
||||
int _sockfdMcast;
|
||||
int _sockfdSsl;
|
||||
SSL_CTX *_ctx;
|
||||
SSL *_ssl;
|
||||
in_port_t _gPortNo;
|
||||
in_port_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
uint32_t _ifIndex;
|
||||
string _interfaceName;
|
||||
uint8_t _castStat;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LDtls6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
int sslConnect(void);
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
in_port_t _gwPortNo;
|
||||
in_port_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* DTLS6 */
|
||||
#endif /* NETWORKDTLS6_H_ */
|
||||
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/rfcomm.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
extern LRfcommConfig theNetcon;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
_returnCode = 0;
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LRfcommPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LRfcommPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int* len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LRfcommPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false);
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
}
|
||||
|
||||
void LNetwork::setFixedGwAddress(void)
|
||||
{
|
||||
_channel = LRfcommPort::_channel;
|
||||
str2ba( theNetcon.gwAddress, (bdaddr_t*)_gwAddress);
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LRfcommConfig* config)
|
||||
{
|
||||
return LRfcommPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class RFCOMM Stack
|
||||
=========================================*/
|
||||
LRfcommPort::LRfcommPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockRfcomm = 0;
|
||||
_channel = 0;
|
||||
}
|
||||
|
||||
LRfcommPort::~LRfcommPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void LRfcommPort::close()
|
||||
{
|
||||
if (_sockRfcomm > 0)
|
||||
{
|
||||
::close(_sockRfcomm);
|
||||
_sockRfcomm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool LRfcommPort::open(LRfcommConfig* config)
|
||||
{
|
||||
const int reuse = 1;
|
||||
str2ba(config->gwAddress, (bdaddr_t*)_gwAddress);
|
||||
_channel = config->channel;
|
||||
|
||||
if (_channel == 0 || _gwAddress == 0 )
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockRfcomm = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
|
||||
if (_sockRfcomm < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockRfcomm, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_rc addru = { 0 };
|
||||
addru.rc_family = AF_BLUETOOTH;
|
||||
addru.rc_channel = _channel;
|
||||
memcpy(&addru.rc_bdaddr, _gwAddress, 6);
|
||||
|
||||
char bufgw[30];
|
||||
ba2str(&addru.rc_bdaddr, bufgw);
|
||||
DISPLAY("GW MAC = %s RFCOMM CH = %d\n", bufgw, addru.rc_channel);
|
||||
|
||||
// connect to server
|
||||
errno = 0;
|
||||
int status = connect(_sockRfcomm, (struct sockaddr *) &addru, sizeof(addru));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror = %d Can't connect to GW in LRfcommPort::open\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merror = %d Can't connect to GW Ble socket in LRfcommPort::open\033[0m\033[0;37m\n",errno);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int LRfcommPort::unicast(const uint8_t* buf, uint32_t length)
|
||||
{
|
||||
int status = ::write(_sockRfcomm, buf, length);
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("errno == %d in LRfcommPort::unicast\n", errno);
|
||||
DISPLAY("errno == %d in LRfcommPort::unicast\n", errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-2d", _channel);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-2dch", _channel);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LRfcommPort::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
if (::recv(_sockRfcomm, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int LRfcommPort::recv(uint8_t* buf, uint16_t length, bool flg)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
int status = ::recv(_sockRfcomm, buf, length, flags);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
D_NWLOG("\nrecved ");
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKRFCOMM_H_
|
||||
#define NETWORKRFCOMM_H_
|
||||
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient
|
||||
{
|
||||
/*========================================
|
||||
Class LRfcommPort
|
||||
=======================================*/
|
||||
class LRfcommPort
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LRfcommPort();
|
||||
virtual ~LRfcommPort();
|
||||
bool open(LRfcommConfig* config);
|
||||
int unicast(const uint8_t* buf, uint32_t length);
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
|
||||
int _sockRfcomm;
|
||||
uint8_t _gwAddress[6];
|
||||
uint8_t _channel;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LRfcommPort
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
void setFixedGwAddress(void);
|
||||
bool initialize(LRfcommConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* RFCOMM */
|
||||
#endif /* NETWORKRFCOM_H_ */
|
||||
@@ -13,6 +13,7 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
@@ -25,12 +26,11 @@
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
@@ -41,39 +41,51 @@ extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork(){
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork(){
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen){
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdpPort::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen){
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
|
||||
uint8_t* LNetwork::getMessage(int* len){
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf()){
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if(_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo)){
|
||||
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(recvLen < 0){
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}else{
|
||||
if(_rxDataBuf[0] == 0x01){
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
//if(recvLen != *len){
|
||||
@@ -87,111 +99,125 @@ uint8_t* LNetwork::getMessage(int* len){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void){
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
}
|
||||
|
||||
void LNetwork::setFixedGwAddress(void){
|
||||
void LNetwork::setFixedGwAddress(void)
|
||||
{
|
||||
_gwPortNo = LUdpPort::_gPortNo;
|
||||
_gwIpAddress = LUdpPort::_gIpAddr;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void){
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
|
||||
bool LNetwork::initialize(LUdpConfig config){
|
||||
bool LNetwork::initialize(LUdpConfig *config)
|
||||
{
|
||||
return LUdpPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep(){
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udpStack
|
||||
=========================================*/
|
||||
LUdpPort::LUdpPort(){
|
||||
LUdpPort::LUdpPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdUcast = -1;
|
||||
_sockfdMcast = -1;
|
||||
_castStat = 0;
|
||||
}
|
||||
|
||||
LUdpPort::~LUdpPort(){
|
||||
LUdpPort::~LUdpPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LUdpPort::close(){
|
||||
if(_sockfdMcast > 0){
|
||||
void LUdpPort::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = -1;
|
||||
if(_sockfdUcast > 0){
|
||||
if (_sockfdUcast > 0)
|
||||
{
|
||||
::close(_sockfdUcast);
|
||||
_sockfdUcast = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdpPort::open(LUdpConfig config){
|
||||
const int reuse = 1;
|
||||
char loopch = 1;
|
||||
bool LUdpPort::open(LUdpConfig *config)
|
||||
{
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config.ipAddress[3];
|
||||
config.ipAddress[3] = config.ipAddress[0];
|
||||
config.ipAddress[0] = sav;
|
||||
sav = config.ipAddress[2];
|
||||
config.ipAddress[2] = config.ipAddress[1];
|
||||
config.ipAddress[1] = sav;
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gPortNo = htons(config.gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*)config.ipAddress);
|
||||
_uPortNo = htons(config.uPortNo);
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdUcast < 0){
|
||||
if (_sockfdUcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if( ::bind ( _sockfdUcast, (struct sockaddr*)&addr, sizeof(addr)) <0){
|
||||
if (::bind(_sockfdUcast, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMcast < 0){
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addrm;
|
||||
sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if( ::bind ( _sockfdMcast, (struct sockaddr*)&addrm, sizeof(addrm)) <0){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in UdpPort::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -199,36 +225,47 @@ bool LUdpPort::open(LUdpConfig config){
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||
|
||||
if( setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
optval= 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LUdpPort::isUnicast(){
|
||||
bool LUdpPort::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
|
||||
int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port ){
|
||||
int LUdpPort::unicast(const uint8_t *buf, uint32_t length, uint32_t ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = port;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
|
||||
int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if( status < 0){
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("errno == %d in UdpPort::unicast\n", errno);
|
||||
DISPLAY("errno == %d in UdpPort::unicast\n", errno);
|
||||
}else{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
@@ -236,7 +273,8 @@ int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, u
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
@@ -245,32 +283,32 @@ int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, u
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
||||
int LUdpPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if( status < 0){
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
||||
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
DISPLAY(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
@@ -278,7 +316,8 @@ int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
||||
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++){
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
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;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
@@ -307,21 +347,29 @@ bool LUdpPort::checkRecvBuf(){
|
||||
FD_SET(_sockfdUcast, &recvfds);
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
|
||||
if(_sockfdMcast > _sockfdUcast){
|
||||
if (_sockfdMcast > _sockfdUcast)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdUcast;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if(FD_ISSET(_sockfdUcast, &recvfds)){
|
||||
if( ::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
||||
if (FD_ISSET(_sockfdUcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_UNICAST;
|
||||
return true;
|
||||
}
|
||||
}else if(FD_ISSET(_sockfdMcast, &recvfds)){
|
||||
if( ::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
||||
}
|
||||
else if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
@@ -330,36 +378,47 @@ bool LUdpPort::checkRecvBuf(){
|
||||
return false;
|
||||
}
|
||||
|
||||
int LUdpPort::recv(uint8_t* buf, uint16_t len, bool flg, uint32_t* ipAddressPtr, uint16_t* portPtr){
|
||||
int LUdpPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){
|
||||
int LUdpPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
if(isUnicast()){
|
||||
if (isUnicast())
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
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);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN) {
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}else if(status > 0){
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
D_NWLOG("\nrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
for(uint16_t i = 0; i < status ; i++){
|
||||
D_NWLOG("recved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
@@ -367,7 +426,8 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < status ; i++){
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
@@ -379,11 +439,13 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef NETWORKUDP_H_
|
||||
#define NETWORKUDP_H_
|
||||
|
||||
#ifdef UDP
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
@@ -27,8 +29,6 @@
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
LUdpPort();
|
||||
virtual ~LUdpPort();
|
||||
|
||||
bool open(LUdpConfig config);
|
||||
bool open(LUdpConfig* config);
|
||||
|
||||
int unicast(const uint8_t* buf, uint32_t length, uint32_t ipaddress, uint16_t port );
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
@@ -87,8 +87,9 @@ public:
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
void setFixedGwAddress(void);
|
||||
bool initialize(LUdpConfig config);
|
||||
bool initialize(LUdpConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
@@ -103,6 +104,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
|
||||
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdp6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int diffAddr = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && diffAddr && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
memcpy(_gwIpAddress.s6_addr, _ipAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = _portNo;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(_gwIpAddress.s6_addr, 0, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LUdp6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udp6Stack
|
||||
=========================================*/
|
||||
LUdp6Port::LUdp6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
memset(_pollfds, 0, sizeof(_pollfds));
|
||||
_sock = 0;
|
||||
_interface = NULL;
|
||||
_gIpAddrStr = NULL;
|
||||
}
|
||||
|
||||
LUdp6Port::~LUdp6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
if (_interface)
|
||||
{
|
||||
free(_interface);
|
||||
}
|
||||
}
|
||||
|
||||
void LUdp6Port::close()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].fd > 0)
|
||||
{
|
||||
::close(_pollfds[i].fd);
|
||||
_pollfds[i].fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
int sock = 0;
|
||||
uint32_t ifindex = 0;
|
||||
sockaddr_in6 addr6;
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create a unicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
ifindex = if_nametoindex(config->interface);
|
||||
#ifdef __APPLE__
|
||||
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
|
||||
#else
|
||||
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, config->interface, strlen(config->interface));
|
||||
#endif
|
||||
}
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _uPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
_pollfds[0].fd = sock;
|
||||
_pollfds[0].events = POLLIN;
|
||||
|
||||
/* create a multicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = ifindex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
optval = 1;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
_pollfds[1].fd = sock;
|
||||
_pollfds[1].events = POLLIN;
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
int LUdp6Port::unicast(const uint8_t *buf, uint32_t length, in6_addr ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = port;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("unicast to [%s]:%-6u", addrBuf, htons(port));
|
||||
|
||||
int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG(" errno = %d %s in Udp6Port::unicast\n", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34municast to [%s[:%-6u", addrBuf, htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LUdp6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gPortNo));
|
||||
|
||||
int status = ::sendto(_pollfds[1].fd, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s ", _gIpAddrStr, portStr);
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d %s in Udp6Port::multicast\033[0m\033[0;37m\n", errno, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
int cnt = poll(_pollfds, 2, 50); // Timeout 50m secs
|
||||
if (cnt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].revents & POLLIN)
|
||||
{
|
||||
if (::recv(_pollfds[i].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_sock = _pollfds[i].fd;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
int LUdp6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LUdp6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in6 sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
|
||||
status = ::recvfrom(_sock, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in Udp6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||
*portPtr = sender.sin6_port;
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecv from [%s]:%-6u", addrBuf, htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LUdp6Port::isUnicast(void)
|
||||
{
|
||||
return (_sock == _pollfds[0].fd && _sock > 0);
|
||||
}
|
||||
#endif /* UDP6 */
|
||||
|
||||
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKUDP6_H_
|
||||
#define NETWORKUDP6_H_
|
||||
|
||||
#ifdef UDP6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LUpd6Port
|
||||
=======================================*/
|
||||
class LUdp6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LUdp6Port();
|
||||
virtual ~LUdp6Port();
|
||||
|
||||
bool open(LUdp6Config *config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length, in6_addr ipaddress, uint16_t port);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t *buf, uint16_t len, bool nonblock, in6_addr *ipaddress, uint16_t *port);
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
int recvfrom(uint8_t *buf, uint16_t len, int flags, in6_addr *ipaddress, uint16_t *port);
|
||||
|
||||
pollfd _pollfds[2];
|
||||
uint16_t _gPortNo;
|
||||
uint16_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
char* _interface;
|
||||
int _sock;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LUdp6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config *config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
uint16_t _gwPortNo;
|
||||
uint16_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP6 */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
@@ -44,6 +44,7 @@ LPublishManager::LPublishManager()
|
||||
_last = 0;
|
||||
_elmCnt = 0;
|
||||
_publishedFlg = SAVE_TASK_INDEX;
|
||||
_autoConnectFlg = false;
|
||||
}
|
||||
|
||||
LPublishManager::~LPublishManager()
|
||||
@@ -115,7 +116,10 @@ void LPublishManager::sendPublish(PubElement* elm)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_autoConnectFlg)
|
||||
{
|
||||
theClient->getGwProxy()->connect();
|
||||
}
|
||||
|
||||
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
uint8_t org = 0;
|
||||
@@ -310,6 +314,11 @@ void LPublishManager::checkTimeout(void)
|
||||
}
|
||||
}
|
||||
|
||||
void LPublishManager::setAutoConnectMode(bool flg)
|
||||
{
|
||||
_autoConnectFlg = flg;
|
||||
}
|
||||
|
||||
PubElement* LPublishManager::getElement(uint16_t msgId)
|
||||
{
|
||||
PubElement* elm = _first;
|
||||
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
void sendSuspend(const char* topicName, uint16_t topicId, uint8_t topicType);
|
||||
bool isDone(void);
|
||||
bool isMaxFlight(void);
|
||||
void setAutoConnectMode(bool);
|
||||
private:
|
||||
PubElement* getElement(uint16_t msgId);
|
||||
PubElement* getElement(const char* topicName);
|
||||
@@ -84,6 +85,7 @@ private:
|
||||
PubElement* _last;
|
||||
uint8_t _elmCnt;
|
||||
uint8_t _publishedFlg;
|
||||
uint8_t _autoConnectFlg;
|
||||
};
|
||||
|
||||
} /* tomyAsyncClient */
|
||||
|
||||
@@ -67,7 +67,9 @@ void LSubscribeManager::onConnect(void)
|
||||
{
|
||||
if ( theOnPublishList[i].type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
subscribe(theOnPublishList[i].id, theOnPublishList[i].pubCallback, theOnPublishList[i].qos);
|
||||
subscribePredefinedId(theOnPublishList[i].id,
|
||||
theOnPublishList[i].pubCallback,
|
||||
theOnPublishList[i].qos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,6 +124,7 @@ void LSubscribeManager::send(SubElement* elm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
if (elm->topicType == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
@@ -169,7 +172,7 @@ void LSubscribeManager::subscribe(const char* topicName, TopicCallback onPublish
|
||||
send(elm);
|
||||
}
|
||||
|
||||
void LSubscribeManager::subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
void LSubscribeManager::subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
{
|
||||
SubElement* elm = add(MQTTSN_TYPE_SUBSCRIBE, 0, MQTTSN_TOPIC_TYPE_PREDEFINED, topicId, qos, onPublish);
|
||||
send(elm);
|
||||
@@ -262,7 +265,9 @@ void LSubscribeManager::responce(const uint8_t* msg)
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;31m UNSUBACK Invalid messageId. \033[0m\033[0;37m\n\n");
|
||||
DISPLAY(
|
||||
"\033[0m\033[0;31m UNSUBACK Invalid messageId=%04x. \033[0m\033[0;37m\n\n",
|
||||
msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
~LSubscribeManager();
|
||||
void onConnect(void);
|
||||
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void unsubscribe(const char* topicName);
|
||||
void unsubscribe(uint16_t topicId);
|
||||
void responce(const uint8_t* msg);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -34,25 +33,30 @@ extern bool theClientMode;
|
||||
/*=====================================
|
||||
TaskManager
|
||||
======================================*/
|
||||
LTaskManager::LTaskManager(void){
|
||||
LTaskManager::LTaskManager(void)
|
||||
{
|
||||
_tasks = 0;
|
||||
_tests = 0;
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
LTaskManager::~LTaskManager(void){
|
||||
LTaskManager::~LTaskManager(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LTaskManager::add(TaskList* task){
|
||||
void LTaskManager::add(TaskList* task)
|
||||
{
|
||||
_tasks = task;
|
||||
}
|
||||
|
||||
void LTaskManager::add(TestList* test){
|
||||
void LTaskManager::add(TestList* test)
|
||||
{
|
||||
_tests = test;
|
||||
}
|
||||
|
||||
void LTaskManager::run(void){
|
||||
void LTaskManager::run(void)
|
||||
{
|
||||
int i = 0;
|
||||
char c = 0;
|
||||
bool cancelFlg = false;
|
||||
@@ -99,9 +103,8 @@ void LTaskManager::run(void){
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while(theClient->getPublishManager()->isMaxFlight() ||
|
||||
!theClient->getSubscribeManager()->isDone() ||
|
||||
!theClient->getRegisterManager()->isDone());
|
||||
while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
|
||||
|| !theClient->getRegisterManager()->isDone());
|
||||
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
@@ -122,8 +125,7 @@ void LTaskManager::run(void){
|
||||
theClient->getGwProxy()->getMessage();
|
||||
for (_index = 0; _tasks[_index].callback > task.callback; _index++)
|
||||
{
|
||||
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) &&
|
||||
_tasks[_index].count == 0)
|
||||
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) && _tasks[_index].count == 0)
|
||||
{
|
||||
_tasks[_index].prevTime = time(NULL);
|
||||
(_tasks[_index].callback)();
|
||||
@@ -134,9 +136,8 @@ void LTaskManager::run(void){
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while(theClient->getPublishManager()->isMaxFlight() ||
|
||||
!theClient->getSubscribeManager()->isDone() ||
|
||||
!theClient->getRegisterManager()->isDone());
|
||||
while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
|
||||
|| !theClient->getRegisterManager()->isDone());
|
||||
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
@@ -146,11 +147,13 @@ void LTaskManager::run(void){
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LTaskManager::getIndex(void){
|
||||
uint8_t LTaskManager::getIndex(void)
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
|
||||
void LTaskManager::done(uint8_t index){
|
||||
void LTaskManager::done(uint8_t index)
|
||||
{
|
||||
if (_tasks)
|
||||
{
|
||||
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)
|
||||
{
|
||||
_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** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
MQTT-SN requires a MQTT-SN Gateway which acts as a protocol converter to convert MQTT-SN messages to MQTT messages.
|
||||
MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||
|
||||
### **step1. Build the gateway**
|
||||
````
|
||||
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
### step1. Build the gateway
|
||||
copy and expand source code then,
|
||||
```
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||
$ make [SENSORNET={udp6|xbee|loralink}]
|
||||
$ make install
|
||||
$ make clean
|
||||
````
|
||||
By default, a gateway for UDP is built.
|
||||
In order to create a gateway for UDP6, XBee or LoRaLink, SENSORNET argument is required.
|
||||
```
|
||||
In order to build a gateway, one sensor network argument is required.
|
||||
```
|
||||
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm|dtls|dtls6]
|
||||
```
|
||||
|
||||
MQTT-SNGateway, MQTT-SNLogmonitor and *.conf files are copied into ../ directory.
|
||||
If you want to install the gateway into specific directories, enter a command line as follows:
|
||||
````
|
||||
$ make install INSTALL_DIR=/path/to/your_directory CONFIG_DIR=/path/to/your_directory
|
||||
````
|
||||
MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin directory.
|
||||
|
||||
### step2. Execute the Gateway.
|
||||
|
||||
### **step2. Execute the Gateway.**
|
||||
|
||||
````
|
||||
$ cd ../../
|
||||
$ ./MQTT-SNGateway [-f Config file name]
|
||||
````
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNGateway
|
||||
```
|
||||
If you get the error message as follows:
|
||||
````
|
||||
what(): RingBuffer can't create a shared memory.
|
||||
Aborted (core dumped)
|
||||
````
|
||||
|
||||
RingBuffer can't create a shared memory. ABORT Gateway!!!
|
||||
You have to start using sudo command only once for the first time.
|
||||
````
|
||||
$ sudo ./MQTT-SNGateway [-f Config file name]
|
||||
````
|
||||
|
||||
### **How to Change the configuration of the gateway**
|
||||
**../gateway.conf** Contents are follows:
|
||||
|
||||
<pre><dev>
|
||||
```
|
||||
$ sudo ./MQTT-SNGateway
|
||||
```
|
||||
## Contents of the gateway configuration file
|
||||
**gateway.conf** is in bin directory. It's contents are follows:
|
||||
|
||||
```
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#***************************************************************************
|
||||
#
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
BrokerName=mqtt.eclipse.org
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
```
|
||||
**GatewayID** is a gateway ID which used by GWINFO message.
|
||||
**GatewayName** is a name of the gateway.
|
||||
**MaxNumberOfClients** is a maxmum number of clients. Clients are dynamically allocated.
|
||||
**KeepAlive** is KeepAlive time in seconds.
|
||||
**LoginID** is used by CONNECT message.
|
||||
**Password** is used by CONNECT message.
|
||||
**BrokerName**is a domain name or IP address of a broker.
|
||||
**BrokerPortNo** is a broker's port no.
|
||||
**BrokerSecurePortNo** is a broker's port no of TLS connection.
|
||||
```
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
```
|
||||
**RootCAfile** is a CA file name.
|
||||
**RootCApath** is a CA path. **SSL_CTX_load_verify_locations(ctx, CAfile, CApath)** function requires these parameters.
|
||||
**CertsKey** is a certificate pem file.
|
||||
**PrivateKey** is a private key pem file.
|
||||
Clients can connect to the broker via TLS by setting '**Secure Connection**' for each client in the client conf file.
|
||||
```
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
```
|
||||
The gateway runs as a aggregating gateway when **AggregatingGateway** is 'YES'.
|
||||
If **QoS-1** is 'YES, the gateway prepares a proxy for the QoS-1 client. QoS-1 client has a 'QoS-1' parameter in a clients.conf file. For QoS-1 clients, set the QoS-1 parameters in the clients.conf file.
|
||||
If **Forwarder** is 'YES', the gateway prepare a forwarder agent.
|
||||
If **ClientAuthentication** is 'YES', the client cannot connect unless it is registered in the clients.conf file.
|
||||
**ClientsList** defines clients and those address so on.
|
||||
**PredefinedTopicList** file defines Predefined Topic.
|
||||
|
||||
|
||||
# UDP
|
||||
```
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
```
|
||||
**GatewayPortNo** is a unicast port no of the gateway.
|
||||
**MulticastIP** and **MulticastPortNo** are for GWSEARCH messages. Clients can get the gateway address (Gateway IP address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
|
||||
Client needs to know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**MulticastTTL** is a multicast TTL.
|
||||
```
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::feed:caca:dead
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
```
|
||||
**GatewayIPv6PortNo** is a unicast port no of the gateway.
|
||||
**MulticastIPv6PortNo** and **MulticastIPv6** are for GWSEARCH messages. Set the Global scope Multicast address so that the Global address is used for sending GWINFO.
|
||||
Clients can get the gateway address (Gateway IPv6 address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
|
||||
**MulticastIPv6If** is a multicast interface name.
|
||||
**MulticastHops** is a multicast hops.
|
||||
```
|
||||
#
|
||||
# DTLS | DTLS6 DTLS CertsKey
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
```
|
||||
**DtlsCertsKey** is a certs Key pem file for DTLS connection.
|
||||
**DtlsPrivKey** is a private key pem file for DTLS connection.
|
||||
```
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
|
||||
```
|
||||
**Baudrate** is a baudrate of xbee.
|
||||
```
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/ttyLoRaLinkRx
|
||||
DeviceTxLoRaLink=/dev/ttyLoRaLinkTx
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
```
|
||||
https://github.com/ty4tw/MQTT-SN-LoRa
|
||||
|
||||
```
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
```
|
||||
**RFCOMMAddress** is a bluetooth mac address and channel. channel should be * for the gateway.
|
||||
```
|
||||
#
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
|
||||
</dev></pre>
|
||||
ShearedMemory=NO
|
||||
```
|
||||
|
||||
**BrokerName** to specify a domain name of the Broker, and **BrokerPortNo** is a port No of the Broker. **BrokerSecurePortNo** is for TLS connection.
|
||||
**MulticastIP** and **MulticastPortNo** is a multicast address for GWSEARCH messages. Gateway is waiting GWSEARCH and when receiving it send GWINFO message via MulticastIP address. Clients can get the gateway address (Gateway IP address and **GatewayPortNo**) from GWINFO message by means of std::recvfrom().
|
||||
Client should know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**GatewayId** is used by GWINFO message.
|
||||
**KeepAlive** is a duration of ADVERTISE message in seconds.
|
||||
when **AggregatingGateway** or **ClientAuthentication** is **YES**, All clients which connect to the gateway must be declared by a **ClientsList** file.
|
||||
Format of the file is ClientId and SensorNetwork Address. e.g. IP address and Port No etc, in CSV. more detail see clients.conf.
|
||||
When **QoS-1** is **YES**, QoS-1 PUBLISH is available. All clients which send QoS-1 PUBLISH must be specified by Client.conf file.
|
||||
When **PredefinedTopic** is **YES**, **Pre-definedTopicId**s specified by **PredefinedTopicList** are effective. This file defines Pre-definedTopics of the clients. In this file, ClientID,TopicName and TopicID are declared in CSV format.
|
||||
When **Forwarder** is **YES**, Forwarder Encapsulation Message is available. Connectable Forwarders must be declared by a **ClientsList** file.
|
||||
|
||||
### ** How to monitor the gateway from remote. **
|
||||
### How to monitor the gateway from a remote terminal.
|
||||
Change gateway.conf as follows:
|
||||
```
|
||||
# LOG
|
||||
ShearedMemory=YES;
|
||||
````
|
||||
|
||||
```
|
||||
Restart the gateway with sudo only once to create shared memories.
|
||||
|
||||
open ssh terminal and execute LogMonitor.
|
||||
|
||||
`$ ./MQTT-SNLogmonitor`
|
||||
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNLogmonitor
|
||||
```
|
||||
Now you can get the Log on your terminal.
|
||||
|
||||
|
||||
## ** Tips **
|
||||
Uncomment the line 62, 63 in MQTTSNDefines.h then you can get more precise logs.
|
||||
##### Tips
|
||||
Use compiler definitions then you can get more precise logs.
|
||||
**-DDEBUG_NW** is a flag for debug logs of Sensor network.
|
||||
**-DDEBUG_MQTTSN** is a flag for debug logs of MQTT-SN message haandling.
|
||||
One or both flags can be specified.
|
||||
|
||||
```
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
./build.sh udp -DDEBUG -DDEBUG_NW
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
42
MQTTSNGateway/build.sh
Executable file
42
MQTTSNGateway/build.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
build () {
|
||||
echo "Start building MQTT-SN Gateway $1"
|
||||
|
||||
cd $SCRIPT_DIR/..
|
||||
BDIR='build.gateway'
|
||||
if [ ! -d ./$BDIR ]; then
|
||||
mkdir $BDIR
|
||||
fi
|
||||
cd $BDIR
|
||||
cmake .. -DSENSORNET=$1 -DDEFS="${2} ${3}"
|
||||
make MQTTSNPacket
|
||||
make MQTT-SNGateway
|
||||
make MQTT-SNLogmonitor
|
||||
cd ../MQTTSNGateway
|
||||
cp *.conf ./bin/
|
||||
}
|
||||
|
||||
SCRIPT_DIR=$(cd $(dirname $0); pwd)
|
||||
|
||||
if [ $1 == "udp" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "udp6" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "xbee" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "loralink" ]; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "rfcomm" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "dtls" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "dtls6" ] ; then
|
||||
build dtls "${2} ${3} -DDTLS6"
|
||||
elif [ $1 == "clean" ] ; then
|
||||
rm -rf ../builg.gateway
|
||||
else
|
||||
echo "Usage: build.sh [ udp | udp6 | xbee | loralink | rfcomm | dtls | dtls6 | clean]"
|
||||
fi
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
# Lines bigning with # are comment line.
|
||||
# ClientId, SensorNetAddress, "unstableLine", "secureConnection"
|
||||
# in case of UDP, SensorNetAddress format is IPAddress: port no.
|
||||
# if the SensorNetwork is not stable, write "unstableLine".
|
||||
# if Broker's Connection is SSL, write "secureConnection".
|
||||
# if the client is a forwarder, "forwarder" is required.
|
||||
# if the client send PUBLISH QoS-1, "QoS-1" is required.
|
||||
# if the SensorNetwork is not stable, specify "unstableLine".
|
||||
# if Broker's Connection is TLS, specify "secureConnection".
|
||||
# if the client is a forwarder,specify "forwarder".
|
||||
# if the client send PUBLISH QoS-1, specify "QoS-1".
|
||||
#
|
||||
# Ex:
|
||||
# #Client List
|
||||
@@ -31,6 +31,17 @@
|
||||
#
|
||||
# SensorNetwork address format is defined by SensorNetAddress::setAddress(string* data) function.
|
||||
#
|
||||
# UDP6 (IPv6 UDP) [IPv6 address]:PortNo
|
||||
# RFCOMM Device_address.channel (1-30)
|
||||
# XBee FFFFFFFFFFFFFFFF 8bytes Hex
|
||||
# LoRaLink 1-254
|
||||
#
|
||||
#
|
||||
# This is a sample of UDP.
|
||||
#
|
||||
# REWRITE ALL ACCORDING TO YOUR CLIENTS.
|
||||
#
|
||||
|
||||
GatewayTester, 172.16.1.11:20020
|
||||
ClientPUB,172.16.1.11:2010
|
||||
Client01,172.16.1.11:12001
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2019, Tomoaki Yamaguchi
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
@@ -14,55 +14,95 @@
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
BrokerName=mqtt.eclipse.org
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
|
||||
|
||||
# UDP
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::1
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
|
||||
#
|
||||
# DTLS | DTLS6
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
|
||||
#
|
||||
# LOG
|
||||
#
|
||||
|
||||
ShearedMemory=NO
|
||||
|
||||
|
||||
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
@@ -0,0 +1,151 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2022 a1lu
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# Contributors:
|
||||
# a1lu - initial version
|
||||
# ty4tw - modify
|
||||
#*******************************************************************************/
|
||||
PROJECT(mqtt-sn-gateway CXX)
|
||||
|
||||
SET(GW_VERSION_MAJOR 1)
|
||||
SET(GW_VERSION_MINOR 5)
|
||||
SET(GW_VERSION_PATCH 1)
|
||||
|
||||
SET(GATEWAY_VERSION ${GW_VERSION_MAJOR}.${GW_VERSION_MINOR}.${GW_VERSION_PATCH})
|
||||
MESSAGE(STATUS "VERSION : ${GATEWAY_VERSION}")
|
||||
|
||||
configure_file( MQTTSNGWVersion.h.in ${CMAKE_CURRENT_SOURCE_DIR}/MQTTSNGWVersion.h )
|
||||
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../bin)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
SET(OS linux)
|
||||
|
||||
IF(NOT DEFINED SENSORNET)
|
||||
SET(SENSORNET udp)
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "SENSORNET: " ${SENSORNET})
|
||||
|
||||
ADD_DEFINITIONS(${DEFS})
|
||||
MESSAGE(STATUS "Definitions: " ${DEFS})
|
||||
|
||||
ADD_LIBRARY(mqtt-sngateway_common
|
||||
MQTTGWConnectionHandler.cpp
|
||||
MQTTGWPacket.cpp
|
||||
MQTTGWPublishHandler.cpp
|
||||
MQTTGWSubscribeHandler.cpp
|
||||
MQTTSNGateway.cpp
|
||||
MQTTSNGWBrokerRecvTask.cpp
|
||||
MQTTSNGWBrokerSendTask.cpp
|
||||
MQTTSNGWClient.cpp
|
||||
MQTTSNGWClientRecvTask.cpp
|
||||
MQTTSNGWClientSendTask.cpp
|
||||
MQTTSNGWConnectionHandler.cpp
|
||||
MQTTSNGWLogmonitor.cpp
|
||||
MQTTSNGWPacket.cpp
|
||||
MQTTSNGWPacketHandleTask.cpp
|
||||
MQTTSNGWProcess.cpp
|
||||
MQTTSNGWPublishHandler.cpp
|
||||
MQTTSNGWSubscribeHandler.cpp
|
||||
MQTTSNGWEncapsulatedPacket.cpp
|
||||
MQTTSNGWForwarder.cpp
|
||||
MQTTSNGWQoSm1Proxy.cpp
|
||||
MQTTSNGWAdapter.cpp
|
||||
MQTTSNGWAggregater.cpp
|
||||
MQTTSNGWClientList.cpp
|
||||
MQTTSNGWTopic.cpp
|
||||
MQTTSNGWAdapterManager.cpp
|
||||
MQTTSNAggregateConnectionHandler.cpp
|
||||
MQTTSNGWMessageIdTable.cpp
|
||||
MQTTSNGWAggregateTopicTable.cpp
|
||||
${OS}/${SENSORNET}/SensorNetwork.cpp
|
||||
${OS}/${SENSORNET}/SensorNetwork.h
|
||||
${OS}/Timer.cpp
|
||||
${OS}/Timer.h
|
||||
${OS}/Network.cpp
|
||||
${OS}/Network.h
|
||||
${OS}/Threading.cpp
|
||||
${OS}/Threading.h
|
||||
)
|
||||
|
||||
# linux
|
||||
link_directories("/usr/local/lib")
|
||||
|
||||
# Mac
|
||||
link_directories("/usr/local/opt/openssl/lib")
|
||||
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
|
||||
PUBLIC
|
||||
.
|
||||
${OS}
|
||||
${OS}/${SENSORNET}
|
||||
../../MQTTSNPacket/src
|
||||
/usr/local/include
|
||||
/usr/local/opt/openssl/include
|
||||
)
|
||||
|
||||
IF(SENSORNET MATCHES "rfcomm")
|
||||
|
||||
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||
PRIVATE
|
||||
MQTTSNPacket
|
||||
pthread
|
||||
ssl
|
||||
crypto
|
||||
bluetooth
|
||||
)
|
||||
ELSE()
|
||||
|
||||
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||
PRIVATE
|
||||
MQTTSNPacket
|
||||
pthread
|
||||
ssl
|
||||
crypto
|
||||
)
|
||||
|
||||
ENDIF()
|
||||
|
||||
ADD_EXECUTABLE(MQTT-SNGateway
|
||||
mainGateway.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(MQTT-SNGateway
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(MQTT-SNLogmonitor
|
||||
mainLogmonitor.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(MQTT-SNLogmonitor
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(testPFW
|
||||
tests/mainTestProcess.cpp
|
||||
tests/TestProcess.cpp
|
||||
tests/TestQue.cpp
|
||||
tests/TestTree23.cpp
|
||||
tests/TestTopics.cpp
|
||||
tests/TestTopicIdMap.cpp
|
||||
tests/TestTask.cpp
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(testPFW
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
|
||||
ADD_TEST(NAME testPFW
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/..
|
||||
COMMAND testPFW -f ./gateway.conf)
|
||||
@@ -49,8 +49,7 @@ void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet
|
||||
else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n",
|
||||
client->getClientId());
|
||||
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n", client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_SERVER_UNAVAILABLE)
|
||||
{
|
||||
|
||||
@@ -28,9 +28,8 @@ void writeInt(unsigned char** pptr, int msgId);
|
||||
/**
|
||||
* List of the predefined MQTT v3 packet names.
|
||||
*/
|
||||
static const char* mqtt_packet_names[] =
|
||||
{ "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP", "SUBSCRIBE", "SUBACK",
|
||||
"UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
|
||||
static const char* mqtt_packet_names[] = { "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP",
|
||||
"SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
|
||||
|
||||
/**
|
||||
* Encodes the message length according to the MQTT algorithm
|
||||
@@ -49,7 +48,8 @@ int MQTTPacket_encode(char* buf, int length)
|
||||
if (length > 0)
|
||||
d |= 0x80;
|
||||
buf[rc++] = d;
|
||||
} while (length > 0);
|
||||
}
|
||||
while (length > 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,8 @@ int MQTTGWPacket::recv(Network* network)
|
||||
}
|
||||
_remainingLength += (c & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
}
|
||||
while ((c & 128) != 0);
|
||||
|
||||
if (_remainingLength > 0)
|
||||
{
|
||||
|
||||
@@ -31,18 +31,29 @@ typedef void* (*pf)(unsigned char, char*, size_t);
|
||||
|
||||
enum msgTypes
|
||||
{
|
||||
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
|
||||
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
|
||||
PINGREQ, PINGRESP, DISCONNECT
|
||||
CONNECT = 1,
|
||||
CONNACK,
|
||||
PUBLISH,
|
||||
PUBACK,
|
||||
PUBREC,
|
||||
PUBREL,
|
||||
PUBCOMP,
|
||||
SUBSCRIBE,
|
||||
SUBACK,
|
||||
UNSUBSCRIBE,
|
||||
UNSUBACK,
|
||||
PINGREQ,
|
||||
PINGRESP,
|
||||
DISCONNECT
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bitfields for the MQTT header byte.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/*unsigned*/ char byte; /**< the whole byte */
|
||||
/*unsigned*/
|
||||
char byte; /**< the whole byte */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
@@ -62,12 +73,12 @@ typedef union
|
||||
#endif
|
||||
} Header;
|
||||
|
||||
|
||||
/**
|
||||
* Data for a connect packet.
|
||||
*/
|
||||
|
||||
enum MQTT_connackCodes{
|
||||
enum MQTT_connackCodes
|
||||
{
|
||||
MQTT_CONNECTION_ACCEPTED,
|
||||
MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
|
||||
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, \
|
||||
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data for a willMessage.
|
||||
*/
|
||||
@@ -160,7 +169,6 @@ typedef struct
|
||||
char rc; /**< connack return code */
|
||||
} Connack;
|
||||
|
||||
|
||||
/**
|
||||
* Data for a publish packet.
|
||||
*/
|
||||
@@ -214,11 +222,13 @@ public:
|
||||
int getSUBACK(unsigned short* msgId, unsigned char* rc);
|
||||
int getPUBLISH(Publish* pub);
|
||||
|
||||
int setCONNECT(Connect* conect, unsigned char* username, unsigned char* password);
|
||||
int setCONNECT(Connect* conect, unsigned char* username,
|
||||
unsigned char* password);
|
||||
int setPUBLISH(Publish* pub);
|
||||
int setAck(unsigned char msgType, unsigned short msgid);
|
||||
int setHeader(unsigned char msgType);
|
||||
int setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId);
|
||||
int setSUBSCRIBE(const char* topic, unsigned char qos,
|
||||
unsigned short msgId);
|
||||
int setUNSUBSCRIBE(const char* topics, unsigned short msgid);
|
||||
|
||||
UTF8String getTopic(void);
|
||||
|
||||
@@ -39,7 +39,8 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -65,7 +66,8 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
*msg = *packet;
|
||||
if (msg->getType() == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
return;
|
||||
}
|
||||
@@ -99,16 +101,17 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
topicId.type = tp->getType();
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
topicId.data.id = tp->getTopicId();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This message might be subscribed with wild card. */
|
||||
/* This message might be subscribed with wild card or not cleanSession*/
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
Topic* topic = client->getTopics()->match(&topicId);
|
||||
if (topic == nullptr)
|
||||
|
||||
if (topic == nullptr && client->isCleanSession())
|
||||
{
|
||||
WRITELOG(" Invalid Topic. PUBLISH message is canceled.\n");
|
||||
WRITELOG("%sMQTTGWPublishHandler Invalid Topic. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
if (pub.header.bits.qos == 1)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
@@ -122,10 +125,25 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
return;
|
||||
}
|
||||
|
||||
if (topic == nullptr)
|
||||
{
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
topicId.data.id = 0;
|
||||
}
|
||||
|
||||
/* add the Topic and get a TopicId */
|
||||
topic = client->getTopics()->add(&topicId);
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG(
|
||||
"%sMQTTGWPublishHandler Can't Add a Topic. MAX_TOPIC_PAR_CLIENT is exceeded. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
id = topic->getTopicId();
|
||||
|
||||
if (id > 0)
|
||||
{
|
||||
/* create REGISTER */
|
||||
@@ -145,15 +163,15 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
|
||||
/* send PUBLISH */
|
||||
topicId.data.id = id;
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos,
|
||||
(uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload,
|
||||
pub.payloadlen);
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
|
||||
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
|
||||
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
@@ -193,7 +211,8 @@ void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return;
|
||||
}
|
||||
WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t)ack.msgId, client->getClientId());
|
||||
WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t) ack.msgId,
|
||||
client->getClientId());
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int type)
|
||||
@@ -234,8 +253,6 @@ void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int t
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
@@ -272,7 +289,6 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket*
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
|
||||
|
||||
string* topicName = new string(pub.topic, pub.topiclen); // topic deletes topicName when the topic is deleted
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
|
||||
@@ -287,7 +303,8 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket*
|
||||
|
||||
if (msg->getType() == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTGWPUBLISHHANDLER_H_ */
|
||||
|
||||
@@ -96,4 +96,3 @@ void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacke
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CONNECT
|
||||
*/
|
||||
@@ -70,7 +69,6 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
||||
|
||||
/* CONNECT was not sent yet. prepare Connect data */
|
||||
|
||||
|
||||
client->setSessionStatus(false);
|
||||
if (data.cleansession)
|
||||
{
|
||||
@@ -120,7 +118,6 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* WILLMSG
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <string.h>
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Adapter
|
||||
=====================================*/
|
||||
@@ -48,7 +47,6 @@ Adapter::~Adapter(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
||||
{
|
||||
_isSecure = false;
|
||||
@@ -69,12 +67,12 @@ void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
||||
setClient(client, false);
|
||||
client->setAdapterType(adapterType);
|
||||
|
||||
client = _gateway->getClientList()->createClient(0, &idSecure, true, true, TRANSPEARENT_TYPE);
|
||||
client = _gateway->getClientList()->createClient(0, &idSecure, true, true,
|
||||
TRANSPEARENT_TYPE);
|
||||
setClient(client, true);
|
||||
client->setAdapterType(adapterType);
|
||||
}
|
||||
|
||||
|
||||
Client* Adapter::getClient(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = _gateway->getClientList()->getClient(addr);
|
||||
@@ -174,7 +172,8 @@ void Adapter::send(MQTTSNPacket* packet, Client* client)
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -212,7 +211,6 @@ void Adapter::savePacket(Client* client, MQTTSNPacket* packet)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Client* Adapter::getAdapterClient(Client* client)
|
||||
{
|
||||
if (client->isSecureNetwork())
|
||||
@@ -276,7 +274,6 @@ void Proxy::checkConnection(Client* client)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Proxy::resetPingTimer(void)
|
||||
{
|
||||
_keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL);
|
||||
|
||||
@@ -31,7 +31,8 @@ class EventQue;
|
||||
class Timer;
|
||||
|
||||
/* When you add a new type, Client::setAdapterType() and Client::isAdapter() functions must be modified. */
|
||||
typedef enum{
|
||||
typedef enum
|
||||
{
|
||||
Atype_QoSm1Proxy, Atype_Aggregater
|
||||
} AdapterType;
|
||||
|
||||
@@ -69,7 +70,6 @@ private:
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Proxy
|
||||
=====================================*/
|
||||
@@ -88,7 +88,8 @@ public:
|
||||
private:
|
||||
void sendSuspendedPacket(void);
|
||||
Gateway* _gateway;
|
||||
EventQue* _suspendedPacketEventQue {nullptr};
|
||||
EventQue* _suspendedPacketEventQue
|
||||
{ nullptr };
|
||||
Timer _keepAliveTimer;
|
||||
Timer _responseTimer;
|
||||
bool _isWaitingResp { false };
|
||||
|
||||
@@ -39,7 +39,6 @@ AdapterManager::AdapterManager(Gateway* gw)
|
||||
_aggregater = new Aggregater(gw);
|
||||
}
|
||||
|
||||
|
||||
void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bool qosM1)
|
||||
{
|
||||
if (aggregate)
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
bool isAggregatedClient(Client* client);
|
||||
Client* getClient(Client* client);
|
||||
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId);
|
||||
int unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task);
|
||||
int unicastToClient(Client* client, MQTTSNPacket* packet,
|
||||
ClientSendTask* task);
|
||||
bool isAggregaterActive(void);
|
||||
|
||||
private:
|
||||
@@ -59,8 +60,5 @@ private:
|
||||
Aggregater* _aggregater { nullptr };
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */
|
||||
|
||||
@@ -68,7 +68,8 @@ public:
|
||||
|
||||
ClientTopicElement* add(Client* client);
|
||||
ClientTopicElement* getFirstClientTopicElement(void);
|
||||
ClientTopicElement* getNextClientTopicElement(ClientTopicElement* elmClient);
|
||||
ClientTopicElement* getNextClientTopicElement(
|
||||
ClientTopicElement* elmClient);
|
||||
void eraseClient(Client* client);
|
||||
ClientTopicElement* find(Client* client);
|
||||
|
||||
@@ -103,6 +104,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
Aggregater::Aggregater(Gateway* gw) : Adapter(gw)
|
||||
Aggregater::Aggregater(Gateway* gw) :
|
||||
Adapter(gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
}
|
||||
@@ -63,7 +64,6 @@ Client* Aggregater::convertClient(uint16_t msgId, uint16_t* clientMsgId)
|
||||
return _msgIdTable.getClientMsgId(msgId, clientMsgId);
|
||||
}
|
||||
|
||||
|
||||
uint16_t Aggregater::addMessageIdTable(Client* client, uint16_t msgId)
|
||||
{
|
||||
/* set Non secure client`s nextMsgId. otherwise Id is duplicated.*/
|
||||
@@ -89,7 +89,6 @@ AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* clien
|
||||
return _topicTable.add(topic, client);
|
||||
}
|
||||
|
||||
|
||||
void Aggregater::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
_topicTable.erase(topic, client);
|
||||
|
||||
@@ -73,10 +73,6 @@ private:
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "MQTTSNGWBrokerRecvTask.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTSNGWClientList.h"
|
||||
#include "MQTTSNGateway.h"
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -32,11 +33,11 @@ BrokerRecvTask::BrokerRecvTask(Gateway* gateway)
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_light = nullptr;
|
||||
setTaskName("BrokerRecvTask");
|
||||
}
|
||||
|
||||
BrokerRecvTask::~BrokerRecvTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +65,7 @@ void BrokerRecvTask::run(void)
|
||||
_light->blueLight(false);
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("\n%s BrokerRecvTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
return;
|
||||
}
|
||||
timeout.tv_sec = 0;
|
||||
@@ -100,6 +101,7 @@ void BrokerRecvTask::run(void)
|
||||
{
|
||||
/* Check sockets is ready to read */
|
||||
int activity = select(maxSock + 1, &rset, 0, 0, &timeout);
|
||||
|
||||
if (activity > 0)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(0);
|
||||
@@ -134,47 +136,43 @@ void BrokerRecvTask::run(void)
|
||||
{
|
||||
if (rc == 0) // Disconnected
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask %s is disconnected by the broker.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
client->getNetwork()->close();
|
||||
delete packet;
|
||||
|
||||
/* delete client when the client is not authorized & session is clean */
|
||||
_gateway->getClientList()->erase(client);
|
||||
|
||||
if ( client )
|
||||
{
|
||||
client = client->getNextClient();
|
||||
}
|
||||
continue;
|
||||
client->disconnected();
|
||||
}
|
||||
else if (rc == -1)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n", ERRMSG_HEADER, errno, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n",
|
||||
ERRMSG_HEADER, errno, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else if (rc == -2)
|
||||
{
|
||||
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)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't get memories for the packet %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s BrokerRecvTask can't allocate memories for the packet %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
|
||||
delete packet;
|
||||
|
||||
if ((rc == -1 || rc == -2) && (client->isActive() || client->isSleep() || client->isAwake()))
|
||||
{
|
||||
/* disconnect the client */
|
||||
packet = new MQTTGWPacket();
|
||||
packet->setHeader(DISCONNECT);
|
||||
ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextClient:
|
||||
client = client->getNextClient();
|
||||
nextClient: client = client->getNextClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,17 +194,20 @@ int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGRESP:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace MQTTSNGW
|
||||
class BrokerRecvTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
;
|
||||
|
||||
public:
|
||||
BrokerRecvTask(Gateway* gateway);
|
||||
~BrokerRecvTask();
|
||||
@@ -44,5 +44,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* MQTTSNGWBROKERRECVTASK_H_ */
|
||||
|
||||
@@ -37,11 +37,11 @@ BrokerSendTask::BrokerSendTask(Gateway* gateway)
|
||||
_gateway->attach((Thread*) this);
|
||||
_gwparams = nullptr;
|
||||
_light = nullptr;
|
||||
setTaskName("BrokerSendTask");
|
||||
}
|
||||
|
||||
BrokerSendTask::~BrokerSendTask()
|
||||
{
|
||||
// WRITELOG("BrokerSendTask is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +70,7 @@ void BrokerSendTask::run()
|
||||
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("\n%s BrokerSendTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
@@ -94,8 +94,9 @@ void BrokerSendTask::run()
|
||||
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*)_gwparams->brokerName, (const char*)_gwparams->portSecure, (const char*)_gwparams->rootCApath,
|
||||
(const char*)_gwparams->rootCAfile, (const char*)_gwparams->certKey, (const char*)_gwparams->privateKey);
|
||||
rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->portSecure,
|
||||
(const char*) _gwparams->rootCApath, (const char*) _gwparams->rootCAfile,
|
||||
(const char*) _gwparams->certKey, (const char*) _gwparams->privateKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -151,7 +152,6 @@ void BrokerSendTask::run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* write message content into stdout or Ringbuffer
|
||||
*/
|
||||
@@ -163,10 +163,12 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
@@ -174,13 +176,16 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGREQ:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case DISCONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -28,17 +28,17 @@
|
||||
using namespace MQTTSNGW;
|
||||
char* currentDateTime(void);
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Client
|
||||
=====================================*/
|
||||
static const char* theClientStatus[] = { "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake", "Lost" };
|
||||
static const char* theClientStatus[] = { "InPool", "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake",
|
||||
"Lost" };
|
||||
|
||||
Client::Client(bool secure)
|
||||
{
|
||||
_packetId = 0;
|
||||
_snMsgId = 0;
|
||||
_status = Cstat_Disconnected;
|
||||
_status = Cstat_Free;
|
||||
_keepAliveMsec = 0;
|
||||
_topics = new Topics();
|
||||
_clientId = nullptr;
|
||||
@@ -58,7 +58,7 @@ Client::Client(bool secure)
|
||||
_hasPredefTopic = false;
|
||||
_holdPingRequest = false;
|
||||
_forwarder = nullptr;
|
||||
_clientType = Ctype_Regular;
|
||||
_clientType = Ctype_Normal;
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
@@ -177,13 +177,14 @@ void Client::clearWaitedSubTopicId(void)
|
||||
_waitedSubTopicIdMap.clear();
|
||||
}
|
||||
|
||||
void Client::setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
void Client::setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_waitedPubTopicIdMap.add(msgId, topicId, type);
|
||||
_waitedPubTopicIdMap.add(msgId, topicId, topic);
|
||||
}
|
||||
void Client::setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
|
||||
void Client::setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_waitedSubTopicIdMap.add(msgId, topicId, type);
|
||||
_waitedSubTopicIdMap.add(msgId, topicId, topic);
|
||||
}
|
||||
|
||||
bool Client::checkTimeover(void)
|
||||
@@ -280,8 +281,7 @@ void Client::updateStatus(MQTTSNPacket* packet)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
|
||||
}DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
|
||||
}
|
||||
|
||||
void Client::updateStatus(ClientStatus stat)
|
||||
@@ -317,6 +317,11 @@ void Client::tryConnect(void)
|
||||
_status = Cstat_TryConnecting;
|
||||
}
|
||||
|
||||
bool Client::isCleanSession(void)
|
||||
{
|
||||
return _sessionStatus;
|
||||
}
|
||||
|
||||
bool Client::isConnectSendable(void)
|
||||
{
|
||||
if (_status == Cstat_Lost || _status == Cstat_TryConnecting)
|
||||
@@ -537,7 +542,7 @@ void Client::setAdapterType(AdapterType type)
|
||||
_clientType = Ctype_Aggregater;
|
||||
break;
|
||||
default:
|
||||
throw Exception("Client::setAdapterType(): Invalid Type.");
|
||||
throw EXCEPTION("Client::setAdapterType(): Invalid Type.", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -577,8 +582,6 @@ bool Client::isHoldPingReqest(void)
|
||||
return _holdPingRequest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class WaitREGACKPacket
|
||||
=====================================*/
|
||||
@@ -691,4 +694,3 @@ uint8_t WaitREGACKPacketList::getCount(void)
|
||||
return _cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
_que = new Que<T>;
|
||||
}
|
||||
|
||||
|
||||
~PacketQue()
|
||||
{
|
||||
clear();
|
||||
@@ -72,8 +71,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
post(T* packet)
|
||||
int post(T* packet)
|
||||
{
|
||||
int rc;
|
||||
_mutex.lock();
|
||||
@@ -113,8 +111,6 @@ private:
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class WaitREGACKPacket
|
||||
=====================================*/
|
||||
@@ -151,19 +147,29 @@ private:
|
||||
waitREGACKPacket* _end;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Client
|
||||
=====================================*/
|
||||
typedef enum
|
||||
{
|
||||
Cstat_Disconnected = 0, Cstat_TryConnecting, Cstat_Connecting, Cstat_Active, Cstat_Asleep, Cstat_Awake, Cstat_Lost
|
||||
Cstat_Free = 0,
|
||||
Cstat_Disconnected,
|
||||
Cstat_TryConnecting,
|
||||
Cstat_Connecting,
|
||||
Cstat_Active,
|
||||
Cstat_Asleep,
|
||||
Cstat_Awake,
|
||||
Cstat_Lost
|
||||
} ClientStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Ctype_Regular = 0, Ctype_Forwarded, Ctype_QoS_1, Ctype_Aggregated, Ctype_Proxy, Ctype_Aggregater
|
||||
Ctype_Normal = 0,
|
||||
Ctype_Forwarded,
|
||||
Ctype_QoS_1,
|
||||
Ctype_Aggregated,
|
||||
Ctype_Proxy,
|
||||
Ctype_Aggregater
|
||||
} ClientType;
|
||||
|
||||
class Forwarder;
|
||||
@@ -171,6 +177,7 @@ class Forwarder;
|
||||
class Client
|
||||
{
|
||||
friend class ClientList;
|
||||
friend class ClientsPool;
|
||||
public:
|
||||
Client(bool secure = false);
|
||||
Client(uint8_t maxInflightMessages, bool secure);
|
||||
@@ -193,8 +200,8 @@ public:
|
||||
|
||||
int setClientSleepPacket(MQTTGWPacket*);
|
||||
int setProxyPacket(MQTTSNPacket* packet);
|
||||
void setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
void setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
|
||||
bool checkTimeover(void);
|
||||
void updateStatus(MQTTSNPacket*);
|
||||
@@ -249,6 +256,7 @@ public:
|
||||
bool isSecureNetwork(void);
|
||||
bool isSensorNetStable(void);
|
||||
bool isWaitWillMsg(void);
|
||||
bool isCleanSession(void);
|
||||
|
||||
void holdPingRequest(void);
|
||||
void resetPingRequest(void);
|
||||
@@ -299,7 +307,5 @@ private:
|
||||
Client* _prevClient;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWCLIENT_H_ */
|
||||
|
||||
@@ -20,18 +20,20 @@
|
||||
#include <string>
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
extern Gateway* theGateway;
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
const char* common_topic = "*";
|
||||
|
||||
ClientList::ClientList()
|
||||
ClientList::ClientList(Gateway* gw)
|
||||
{
|
||||
_clientCnt = 0;
|
||||
_authorize = false;
|
||||
_firstClient = nullptr;
|
||||
_endClient = nullptr;
|
||||
_clientsPool = new ClientsPool();
|
||||
_gateway = gw;
|
||||
}
|
||||
|
||||
ClientList::~ClientList()
|
||||
@@ -46,12 +48,20 @@ ClientList::~ClientList()
|
||||
delete cl;
|
||||
cl = ncl;
|
||||
};
|
||||
|
||||
if (_clientsPool)
|
||||
{
|
||||
delete _clientsPool;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void ClientList::initialize(bool aggregate)
|
||||
{
|
||||
if (theGateway->getGWParams()->clientAuthentication )
|
||||
_maxClients = _gateway->getGWParams()->maxClients;
|
||||
_clientsPool->allocate(_gateway->getGWParams()->maxClients);
|
||||
|
||||
if (_gateway->getGWParams()->clientAuthentication)
|
||||
{
|
||||
int type = TRANSPEARENT_TYPE;
|
||||
if (aggregate)
|
||||
@@ -62,7 +72,7 @@ void ClientList::initialize(bool aggregate)
|
||||
_authorize = true;
|
||||
}
|
||||
|
||||
if ( theGateway->getGWParams()->predefinedTopic )
|
||||
if (_gateway->getGWParams()->predefinedTopic)
|
||||
{
|
||||
setPredefinedTopics(aggregate);
|
||||
}
|
||||
@@ -70,17 +80,17 @@ void ClientList::initialize(bool aggregate)
|
||||
|
||||
void ClientList::setClientList(int type)
|
||||
{
|
||||
if (!createList(theGateway->getGWParams()->clientListName, type))
|
||||
if (!createList(_gateway->getGWParams()->clientListName, type))
|
||||
{
|
||||
throw Exception("ClientList::setClientList No client list defined by config file.");
|
||||
throw EXCEPTION("ClientList::setClientList Client list not found!", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientList::setPredefinedTopics(bool aggrecate)
|
||||
{
|
||||
if ( !readPredefinedList(theGateway->getGWParams()->predefinedTopicFileName, aggrecate) )
|
||||
if (!readPredefinedList(_gateway->getGWParams()->predefinedTopicFileName, aggrecate))
|
||||
{
|
||||
throw Exception("ClientList::setPredefinedTopics No predefindTopi list defined by config file.");
|
||||
throw EXCEPTION("ClientList::setPredefinedTopics PredefindTopic list not found!", 0);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -154,7 +164,7 @@ bool ClientList::createList(const char* fileName, int type)
|
||||
}
|
||||
else if (forwarder && type == FORWARDER_TYPE)
|
||||
{
|
||||
theGateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
|
||||
_gateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
|
||||
}
|
||||
else if (type == TRANSPEARENT_TYPE)
|
||||
{
|
||||
@@ -179,7 +189,8 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
FILE* fp;
|
||||
char buf[MAX_CLIENTID_LENGTH + 256];
|
||||
size_t pos0, pos1;
|
||||
MQTTSNString clientId = MQTTSNString_initializer;;
|
||||
MQTTSNString clientId = MQTTSNString_initializer;
|
||||
;
|
||||
bool rc = false;
|
||||
|
||||
if ((fp = fopen(fileName, "r")) != 0)
|
||||
@@ -297,7 +308,6 @@ Client* ClientList::getClient(int index)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Client* ClientList::getClient(MQTTSNString* clientId)
|
||||
{
|
||||
_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* client = nullptr;
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return 0; // full of clients
|
||||
}
|
||||
|
||||
client = getClient(addr);
|
||||
Client* client = getClient(addr);
|
||||
if (client)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
/* creat a new client */
|
||||
client = new Client(secure);
|
||||
/* acquire a free client */
|
||||
client = _clientsPool->getClient();
|
||||
|
||||
if (!client)
|
||||
{
|
||||
WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(),
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
client->disconnected();
|
||||
if (addr)
|
||||
{
|
||||
client->setClientAddress(addr);
|
||||
@@ -370,6 +381,7 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
{
|
||||
client->setQoSm1();
|
||||
}
|
||||
client->getNetwork()->setSecure(secure);
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
@@ -400,7 +412,7 @@ Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicN
|
||||
|
||||
if (strcmp(clientId->cstring, common_topic) == 0)
|
||||
{
|
||||
theGateway->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
@@ -412,37 +424,11 @@ Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicN
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return nullptr; // full of clients
|
||||
}
|
||||
client = createClient(NULL, clientId, aggregate);
|
||||
|
||||
if (client == nullptr)
|
||||
{
|
||||
/* creat a new client */
|
||||
client = new Client();
|
||||
client->setClientId(*clientId);
|
||||
if ( aggregate )
|
||||
{
|
||||
client->setAggregated();
|
||||
}
|
||||
_mutex.lock();
|
||||
|
||||
/* add the list */
|
||||
if ( _firstClient == nullptr )
|
||||
{
|
||||
_firstClient = client;
|
||||
_endClient = client;
|
||||
}
|
||||
else
|
||||
{
|
||||
_endClient->_nextClient = client;
|
||||
client->_prevClient = _endClient;
|
||||
_endClient = client;
|
||||
}
|
||||
_clientCnt++;
|
||||
_mutex.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// create Topic & Add it
|
||||
@@ -462,4 +448,70 @@ bool ClientList::isAuthorized()
|
||||
return _authorize;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Class ClientsPool
|
||||
******************************/
|
||||
|
||||
ClientsPool::ClientsPool()
|
||||
{
|
||||
_clientCnt = 0;
|
||||
_firstClient = nullptr;
|
||||
_endClient = nullptr;
|
||||
}
|
||||
|
||||
ClientsPool::~ClientsPool()
|
||||
{
|
||||
Client* cl = _firstClient;
|
||||
Client* ncl;
|
||||
|
||||
while (cl != nullptr)
|
||||
{
|
||||
ncl = cl->_nextClient;
|
||||
delete cl;
|
||||
cl = ncl;
|
||||
};
|
||||
}
|
||||
|
||||
void ClientsPool::allocate(int maxClients)
|
||||
{
|
||||
Client* cl = nullptr;
|
||||
|
||||
_firstClient = new Client();
|
||||
|
||||
for (int i = 0; i < maxClients; i++)
|
||||
{
|
||||
if ((cl = new Client()) == nullptr)
|
||||
{
|
||||
throw Exception("ClientsPool::Can't allocate max number of clients\n", 0);
|
||||
}
|
||||
cl->_nextClient = _firstClient;
|
||||
_firstClient = cl;
|
||||
_clientCnt++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Client* ClientsPool::getClient(void)
|
||||
{
|
||||
Client *cl = nullptr;
|
||||
|
||||
while (_firstClient != nullptr)
|
||||
{
|
||||
cl = _firstClient;
|
||||
_firstClient = cl->_nextClient;
|
||||
cl->_nextClient = nullptr;
|
||||
_clientCnt--;
|
||||
break;
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
void ClientsPool::setClient(Client* client)
|
||||
{
|
||||
if (client)
|
||||
{
|
||||
client->_nextClient = _firstClient;
|
||||
_firstClient = client;
|
||||
_clientCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,21 +30,41 @@ namespace MQTTSNGW
|
||||
|
||||
class Client;
|
||||
|
||||
/*=====================================
|
||||
Class ClientsPool
|
||||
=====================================*/
|
||||
class ClientsPool
|
||||
{
|
||||
public:
|
||||
ClientsPool();
|
||||
~ClientsPool();
|
||||
void allocate(int maxClients);
|
||||
Client* getClient(void);
|
||||
void setClient(Client* client);
|
||||
|
||||
private:
|
||||
Client* _firstClient;
|
||||
Client* _endClient;
|
||||
int _clientCnt;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
class ClientList
|
||||
{
|
||||
public:
|
||||
ClientList();
|
||||
ClientList(Gateway* gw);
|
||||
~ClientList();
|
||||
|
||||
void initialize(bool aggregate);
|
||||
void setClientList(int type);
|
||||
void setPredefinedTopics(bool aggregate);
|
||||
void erase(Client*&);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
bool unstableLine, bool secure, int type);
|
||||
bool createList(const char* fileName, int type);
|
||||
Client* getClient(SensorNetAddress* addr);
|
||||
Client* getClient(MQTTSNString* clientId);
|
||||
@@ -55,18 +75,18 @@ public:
|
||||
|
||||
private:
|
||||
bool readPredefinedList(const char* fileName, bool _aggregate);
|
||||
Gateway* _gateway {nullptr};
|
||||
Client* createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t toipcId, bool _aggregate);
|
||||
ClientsPool* _clientsPool;
|
||||
Gateway* _gateway;
|
||||
Client* createPredefinedTopic(MQTTSNString* clientId, string topicName,
|
||||
uint16_t toipcId, bool _aggregate);
|
||||
Client* _firstClient;
|
||||
Client* _endClient;
|
||||
Mutex _mutex;
|
||||
uint16_t _clientCnt;
|
||||
uint16_t _maxClients;
|
||||
bool _authorize { false };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||
#include <cstring>
|
||||
|
||||
//#include "MQTTSNGWForwarder.h"
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
@@ -32,27 +30,20 @@ ClientRecvTask::ClientRecvTask(Gateway* gateway)
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
setTaskName("ClientRecvTask");
|
||||
}
|
||||
|
||||
ClientRecvTask::~ClientRecvTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize SensorNetwork
|
||||
*/
|
||||
void ClientRecvTask::initialize(int argc, char** argv)
|
||||
{
|
||||
if ( _sensorNetwork->initialize() < 0 )
|
||||
{
|
||||
throw Exception(" Can't open the sensor network.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a packet from clients via sensor netwwork
|
||||
* and generate a event to execute the packet handling procedure
|
||||
* and creats a event to execute the packet handling procedure
|
||||
* of MQTTSNPacketHandlingTask.
|
||||
*/
|
||||
void ClientRecvTask::run()
|
||||
@@ -63,6 +54,7 @@ void ClientRecvTask::run()
|
||||
int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE;
|
||||
ClientList* clientList = _gateway->getClientList();
|
||||
EventQue* packetEventQue = _gateway->getPacketEventQue();
|
||||
EventQue* clientsendQue = _gateway->getClientSendQue();
|
||||
|
||||
char buf[128];
|
||||
|
||||
@@ -77,7 +69,7 @@ void ClientRecvTask::run()
|
||||
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("\n%s ClientRecvTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete packet;
|
||||
return;
|
||||
}
|
||||
@@ -104,12 +96,11 @@ void ClientRecvTask::run()
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
SensorNetAddress* senderAddr = _gateway->getSensorNetwork()->getSenderAddress();
|
||||
SensorNetAddress senderAddr = *_gateway->getSensorNetwork()->getSenderAddress();
|
||||
|
||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||
{
|
||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(senderAddr);
|
||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(&senderAddr);
|
||||
|
||||
if (fwd != nullptr)
|
||||
{
|
||||
@@ -131,7 +122,7 @@ void ClientRecvTask::run()
|
||||
|
||||
if (qosm1Proxy->isActive())
|
||||
{
|
||||
const char* clientName = qosm1Proxy->getClientId(senderAddr);
|
||||
const char *clientName = qosm1Proxy->getClientId(&senderAddr);
|
||||
|
||||
if (clientName != nullptr)
|
||||
{
|
||||
@@ -140,7 +131,8 @@ void ClientRecvTask::run()
|
||||
if (!packet->isQoSMinusPUBLISH())
|
||||
{
|
||||
log(clientName, packet);
|
||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n", ERRMSG_HEADER, clientName, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n",
|
||||
ERRMSG_HEADER, clientName, senderAddr.sprint(buf), ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
@@ -149,18 +141,35 @@ void ClientRecvTask::run()
|
||||
|
||||
if (client == nullptr)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(senderAddr);
|
||||
client = _gateway->getClientList()->getClient(&senderAddr);
|
||||
}
|
||||
}
|
||||
|
||||
if (client != nullptr)
|
||||
{
|
||||
/* write log and post Event */
|
||||
log(client, packet, 0);
|
||||
|
||||
if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT)
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
|
||||
/* send DISCONNECT to the client, if it is not connected */
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
ev = new Event();
|
||||
ev->setClientSendEvent(client, snPacket);
|
||||
clientsendQue->post(ev);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
packetEventQue->post(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new client */
|
||||
@@ -171,7 +180,9 @@ void ClientRecvTask::run()
|
||||
if (!packet->getCONNECT(&data))
|
||||
{
|
||||
log(0, packet, &data.clientID);
|
||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
@@ -195,13 +206,13 @@ void ClientRecvTask::run()
|
||||
/* Authentication is not required */
|
||||
if (_gateway->getGWParams()->clientAuthentication == false)
|
||||
{
|
||||
client->setClientAddress(senderAddr);
|
||||
client->setClientAddress(&senderAddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a new client */
|
||||
client = clientList->createClient(senderAddr, &data.clientID, clientType);
|
||||
client = clientList->createClient(&senderAddr, &data.clientID, clientType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +220,9 @@ void ClientRecvTask::run()
|
||||
|
||||
if (client == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
@@ -224,11 +237,16 @@ void ClientRecvTask::run()
|
||||
log(client, packet, 0);
|
||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n", ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG(
|
||||
"%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
delete packet;
|
||||
}
|
||||
@@ -275,11 +293,13 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_SEARCHGW:
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), LEFTARROW, CLIENT, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
|
||||
LEFTARROW, CLIENT, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNECT:
|
||||
case MQTTSN_PINGREQ:
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
|
||||
LEFTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
@@ -292,14 +312,16 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_ENCAPSULATED:
|
||||
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
|
||||
@@ -31,11 +31,11 @@ ClientSendTask::ClientSendTask(Gateway* gateway)
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
setTaskName("ClientSendTask");
|
||||
}
|
||||
|
||||
ClientSendTask::~ClientSendTask()
|
||||
{
|
||||
// WRITELOG("ClientSendTask is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
void ClientSendTask::run()
|
||||
@@ -51,7 +51,7 @@ void ClientSendTask::run()
|
||||
|
||||
if (ev->getEventType() == EtStop || _gateway->IsStopping())
|
||||
{
|
||||
WRITELOG("\n%s ClientSendTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
break;
|
||||
}
|
||||
@@ -85,7 +85,8 @@ void ClientSendTask::run()
|
||||
if (rc < 0)
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't send a packet to the client %s. Error=%d%s\n",
|
||||
ERRMSG_HEADER, (client ? (const char*)client->getClientId() : UNKNOWNCL ), errno, ERRMSG_FOOTER);
|
||||
ERRMSG_HEADER, (client ? (const char*) client->getClientId() : UNKNOWNCL),
|
||||
errno, ERRMSG_FOOTER);
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
@@ -102,7 +103,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
case MQTTSN_ADVERTISE:
|
||||
case MQTTSN_GWINFO:
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, CLIENTS, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW,
|
||||
CLIENTS, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNACK:
|
||||
case MQTTSN_DISCONNECT:
|
||||
@@ -115,7 +117,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
@@ -124,7 +127,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_SUBACK:
|
||||
case MQTTSN_UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -125,7 +125,8 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
||||
/* renew the TopicList */
|
||||
if (topics)
|
||||
{
|
||||
topics->eraseNormal();;
|
||||
topics->eraseNormal();
|
||||
;
|
||||
}
|
||||
client->setSessionStatus(true);
|
||||
}
|
||||
@@ -146,7 +147,8 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
||||
/* CONNECT message was not qued in.
|
||||
* create CONNECT message & send it to the broker */
|
||||
MQTTGWPacket* mqMsg = new MQTTGWPacket();
|
||||
mqMsg->setCONNECT(client->getConnectData(), (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password);
|
||||
mqMsg->setCONNECT(client->getConnectData(), (unsigned char*) _gateway->getGWParams()->loginId,
|
||||
(unsigned char*) _gateway->getGWParams()->password);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, mqMsg);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
@@ -209,7 +211,8 @@ void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet
|
||||
/* create CONNECT message */
|
||||
MQTTGWPacket* mqttPacket = new MQTTGWPacket();
|
||||
connectData->willMsg = client->getWillMsg();
|
||||
mqttPacket->setCONNECT(connectData, (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password);
|
||||
mqttPacket->setCONNECT(connectData, (unsigned char*) _gateway->getGWParams()->loginId,
|
||||
(unsigned char*) _gateway->getGWParams()->password);
|
||||
|
||||
/* Send CONNECT to the broker */
|
||||
Event* evt = new Event();
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace MQTTSNGW
|
||||
/*=================================
|
||||
* MQTT-SN Parametrs
|
||||
==================================*/
|
||||
#define MAX_CLIENTS (100) // Number of Clients can be handled.
|
||||
#define MAX_CLIENTS (100) // Default number of Clients can be handled.
|
||||
#define MAX_CLIENTID_LENGTH (64) // Max length of clientID
|
||||
#define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages
|
||||
#define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size
|
||||
@@ -60,14 +60,19 @@ typedef unsigned int uint32_t;
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
|
||||
#ifdef DEBUG
|
||||
//#define DEBUG_MQTTSN // print out log for debug
|
||||
//#define DEBUG_NW // print out SensorNetwork log
|
||||
#ifdef DEBUG_MQTTSN
|
||||
#define DEBUGLOG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUGLOG(...)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWDEFINES_H_ */
|
||||
|
||||
@@ -21,10 +21,8 @@
|
||||
using namespace MQTTSNGW;
|
||||
using namespace std;
|
||||
|
||||
WirelessNodeId::WirelessNodeId()
|
||||
:
|
||||
_len{0},
|
||||
_nodeId{0}
|
||||
WirelessNodeId::WirelessNodeId() :
|
||||
_len { 0 }, _nodeId { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
@@ -77,16 +75,14 @@ bool WirelessNodeId::operator ==(WirelessNodeId& id)
|
||||
/*
|
||||
* Class MQTTSNGWEncapsulatedPacket
|
||||
*/
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket()
|
||||
: _mqttsn{0},
|
||||
_ctrl{0}
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() :
|
||||
_mqttsn { 0 }, _ctrl { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet)
|
||||
: _mqttsn{packet},
|
||||
_ctrl{0}
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) :
|
||||
_mqttsn { packet }, _ctrl { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -60,6 +60,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */
|
||||
|
||||
@@ -44,14 +44,12 @@ ForwarderList::~ForwarderList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ForwarderList::initialize(Gateway* gw)
|
||||
{
|
||||
/* Create Fowarders from clients.conf */
|
||||
gw->getClientList()->setClientList(FORWARDER_TYPE);
|
||||
}
|
||||
|
||||
|
||||
Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
@@ -251,10 +249,8 @@ SensorNetAddress* Forwarder::getSensorNetAddr(void)
|
||||
* Class ForwardedClient
|
||||
*/
|
||||
|
||||
ForwarderElement::ForwarderElement()
|
||||
: _client{0}
|
||||
, _wirelessNodeId{0}
|
||||
, _next{0}
|
||||
ForwarderElement::ForwarderElement() :
|
||||
_client { 0 }, _wirelessNodeId { 0 }, _next { 0 }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||
#include "SensorNetwork.h"
|
||||
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class Gateway;
|
||||
@@ -94,6 +93,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */
|
||||
|
||||
@@ -115,7 +115,6 @@ MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
Client* MessageIdTable::getClientMsgId(uint16_t msgId, uint16_t* clientMsgId)
|
||||
{
|
||||
Client* clt = nullptr;
|
||||
@@ -179,7 +178,6 @@ void MessageIdTable::clear(MessageIdElement* elm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
uint16_t msgId = 0;
|
||||
@@ -194,18 +192,14 @@ uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
|
||||
/*===============================
|
||||
* Class MessageIdElement
|
||||
===============================*/
|
||||
MessageIdElement::MessageIdElement(void)
|
||||
: _msgId{0}
|
||||
, _clientMsgId {0}
|
||||
, _client {nullptr}
|
||||
, _next {nullptr}
|
||||
, _prev {nullptr}
|
||||
MessageIdElement::MessageIdElement(void) :
|
||||
_msgId { 0 }, _clientMsgId { 0 }, _client { nullptr }, _next { nullptr }, _prev { nullptr }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId)
|
||||
: MessageIdElement()
|
||||
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId) :
|
||||
MessageIdElement()
|
||||
{
|
||||
_msgId = msgId;
|
||||
_client = client;
|
||||
|
||||
@@ -37,7 +37,8 @@ public:
|
||||
MessageIdTable();
|
||||
~MessageIdTable();
|
||||
|
||||
MessageIdElement* add(Aggregater* aggregater, Client* client, uint16_t clientMsgId);
|
||||
MessageIdElement* add(Aggregater* aggregater, Client* client,
|
||||
uint16_t clientMsgId);
|
||||
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
|
||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||
void erase(uint16_t msgId);
|
||||
@@ -72,7 +73,6 @@ private:
|
||||
MessageIdElement* _prev;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */
|
||||
|
||||
@@ -100,10 +100,6 @@ int MQTTSNPacket::recv(SensorNetwork* network)
|
||||
{
|
||||
len = desirialize(buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
}
|
||||
return len;
|
||||
|
||||
}
|
||||
@@ -149,8 +145,7 @@ int MQTTSNPacket::setADVERTISE(uint8_t gatewayid, uint16_t duration)
|
||||
{
|
||||
unsigned char buf[5];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid,
|
||||
(unsigned short) duration);
|
||||
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, (unsigned short) duration);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -205,8 +200,7 @@ int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* to
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
topicName);
|
||||
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, topicName);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -214,18 +208,17 @@ int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode
|
||||
{
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic,
|
||||
uint8_t* payload, uint16_t payloadlen)
|
||||
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic, uint8_t* payload,
|
||||
uint16_t payloadlen)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained,
|
||||
(unsigned short) msgId, topic, (unsigned char*) payload, (int) payloadlen);
|
||||
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained, (unsigned short) msgId,
|
||||
topic, (unsigned char*) payload, (int) payloadlen);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -233,8 +226,7 @@ int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode
|
||||
{
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -266,8 +258,8 @@ int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t r
|
||||
{
|
||||
unsigned char buf[8];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId,
|
||||
(unsigned short) msgId, (unsigned char) returnCode);
|
||||
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -354,26 +346,26 @@ int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
|
||||
|
||||
int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName)
|
||||
{
|
||||
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName,
|
||||
_buf, _bufLen);
|
||||
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
|
||||
_bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId, MQTTSN_topicid* topic,
|
||||
uint8_t** payload, int* payloadlen)
|
||||
{
|
||||
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId,
|
||||
topic, (unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId, topic,
|
||||
(unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode,
|
||||
_buf, _bufLen);
|
||||
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
|
||||
_bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getACK(uint16_t* msgId)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class SensorNetwork;
|
||||
|
||||
class MQTTSNPacket
|
||||
{
|
||||
@@ -53,7 +54,8 @@ public:
|
||||
int setPUBREC(uint16_t msgId);
|
||||
int setPUBREL(uint16_t msgId);
|
||||
int setPUBCOMP(uint16_t msgId);
|
||||
int setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setSUBACK(int qos, uint16_t topicId, uint16_t msgId,
|
||||
uint8_t returnCode);
|
||||
int setUNSUBACK(uint16_t msgId);
|
||||
int setPINGRESP(void);
|
||||
int setDISCONNECT(uint16_t duration);
|
||||
@@ -66,19 +68,23 @@ public:
|
||||
int getSERCHGW(uint8_t* radius);
|
||||
int getCONNECT(MQTTSNPacket_connectData* option);
|
||||
int getCONNACK(uint8_t* returnCode);
|
||||
int getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
||||
int getWILLTOPIC(int* willQoS, uint8_t* willRetain,
|
||||
MQTTSNString* willTopic);
|
||||
int getWILLMSG(MQTTSNString* willmsg);
|
||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName);
|
||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId,
|
||||
MQTTSNString* topicName);
|
||||
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
|
||||
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
|
||||
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getACK(uint16_t* msgId);
|
||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId,
|
||||
MQTTSN_topicid* topicFilter);
|
||||
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getPINGREQ(void);
|
||||
int getDISCONNECT(uint16_t* duration);
|
||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain,
|
||||
MQTTSNString* willTopic);
|
||||
int getWILLMSGUPD(MQTTSNString* willMsg);
|
||||
|
||||
bool isAccepted(void);
|
||||
|
||||
@@ -38,6 +38,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
|
||||
char* currentDateTime(void);
|
||||
|
||||
/*=====================================
|
||||
Class PacketHandleTask
|
||||
=====================================*/
|
||||
@@ -54,6 +55,7 @@ PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
||||
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
|
||||
|
||||
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
|
||||
setTaskName("PacketHandleTask");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +115,7 @@ void PacketHandleTask::run()
|
||||
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("\n%s PacketHandleTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
@@ -155,7 +157,6 @@ void PacketHandleTask::run()
|
||||
transparentPacketHandler(client, snPacket);
|
||||
}
|
||||
|
||||
|
||||
/* Reset the Timer for PINGREQ. */
|
||||
client->updateStatus(snPacket);
|
||||
}
|
||||
@@ -166,7 +167,6 @@ void PacketHandleTask::run()
|
||||
brPacket = ev->getMQTTGWPacket();
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
|
||||
|
||||
|
||||
if (client->isAggregater())
|
||||
{
|
||||
aggregatePacketHandler(client, brPacket);
|
||||
@@ -180,8 +180,6 @@ void PacketHandleTask::run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
@@ -239,7 +237,6 @@ void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
@@ -333,7 +330,6 @@ void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* pac
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
|
||||
@@ -60,7 +60,8 @@ private:
|
||||
void transparentPacketHandler(Client*client, MQTTSNPacket* packet);
|
||||
void transparentPacketHandler(Client*client, MQTTGWPacket* packet);
|
||||
|
||||
Gateway* _gateway {nullptr};
|
||||
Gateway* _gateway
|
||||
{ nullptr };
|
||||
Timer _advertiseTimer;
|
||||
Timer _sendUnixTimer;
|
||||
MQTTGWConnectionHandler* _mqttConnection { nullptr };
|
||||
@@ -69,11 +70,9 @@ private:
|
||||
MQTTSNConnectionHandler* _mqttsnConnection { nullptr };
|
||||
MQTTSNPublishHandler* _mqttsnPublish { nullptr };
|
||||
MQTTSNSubscribeHandler* _mqttsnSubscribe { nullptr };
|
||||
|
||||
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection { nullptr };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGWPACKETHANDLETASK_H_ */
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <Timer.h>
|
||||
@@ -57,6 +57,8 @@ Process::Process()
|
||||
_configDir = CONFIG_DIRECTORY;
|
||||
_configFile = CONFIG_FILE;
|
||||
_log = 0;
|
||||
_rbsem = NULL;
|
||||
_rb = NULL;
|
||||
}
|
||||
|
||||
Process::~Process()
|
||||
@@ -98,7 +100,7 @@ void Process::initialize(int argc, char** argv)
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -155,6 +157,8 @@ int Process::getParam(const char* parameter, char* value)
|
||||
{
|
||||
char str[MQTTSNGW_PARAM_MAX];
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
memset(str, 0, sizeof(str));
|
||||
memset(param, 0, sizeof(param));
|
||||
FILE *fp;
|
||||
|
||||
int i = 0, j = 0;
|
||||
@@ -162,27 +166,41 @@ int Process::getParam(const char* parameter, char* value)
|
||||
|
||||
if ((fp = fopen(configPath.c_str(), "r")) == NULL)
|
||||
{
|
||||
throw Exception("No config file:[" + configPath + "]\n");
|
||||
throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
|
||||
}
|
||||
|
||||
int paramlen = strlen(parameter);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int pos = 0;
|
||||
int len = 0;
|
||||
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (!strncmp(str, parameter, strlen(parameter)))
|
||||
if (str[0] == '#' || str[0] == '\n')
|
||||
{
|
||||
while (str[i++] != '=')
|
||||
{
|
||||
;
|
||||
continue;
|
||||
}
|
||||
while (str[i] != '\n')
|
||||
|
||||
len = strlen(str);
|
||||
for (pos = 0; i < len; pos++)
|
||||
{
|
||||
param[j++] = str[i++];
|
||||
if (str[pos] == '=')
|
||||
{
|
||||
break;
|
||||
}
|
||||
param[j] = '\0';
|
||||
}
|
||||
|
||||
if (pos == paramlen)
|
||||
{
|
||||
if (strncmp(str, parameter, paramlen) == 0)
|
||||
{
|
||||
strcpy(param, str + pos + 1);
|
||||
param[len - pos - 2] = '\0';
|
||||
|
||||
|
||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||
;
|
||||
@@ -201,6 +219,7 @@ int Process::getParam(const char* parameter, char* value)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
@@ -277,8 +296,6 @@ void MultiTaskProcess::run(void)
|
||||
_threadList[i]->start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (theProcess->checkSignal() == SIGINT)
|
||||
@@ -288,15 +305,6 @@ void MultiTaskProcess::run(void)
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
catch(Exception* ex)
|
||||
{
|
||||
ex->writeMessage();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskProcess::waitStop(void)
|
||||
{
|
||||
@@ -314,6 +322,11 @@ void MultiTaskProcess::threadStopped(void)
|
||||
|
||||
}
|
||||
|
||||
void MultiTaskProcess::abort(void)
|
||||
{
|
||||
signalHandler(SIGINT);
|
||||
}
|
||||
|
||||
void MultiTaskProcess::attach(Thread* thread)
|
||||
{
|
||||
_mutex.lock();
|
||||
@@ -325,7 +338,7 @@ void MultiTaskProcess::attach(Thread* thread)
|
||||
else
|
||||
{
|
||||
_mutex.unlock();
|
||||
throw Exception("Full of Threads");
|
||||
throw Exception("The maximum number of threads has been exceeded.", -1);
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
@@ -335,40 +348,26 @@ int MultiTaskProcess::getParam(const char* parameter, char* value)
|
||||
_mutex.lock();
|
||||
int rc = Process::getParam(parameter, value);
|
||||
_mutex.unlock();
|
||||
if (rc == -1)
|
||||
{
|
||||
throw Exception("No config file.");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class Exception
|
||||
======================================*/
|
||||
Exception::Exception(const string& message)
|
||||
Exception::Exception(const char* message, const int errNo)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = 0;
|
||||
_fileName = 0;
|
||||
_functionName = 0;
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
Exception::Exception(const int exNo, const string& message)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = exNo;
|
||||
_errNo = errNo;
|
||||
_fileName = nullptr;
|
||||
_functionName = nullptr;
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
Exception::Exception(const int exNo, const string& message, const char* file,
|
||||
const char* function, const int line)
|
||||
Exception::Exception(const char* message, const int errNo, const char* file, const char* function, const int line)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = exNo;
|
||||
_fileName = file;
|
||||
_errNo = errNo;
|
||||
_fileName = getFileName(file);
|
||||
;
|
||||
_functionName = function;
|
||||
_line = line;
|
||||
}
|
||||
@@ -380,7 +379,7 @@ Exception::~Exception() throw ()
|
||||
|
||||
const char* Exception::what() const throw ()
|
||||
{
|
||||
return _message.c_str();
|
||||
return _message;
|
||||
}
|
||||
|
||||
const char* Exception::getFileName()
|
||||
@@ -398,20 +397,49 @@ const int Exception::getLineNo()
|
||||
return _line;
|
||||
}
|
||||
|
||||
const int Exception::getExceptionNo()
|
||||
const int Exception::getErrNo()
|
||||
{
|
||||
return _exNo;
|
||||
return _errNo;
|
||||
}
|
||||
|
||||
void Exception::writeMessage()
|
||||
{
|
||||
if (getExceptionNo() == 0 )
|
||||
if (_fileName == nullptr)
|
||||
{
|
||||
WRITELOG("%s %s\n", currentDateTime(), what());
|
||||
if (_errNo == 0)
|
||||
{
|
||||
WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s:%-6d %s line %-4d %s() : %s\n", currentDateTime(), getExceptionNo(),
|
||||
getFileName(), getLineNo(), getFunctionName(), what());
|
||||
WRITELOG("%s%s %s.\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message, _errNo,
|
||||
strerror(_errNo), CLR_HDR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_errNo == 0)
|
||||
{
|
||||
WRITELOG("%s%s %s. %s line %-4d %s()%s\n", currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName,
|
||||
CLR_HDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s%s %s. %s line %-4d %s()\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message,
|
||||
_fileName, _line, _functionName, _errNo, strerror(_errNo), CLR_HDR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* Exception::getFileName(const char* file)
|
||||
{
|
||||
for (int len = strlen(file); len > 0; len--)
|
||||
{
|
||||
if (*(file + len) == '/')
|
||||
{
|
||||
return file + len + 1;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace MQTTSNGW
|
||||
#define WRITELOG theProcess->putLog
|
||||
#define CHK_SIGINT (theProcess->checkSignal() == SIGINT)
|
||||
#define UNUSED(x) ((void)(x))
|
||||
#define EXCEPTION(...) Exception(__VA_ARGS__, __FILE__, __func__, __LINE__)
|
||||
|
||||
/*=================================
|
||||
Class Process
|
||||
==================================*/
|
||||
@@ -86,6 +88,7 @@ public:
|
||||
void waitStop(void);
|
||||
void threadStopped(void);
|
||||
void attach(Thread* thread);
|
||||
void abort(void);
|
||||
|
||||
private:
|
||||
Thread* _threadList[MQTTSNGW_MAX_TASK];
|
||||
@@ -100,27 +103,25 @@ private:
|
||||
class Exception: public exception
|
||||
{
|
||||
public:
|
||||
Exception(const string& message);
|
||||
Exception(const int exNo, const string& message);
|
||||
Exception(const int exNo, const string& message,
|
||||
const char* file, const char* func, const int line);
|
||||
Exception(const char* message, const int errNo);
|
||||
Exception(const char* message, const int errNo, const char* file, const char* func, int line);
|
||||
virtual ~Exception() throw ();
|
||||
const char* getFileName();
|
||||
const char* getFunctionName();
|
||||
const int getLineNo();
|
||||
const int getExceptionNo();
|
||||
const int getErrNo();
|
||||
virtual const char* what() const throw ();
|
||||
void writeMessage();
|
||||
|
||||
private:
|
||||
int _exNo;
|
||||
string _message;
|
||||
const char* getFileName(const char* file);
|
||||
int _errNo;
|
||||
const char* _message;
|
||||
const char* _fileName;
|
||||
const char* _functionName;
|
||||
int _line;
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class QueElement
|
||||
====================================*/
|
||||
@@ -263,7 +264,8 @@ private:
|
||||
#define TREE23_TRI_NODE (3)
|
||||
|
||||
template<typename K, typename V>
|
||||
class Tree23Elm{
|
||||
class Tree23Elm
|
||||
{
|
||||
template<typename T, typename U> friend class Tree23;
|
||||
public:
|
||||
Tree23Elm()
|
||||
@@ -292,9 +294,9 @@ private:
|
||||
V* _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename K, typename V>
|
||||
class Tree23Node{
|
||||
class Tree23Node
|
||||
{
|
||||
template<typename S, typename W> friend class Tree23;
|
||||
public:
|
||||
Tree23Node(const int type)
|
||||
@@ -320,7 +322,8 @@ public:
|
||||
_left = _midle = _right = NULL;
|
||||
}
|
||||
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm, Tree23Node<K, V>* left, Tree23Node<K, V>* right)
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm, Tree23Node<K, V>* left,
|
||||
Tree23Node<K, V>* right)
|
||||
{
|
||||
_type = type;
|
||||
_telm0 = telm;
|
||||
@@ -330,7 +333,9 @@ public:
|
||||
_right = right;
|
||||
}
|
||||
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm0, Tree23Elm<K, V>* telm1, Tree23Node<K, V>* left, Tree23Node<K, V>* midle, Tree23Node<K, V>* right)
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm0, Tree23Elm<K, V>* telm1,
|
||||
Tree23Node<K, V>* left, Tree23Node<K, V>* midle,
|
||||
Tree23Node<K, V>* right)
|
||||
{
|
||||
_type = type;
|
||||
_telm0 = telm0;
|
||||
@@ -355,7 +360,8 @@ private:
|
||||
};
|
||||
|
||||
template<typename K, typename V>
|
||||
class Tree23{
|
||||
class Tree23
|
||||
{
|
||||
public:
|
||||
Tree23()
|
||||
{
|
||||
@@ -534,7 +540,8 @@ public:
|
||||
switch (node->_type)
|
||||
{
|
||||
case 2:
|
||||
if ( cmp0 < 0 ) node = node->_left;
|
||||
if (cmp0 < 0)
|
||||
node = node->_left;
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
return true;
|
||||
@@ -574,7 +581,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
V* getVal(K* key)
|
||||
{
|
||||
Tree23Node<K, V>* node = _root;
|
||||
@@ -634,7 +640,8 @@ private:
|
||||
Tree23Node<K, V>* n = node->_left;
|
||||
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;
|
||||
}
|
||||
@@ -645,8 +652,10 @@ private:
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
n->_type = TREE23_BI_NODE;
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, node->_midle, node->_right);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm0, n, nn);
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE,
|
||||
node->_telm1, node->_midle, node->_right);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm0, n,
|
||||
nn);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -656,7 +665,8 @@ private:
|
||||
Tree23Node<K, V>* n = node->_right;
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, n->_telm0, node->_left, n->_left, n->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
n->_telm0, node->_left, n->_left, n->_right);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -664,10 +674,13 @@ private:
|
||||
Tree23Node<K, V>* addRight3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_right;
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE) {
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
n->_type = TREE23_BI_NODE;
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, node->_left, node->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm1, nn, n);
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE,
|
||||
node->_telm0, node->_left, node->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm1, nn,
|
||||
n);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -677,14 +690,15 @@ private:
|
||||
Tree23Node<K, V>* n = node->_midle;
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
n->_left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, node->_left, n->_left);
|
||||
n->_right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, n->_right, node->_right);
|
||||
n->_left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
node->_left, n->_left);
|
||||
n->_right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||
n->_right, node->_right);
|
||||
return n;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
Tree23Node<K, V>* removeMax(Tree23Node<K, V>* node, Tree23Elm<K, V>* elm)
|
||||
{
|
||||
if (node->_right == NULL)
|
||||
@@ -719,7 +733,6 @@ private:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Tree23Node<K, V>* removeLeft2(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_left;
|
||||
@@ -733,12 +746,16 @@ private:
|
||||
switch (r->_type)
|
||||
{
|
||||
case 2:
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, r->_telm0, n->_midle, r->_left, r->_right);
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
r->_telm0, n->_midle, r->_left, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_DELETE_ACTIVE, midle);
|
||||
case 3:
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1, r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm0, left, right);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1,
|
||||
r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm0, left,
|
||||
right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -759,12 +776,16 @@ private:
|
||||
switch (l->_type)
|
||||
{
|
||||
case 2:
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, l->_telm0, node->_telm0, l->_left, l->_right, n->_midle);
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, l->_telm0,
|
||||
node->_telm0, l->_left, l->_right, n->_midle);
|
||||
return new Tree23Node<K, V>(-1, midle);
|
||||
case 3:
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l->_right, n->_midle);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm0, l->_left, l->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm1, left, right);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
l->_right, n->_midle);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm0, l->_left,
|
||||
l->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm1, left,
|
||||
right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -782,14 +803,20 @@ private:
|
||||
Tree23Node<K, V>* left;
|
||||
Tree23Node<K, V>* midle;
|
||||
|
||||
switch (m->_type) {
|
||||
switch (m->_type)
|
||||
{
|
||||
case 2:
|
||||
left = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, m->_telm0, n->_midle, m->_left, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, left, r);
|
||||
left = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
m->_telm0, n->_midle, m->_left, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, left,
|
||||
r);
|
||||
case 3:
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, n->_midle, m->_left);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm1, m->_midle, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0, node->_telm1, left, midle, r);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
n->_midle, m->_left);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm1,
|
||||
m->_midle, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0,
|
||||
node->_telm1, left, midle, r);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -809,12 +836,17 @@ private:
|
||||
switch (r->_type)
|
||||
{
|
||||
case 2:
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm1, r->_telm0, n->_midle, r->_left, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l, right);
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm1,
|
||||
r->_telm0, n->_midle, r->_left, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l,
|
||||
right);
|
||||
case 3:
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1, r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, r->_telm0, l, midle, right);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||
n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1,
|
||||
r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
r->_telm0, l, midle, right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -834,12 +866,17 @@ private:
|
||||
switch (m->_type)
|
||||
{
|
||||
case 2:
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0, node->_telm1, m->_left, m->_right, n->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l, right);
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0,
|
||||
node->_telm1, m->_left, m->_right, n->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l,
|
||||
right);
|
||||
case 3:
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, m->_right, n->_midle);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm0, m->_left, m->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, m->_telm1, l, midle, right);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||
m->_right, n->_midle);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm0,
|
||||
m->_left, m->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
m->_telm1, l, midle, right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -847,7 +884,6 @@ private:
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
Tree23Node<K, V>* _root;
|
||||
};
|
||||
|
||||
@@ -873,18 +909,23 @@ public:
|
||||
{
|
||||
return _elm;
|
||||
}
|
||||
~ListElm(){}
|
||||
~ListElm()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
ListElm<T>* getNext(void){return _next;}
|
||||
ListElm<T>* getNext(void)
|
||||
{
|
||||
return _next;
|
||||
}
|
||||
T* _elm;
|
||||
ListElm<T>* _prev;
|
||||
ListElm<T>* _next;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class List{
|
||||
class List
|
||||
{
|
||||
public:
|
||||
List()
|
||||
{
|
||||
@@ -970,14 +1011,12 @@ public:
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
ListElm<T>* _head;
|
||||
ListElm<T>* _tail;
|
||||
int _size;
|
||||
};
|
||||
|
||||
|
||||
extern Process* theProcess;
|
||||
extern MultiTaskProcess* theMultiTaskProcess;
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
int qos;
|
||||
uint8_t retained;
|
||||
uint16_t msgId;
|
||||
uint16_t tid;
|
||||
uint8_t* payload;
|
||||
MQTTSN_topicid topicid;
|
||||
int payloadlen;
|
||||
@@ -66,6 +67,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
pub.header.bits.dup = dup;
|
||||
pub.header.bits.qos = (qos == 3 ? 0 : qos);
|
||||
pub.header.bits.retain = retained;
|
||||
tid = topicid.data.id;
|
||||
|
||||
Topic* topic = nullptr;
|
||||
|
||||
@@ -114,12 +116,14 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
{
|
||||
pub.topic = (char*) topic->getTopicName()->data();
|
||||
pub.topiclen = topic->getTopicName()->length();
|
||||
topicid.data.long_.name = pub.topic;
|
||||
topicid.data.long_.len = pub.topiclen;
|
||||
}
|
||||
}
|
||||
/* Save a msgId & a TopicId pare for PUBACK */
|
||||
if (msgId && qos > 0 && qos < 3)
|
||||
{
|
||||
client->setWaitedPubTopicId(msgId, topicid.data.id, topicid.type);
|
||||
client->setWaitedPubTopicId(msgId, tid, &topicid);
|
||||
}
|
||||
|
||||
pub.payload = (char*) payload;
|
||||
@@ -194,7 +198,8 @@ void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t msgId;
|
||||
MQTTSNString topicName = MQTTSNString_initializer;;
|
||||
MQTTSNString topicName = MQTTSNString_initializer;
|
||||
;
|
||||
MQTTSN_topicid topicid;
|
||||
|
||||
if (client->isActive() || client->isAwake())
|
||||
@@ -230,6 +235,7 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
||||
return;
|
||||
}
|
||||
|
||||
/* get PUBLISH message */
|
||||
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
|
||||
|
||||
if (regAck != nullptr)
|
||||
@@ -239,6 +245,7 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
||||
ev->setClientSendEvent(client, regAck);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
|
||||
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0)
|
||||
{
|
||||
/* send PINGREQ to the broker */
|
||||
@@ -253,9 +260,6 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
int msgId = 0;
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
/*=====================================
|
||||
Class QoSm1Proxy
|
||||
=====================================*/
|
||||
QoSm1Proxy:: QoSm1Proxy(Gateway* gw) : Adapter(gw)
|
||||
QoSm1Proxy::QoSm1Proxy(Gateway* gw) :
|
||||
Adapter(gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
}
|
||||
@@ -37,7 +37,6 @@ QoSm1Proxy::~QoSm1Proxy(void)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QoSm1Proxy::initialize(char* gwName)
|
||||
{
|
||||
if (_gateway->hasSecureConnection())
|
||||
@@ -54,7 +53,6 @@ void QoSm1Proxy::initialize(char* gwName)
|
||||
_isActive = true;
|
||||
}
|
||||
|
||||
|
||||
bool QoSm1Proxy::isActive(void)
|
||||
{
|
||||
return _isActive;
|
||||
|
||||
@@ -45,9 +45,6 @@ private:
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */
|
||||
|
||||
@@ -62,10 +62,17 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
|
||||
if (!topic)
|
||||
{
|
||||
/* Search the topic in Client common topic table */
|
||||
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
||||
if (topic)
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -85,8 +92,9 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
topic = client->getTopics()->add(&topicFilter);
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
topicId = topic->getTopicId();
|
||||
@@ -106,7 +114,7 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
subscribe->setSUBSCRIBE(topicstr, (uint8_t) qos, (uint16_t) msgId);
|
||||
}
|
||||
|
||||
client->setWaitedSubTopicId(msgId, topicId, topicFilter.type);
|
||||
client->setWaitedSubTopicId(msgId, topicId, &topicFilter);
|
||||
|
||||
if (!client->isAggregated())
|
||||
{
|
||||
@@ -120,10 +128,8 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
|
||||
RespExit:
|
||||
MQTTSNPacket* sSuback = new MQTTSNPacket();
|
||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_NOT_SUPPORTED);
|
||||
RespExit: MQTTSNPacket* sSuback = new MQTTSNPacket();
|
||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
evsuback = new Event();
|
||||
evsuback->setClientSendEvent(client, sSuback);
|
||||
_gateway->getClientSendQue()->post(evsuback);
|
||||
@@ -146,7 +152,6 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||
{
|
||||
char shortTopic[3];
|
||||
@@ -216,7 +221,8 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPack
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -250,7 +256,8 @@ void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPa
|
||||
|
||||
if (msgId == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,5 +42,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */
|
||||
|
||||
@@ -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_.len = strlen(topicName);
|
||||
|
||||
|
||||
Topic* topic = getTopicByName(&topicId);
|
||||
|
||||
if (topic)
|
||||
@@ -331,7 +330,6 @@ Topic* Topics::match(const MQTTSN_topicid* topicid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Topics::eraseNormal(void)
|
||||
{
|
||||
Topic* topic = _first;
|
||||
@@ -398,13 +396,22 @@ uint8_t Topics::getCount(void)
|
||||
/*=====================================
|
||||
Class TopicIdMap
|
||||
=====================================*/
|
||||
TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_msgId = msgId;
|
||||
_topicId = topicId;
|
||||
_type = type;
|
||||
_type = topic->type;
|
||||
_wildcard = 0;
|
||||
_next = nullptr;
|
||||
_prev = nullptr;
|
||||
|
||||
if (_type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
if (strchr(topic->data.long_.name, '#') != 0 || strchr(topic->data.long_.name, '+') != 0)
|
||||
{
|
||||
_wildcard = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMapElement::~TopicIdMapElement()
|
||||
@@ -418,9 +425,16 @@ MQTTSN_topicTypes TopicIdMapElement::getTopicType(void)
|
||||
}
|
||||
|
||||
uint16_t TopicIdMapElement::getTopicId(void)
|
||||
{
|
||||
if (_wildcard > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _topicId;
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMap::TopicIdMap()
|
||||
{
|
||||
@@ -456,9 +470,9 @@ TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
if ( _cnt > _maxInflight * 2 || ( topicId == 0 && type != MQTTSN_TOPIC_TYPE_SHORT ) )
|
||||
if (_cnt > _maxInflight * 2 || (topicId == 0 && topic->type != MQTTSN_TOPIC_TYPE_SHORT))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -467,7 +481,7 @@ TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topi
|
||||
erase(msgId);
|
||||
}
|
||||
|
||||
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, type);
|
||||
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, topic);
|
||||
if (elm == 0)
|
||||
{
|
||||
return 0;
|
||||
@@ -534,5 +548,3 @@ void TopicIdMap::clear(void)
|
||||
_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Topic
|
||||
======================================*/
|
||||
@@ -82,7 +81,7 @@ class TopicIdMapElement
|
||||
{
|
||||
friend class TopicIdMap;
|
||||
public:
|
||||
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
~TopicIdMapElement();
|
||||
MQTTSN_topicTypes getTopicType(void);
|
||||
uint16_t getTopicId(void);
|
||||
@@ -90,6 +89,7 @@ public:
|
||||
private:
|
||||
uint16_t _msgId;
|
||||
uint16_t _topicId;
|
||||
uint8_t _wildcard;
|
||||
MQTTSN_topicTypes _type;
|
||||
TopicIdMapElement* _next;
|
||||
TopicIdMapElement* _prev;
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
TopicIdMap();
|
||||
~TopicIdMap();
|
||||
TopicIdMapElement* getElement(uint16_t msgId);
|
||||
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
void erase(uint16_t msgId);
|
||||
void clear(void);
|
||||
private:
|
||||
@@ -112,9 +112,6 @@ private:
|
||||
int _maxInflight;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWTOPIC_H_ */
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#ifndef MQTTSNGWVERSION_H_IN_
|
||||
#define MQTTSNGWVERSION_H_IN_
|
||||
|
||||
#define PAHO_GATEWAY_VERSION "1.4.0"
|
||||
#define PAHO_GATEWAY_VERSION "1.6.0"
|
||||
|
||||
#endif /* MQTTSNGWVERSION_H_IN_ */
|
||||
|
||||
@@ -32,10 +32,10 @@ MQTTSNGW::Gateway* theGateway = nullptr;
|
||||
|
||||
Gateway::Gateway(void)
|
||||
{
|
||||
theGateway = this;
|
||||
theMultiTaskProcess = this;
|
||||
theProcess = this;
|
||||
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
|
||||
_clientList = new ClientList();
|
||||
_clientList = new ClientList(this);
|
||||
_adapterManager = new AdapterManager(this);
|
||||
_topics = new Topics();
|
||||
_stopFlg = false;
|
||||
@@ -95,11 +95,22 @@ Gateway::~Gateway()
|
||||
{
|
||||
free(_params.configName);
|
||||
}
|
||||
|
||||
if (_params.qosMinusClientListName)
|
||||
{
|
||||
free(_params.qosMinusClientListName);
|
||||
}
|
||||
if (_params.rfcommAddr)
|
||||
{
|
||||
free(_params.rfcommAddr);
|
||||
}
|
||||
if (_params.gwCertskey)
|
||||
{
|
||||
free(_params.gwCertskey);
|
||||
}
|
||||
if (_params.gwPrivatekey)
|
||||
{
|
||||
free(_params.gwPrivatekey);
|
||||
}
|
||||
|
||||
if (_adapterManager)
|
||||
{
|
||||
@@ -109,12 +120,10 @@ Gateway::~Gateway()
|
||||
{
|
||||
delete _clientList;
|
||||
}
|
||||
|
||||
if (_topics)
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
// WRITELOG("Gateway is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
int Gateway::getParam(const char* parameter, char* value)
|
||||
@@ -174,6 +183,14 @@ void Gateway::initialize(int argc, char** argv)
|
||||
{
|
||||
_params.rootCAfile = strdup(param);
|
||||
}
|
||||
if (getParam("DtlsCertsKey", param) == 0)
|
||||
{
|
||||
_params.gwCertskey = strdup(param);
|
||||
}
|
||||
if (getParam("DtlsPrivKey", param) == 0)
|
||||
{
|
||||
_params.gwPrivatekey = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("GatewayID", param) == 0)
|
||||
{
|
||||
@@ -182,7 +199,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (_params.gatewayId == 0 || _params.gatewayId > 255)
|
||||
{
|
||||
throw Exception( "Gateway::initialize: invalid Gateway Id");
|
||||
throw Exception("Gateway::initialize: invalid Gateway Id", 0);
|
||||
}
|
||||
|
||||
if (getParam("GatewayName", param) == 0)
|
||||
@@ -192,7 +209,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (_params.gatewayName == 0)
|
||||
{
|
||||
throw Exception( "Gateway::initialize: Gateway Name is missing.");
|
||||
throw Exception("Gateway::initialize: Gateway Name is missing.", 0);
|
||||
}
|
||||
|
||||
_params.mqttVersion = DEFAULT_MQTT_VERSION;
|
||||
@@ -201,7 +218,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
_params.mqttVersion = atoi(param);
|
||||
}
|
||||
|
||||
_params.maxInflightMsgs = DEFAULT_MQTT_VERSION;
|
||||
_params.maxInflightMsgs = MAX_INFLIGHTMESSAGES;
|
||||
if (getParam("MaxInflightMsgs", param) == 0)
|
||||
{
|
||||
_params.maxInflightMsgs = atoi(param);
|
||||
@@ -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 */
|
||||
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||
|
||||
/* Setup ClientList and Predefined topics */
|
||||
_clientList->initialize(_params.aggregatingGw);
|
||||
|
||||
/* SensorNetwork initialize */
|
||||
_sensorNetwork.initialize();
|
||||
}
|
||||
|
||||
void Gateway::run(void)
|
||||
@@ -291,7 +324,6 @@ void Gateway::run(void)
|
||||
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT4);
|
||||
WRITELOG("\n%s %s has been started.\n\n", currentDateTime(), _params.gatewayName);
|
||||
WRITELOG(" ConfigFile : %s\n", _params.configName);
|
||||
|
||||
if (_params.clientListName)
|
||||
@@ -304,18 +336,24 @@ void Gateway::run(void)
|
||||
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
|
||||
}
|
||||
|
||||
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
|
||||
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" RootCApath : %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey : %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey);
|
||||
WRITELOG(" PrivateKey : %s\n", _params.privateKey);
|
||||
WRITELOG(" SensorN/W : %s\n", _sensorNetwork.getDescription());
|
||||
#ifdef DTLS
|
||||
WRITELOG(" DtlsCertsKey: %s\n", _params.gwCertskey);
|
||||
WRITELOG(" DtlsPrivKey : %s\n", _params.gwPrivatekey);
|
||||
#endif
|
||||
WRITELOG(" Max Clients : %d\n\n", _params.maxClients);
|
||||
WRITELOG("%s %s starts running.\n\n", currentDateTime(), _params.gatewayName);
|
||||
|
||||
_stopFlg = false;
|
||||
|
||||
/* Run Tasks until CTRL+C entred */
|
||||
/* Run Tasks until CTRL+C entered or Exception occurred */
|
||||
MultiTaskProcess::run();
|
||||
|
||||
WRITELOG("\n");
|
||||
_stopFlg = true;
|
||||
|
||||
/* stop Tasks */
|
||||
@@ -332,7 +370,7 @@ void Gateway::run(void)
|
||||
/* wait until all Task stop */
|
||||
MultiTaskProcess::waitStop();
|
||||
|
||||
WRITELOG("\n\n%s MQTT-SN Gateway stopped.\n\n", currentDateTime());
|
||||
WRITELOG("\n%s MQTT-SN Gateway stopped.\n\n", currentDateTime());
|
||||
_lightIndicator.allLightOff();
|
||||
}
|
||||
|
||||
@@ -388,17 +426,14 @@ Topics* Gateway::getTopics(void)
|
||||
|
||||
bool Gateway::hasSecureConnection(void)
|
||||
{
|
||||
return ( _params.certKey
|
||||
&& _params.privateKey
|
||||
&& _params.rootCApath
|
||||
&& _params.rootCAfile );
|
||||
return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class EventQue
|
||||
=====================================*/
|
||||
EventQue::EventQue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EventQue::~EventQue()
|
||||
@@ -483,7 +518,6 @@ int EventQue::size()
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Event
|
||||
=====================================*/
|
||||
@@ -586,4 +620,3 @@ MQTTGWPacket* Event::getMQTTGWPacket(void)
|
||||
return _mqttGWPacket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "MQTTSNGWProcess.h"
|
||||
#include "MQTTSNPacket.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTSNGWProcess.h"
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
@@ -28,7 +29,7 @@ namespace MQTTSNGW
|
||||
==================================*/
|
||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway"
|
||||
#define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse"
|
||||
#define PAHO_COPYRIGHT2 " * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)"
|
||||
#define PAHO_COPYRIGHT2 " * (https://github.com/eclipse/paho.mqtt-sn.embedded-c.git)"
|
||||
#define PAHO_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI"
|
||||
#define PAHO_COPYRIGHT4 " ***************************************************************************"
|
||||
/*==========================================================
|
||||
@@ -76,7 +77,8 @@ namespace MQTTSNGW
|
||||
====================================*/
|
||||
class Client;
|
||||
|
||||
enum EventType{
|
||||
enum EventType
|
||||
{
|
||||
Et_NA = 0,
|
||||
EtStop,
|
||||
EtTimeout,
|
||||
@@ -88,8 +90,8 @@ enum EventType{
|
||||
EtSensornetSend
|
||||
};
|
||||
|
||||
|
||||
class Event{
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
Event();
|
||||
~Event();
|
||||
@@ -115,7 +117,6 @@ private:
|
||||
MQTTGWPacket* _mqttGWPacket { nullptr };
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class EventQue
|
||||
====================================*/
|
||||
@@ -136,8 +137,6 @@ private:
|
||||
Semaphore _sem;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class GatewayParams
|
||||
====================================*/
|
||||
@@ -168,17 +167,21 @@ public:
|
||||
bool aggregatingGw { false };
|
||||
bool qosMinus1 { false };
|
||||
bool forwarder { false };
|
||||
int maxClients {0};
|
||||
char* rfcommAddr { nullptr };
|
||||
char* gwCertskey { nullptr };
|
||||
char* gwPrivatekey { nullptr };
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Gateway
|
||||
=====================================*/
|
||||
class AdapterManager;
|
||||
class ClientList;
|
||||
class ClientsPool;
|
||||
|
||||
class Gateway: public MultiTaskProcess{
|
||||
class Gateway: public MultiTaskProcess
|
||||
{
|
||||
public:
|
||||
Gateway(void);
|
||||
~Gateway();
|
||||
@@ -196,24 +199,23 @@ public:
|
||||
int getParam(const char* parameter, char* value);
|
||||
char* getClientListFileName(void);
|
||||
char* getPredefinedTopicFileName(void);
|
||||
|
||||
bool hasSecureConnection(void);
|
||||
Topics* getTopics(void);
|
||||
bool IsStopping(void);
|
||||
void requestSensorNetSubTask(void);
|
||||
|
||||
private:
|
||||
GatewayParams _params;
|
||||
ClientList* _clientList {nullptr};
|
||||
ClientList* _clientList;
|
||||
EventQue _packetEventQue;
|
||||
EventQue _brokerSendQue;
|
||||
EventQue _clientSendQue;
|
||||
LightIndicator _lightIndicator;
|
||||
SensorNetwork _sensorNetwork;
|
||||
AdapterManager* _adapterManager {nullptr};
|
||||
AdapterManager* _adapterManager;
|
||||
Topics* _topics;
|
||||
bool _stopFlg;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGATEWAY_H_ */
|
||||
|
||||
@@ -279,6 +279,7 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
||||
char errmsg[256];
|
||||
char peer_CN[256];
|
||||
bool rc;
|
||||
X509* peer = nullptr;
|
||||
|
||||
_mutex.lock();
|
||||
try
|
||||
@@ -385,7 +386,7 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
||||
throw false;
|
||||
}
|
||||
|
||||
X509* peer = SSL_get_peer_certificate(_ssl);
|
||||
peer = SSL_get_peer_certificate(_ssl);
|
||||
X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);
|
||||
char* pos = peer_CN;
|
||||
if ( *pos == '*')
|
||||
@@ -413,7 +414,12 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
||||
{
|
||||
rc = x;
|
||||
}
|
||||
|
||||
_mutex.unlock();
|
||||
if (peer != nullptr)
|
||||
{
|
||||
X509_free(peer);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -650,3 +656,7 @@ bool Network::isSecure()
|
||||
return _secureFlg;
|
||||
}
|
||||
|
||||
void Network::setSecure(bool secureFlg)
|
||||
{
|
||||
_secureFlg = secureFlg;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
bool isValid(void);
|
||||
bool isSecure(void);
|
||||
int getSock(void);
|
||||
void setSecure(bool secureFlg);
|
||||
|
||||
private:
|
||||
static SSL_CTX* _ctx;
|
||||
|
||||
@@ -79,23 +79,23 @@ Mutex::Mutex(const char* fileName)
|
||||
|
||||
if ((_shmid = shmget(key, sizeof(pthread_mutex_t), IPC_CREAT | 0666)) < 0)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't create a shared memory.");
|
||||
throw Exception("Mutex can't create a shared memory.", -1);
|
||||
}
|
||||
_pmutex = (pthread_mutex_t*) shmat(_shmid, NULL, 0);
|
||||
if (_pmutex == (void*) -1)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't attach shared memory.");
|
||||
throw Exception("Mutex can't attach shared memory.", -1);
|
||||
}
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
|
||||
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't set the process-shared flag");
|
||||
throw Exception("Mutex can't set the process-shared flag", -1);
|
||||
}
|
||||
if (pthread_mutex_init(_pmutex, &attr) != 0)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't initialize.");
|
||||
throw Exception("Mutex can't initialize.", -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,44 +121,37 @@ Mutex::~Mutex(void)
|
||||
|
||||
void Mutex::lock(void)
|
||||
{
|
||||
int rc = 0;
|
||||
if (_pmutex)
|
||||
{
|
||||
pthread_mutex_lock(_pmutex);
|
||||
rc = pthread_mutex_lock(_pmutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pthread_mutex_lock(&_mutex))
|
||||
{
|
||||
throw;
|
||||
rc = pthread_mutex_lock(&_mutex);
|
||||
}
|
||||
} catch (char* errmsg)
|
||||
|
||||
if (rc)
|
||||
{
|
||||
throw Exception( -1, "The same thread can't aquire a mutex twice.");
|
||||
}
|
||||
throw Exception("Mutex lock error", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void Mutex::unlock(void)
|
||||
{
|
||||
|
||||
int rc = 0;
|
||||
if (_pmutex)
|
||||
{
|
||||
pthread_mutex_unlock(_pmutex);
|
||||
rc = pthread_mutex_unlock(_pmutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pthread_mutex_unlock(&_mutex))
|
||||
{
|
||||
throw;
|
||||
rc = pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
} catch (char* errmsg)
|
||||
|
||||
if (rc)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't unlock.");
|
||||
}
|
||||
throw Exception("Mutex lock error", errno);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,12 +218,12 @@ NamedSemaphore::NamedSemaphore(const char* name, unsigned int val)
|
||||
_psem = sem_open(name, O_CREAT, 0666, val);
|
||||
if (_psem == SEM_FAILED)
|
||||
{
|
||||
throw Exception( -1, "Semaphore can't be created.");
|
||||
throw Exception("Semaphore can't be created.", -1);
|
||||
}
|
||||
_name = strdup(name);
|
||||
if (_name == NULL)
|
||||
{
|
||||
throw Exception( -1, "Semaphore can't allocate memories.");
|
||||
throw Exception("Semaphore can't allocate memories.", -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,11 +256,6 @@ void NamedSemaphore::timedwait(uint16_t millsec)
|
||||
/*=========================================
|
||||
Class RingBuffer
|
||||
=========================================*/
|
||||
RingBuffer::RingBuffer()
|
||||
{
|
||||
RingBuffer(MQTTSNGW_KEY_DIRECTORY);
|
||||
}
|
||||
|
||||
RingBuffer::RingBuffer(const char* keyDirectory)
|
||||
{
|
||||
int fp = 0;
|
||||
@@ -303,7 +291,7 @@ RingBuffer::RingBuffer(const char* keyDirectory)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't attach shared memory.");
|
||||
throw Exception("RingBuffer can't attach shared memory.", -1);
|
||||
}
|
||||
}
|
||||
else if ((_shmid = shmget(key, PROCESS_LOG_BUFFER_SIZE, IPC_CREAT | 0666)) != -1)
|
||||
@@ -318,12 +306,12 @@ RingBuffer::RingBuffer(const char* keyDirectory)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't create a shared memory.");
|
||||
throw Exception("RingBuffer can't create a shared memory.", -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't create a shared memory.");
|
||||
throw Exception( "RingBuffer can't create a shared memory.", -1);
|
||||
}
|
||||
|
||||
_pmx = new Mutex(MQTTSNGW_RB_MUTEX_KEY);
|
||||
@@ -495,7 +483,7 @@ void RingBuffer::reset()
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't reset. need to clear shared memory.");
|
||||
throw Exception("RingBuffer can't reset. need to clear shared memory.", -1);
|
||||
}
|
||||
_pmx->unlock();
|
||||
}
|
||||
@@ -506,6 +494,7 @@ void RingBuffer::reset()
|
||||
Thread::Thread()
|
||||
{
|
||||
_threadID = 0;
|
||||
_taskName = nullptr;
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
@@ -539,11 +528,6 @@ int Thread::start(void)
|
||||
return pthread_create(&_threadID, 0, _run, runnable);
|
||||
}
|
||||
|
||||
void Thread::stopProcess(void)
|
||||
{
|
||||
theMultiTaskProcess->threadStopped();
|
||||
}
|
||||
|
||||
void Thread::stop(void)
|
||||
{
|
||||
if ( _threadID )
|
||||
@@ -552,3 +536,13 @@ void Thread::stop(void)
|
||||
_threadID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::setTaskName(const char* name)
|
||||
{
|
||||
_taskName = name;
|
||||
}
|
||||
|
||||
const char* Thread::getTaskName(void)
|
||||
{
|
||||
return _taskName;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace MQTTSNGW
|
||||
#define MQTTSNGW_RB_MUTEX_KEY "rbmutex.key"
|
||||
#define MQTTSNGW_RB_SEMAPHOR_NAME "/rbsemaphor"
|
||||
|
||||
#define RED_HDR "\033[0m\033[0;31m"
|
||||
#define CLR_HDR "\033[0m\033[0;37m"
|
||||
|
||||
/*=====================================
|
||||
Class Mutex
|
||||
====================================*/
|
||||
@@ -92,8 +95,7 @@ private:
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
RingBuffer();
|
||||
RingBuffer(const char* keyDirctory);
|
||||
RingBuffer(const char* keyDirectory = MQTTSNGW_KEY_DIRECTORY);
|
||||
~RingBuffer();
|
||||
void put(char* buffer);
|
||||
int get(char* buffer, int bufferLength);
|
||||
@@ -127,12 +129,14 @@ public: void EXECRUN() \
|
||||
try \
|
||||
{ \
|
||||
run(); \
|
||||
stopProcess(); \
|
||||
} \
|
||||
catch(...) \
|
||||
catch ( Exception &ex ) \
|
||||
{ \
|
||||
throw; \
|
||||
ex.writeMessage(); \
|
||||
WRITELOG("%s%s caught an exception and stopped.%s\n", RED_HDR, getTaskName(), CLR_HDR); \
|
||||
theMultiTaskProcess->abort(); \
|
||||
} \
|
||||
theMultiTaskProcess->threadStopped(); \
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -146,12 +150,15 @@ public:
|
||||
static pthread_t getID();
|
||||
static bool equals(pthread_t*, pthread_t*);
|
||||
virtual void initialize(int argc, char** argv);
|
||||
void stopProcess(void);
|
||||
void waitStop(void);
|
||||
void stop(void);
|
||||
const char* getTaskName(void);
|
||||
void setTaskName(const char* name);
|
||||
void abort(int threadNo);
|
||||
private:
|
||||
static void* _run(void*);
|
||||
pthread_t _threadID;
|
||||
const char* _taskName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
1386
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
1386
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
File diff suppressed because it is too large
Load Diff
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);
|
||||
}
|
||||
|
||||
int SensorNetwork::initialize(void)
|
||||
void SensorNetwork::initialize(void)
|
||||
{
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
uint32_t baudrate = 115200;
|
||||
@@ -135,15 +135,22 @@ int SensorNetwork::initialize(void)
|
||||
theProcess->getParam("DeviceRxLoRaLink", param);
|
||||
_description += ", SerialRx ";
|
||||
_description += param;
|
||||
errno = 0;
|
||||
|
||||
if ( LoRaLink::open(LORALINK_MODEM_RX, param, baudrate) < 0 )
|
||||
{
|
||||
return -1;
|
||||
throw EXCEPTION("Can't open a LoRaLink", errno);
|
||||
}
|
||||
|
||||
theProcess->getParam("DeviceTxLoRaLink", param);
|
||||
_description += ", SerialTx ";
|
||||
_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)
|
||||
@@ -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)
|
||||
{
|
||||
D_NWSTACK("\r\n===> Send: ");
|
||||
D_LRSTACK("\r\n===> Send: ");
|
||||
uint8_t buf[2] = { 0 };
|
||||
uint8_t chks = 0;
|
||||
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);
|
||||
chks += type;
|
||||
|
||||
D_NWSTACK("\r\n Payload: ");
|
||||
D_LRSTACK("\r\n Payload: ");
|
||||
|
||||
for ( uint8_t i = 0; i < pLen; i++ ){
|
||||
send(payload[i]); // Payload
|
||||
@@ -405,21 +412,21 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
|
||||
}
|
||||
|
||||
chks = 0xff - chks;
|
||||
D_NWSTACK(" checksum ");
|
||||
D_LRSTACK(" checksum ");
|
||||
send(chks);
|
||||
D_NWSTACK("\r\n");
|
||||
D_LRSTACK("\r\n");
|
||||
|
||||
/* wait ACK */
|
||||
_sem.timedwait(LORALINK_TIMEOUT_ACK);
|
||||
|
||||
if ( _respCd == LORALINK_NO_FREE_CH )
|
||||
{
|
||||
D_NWSTACK(" Channel isn't free\r\n");
|
||||
D_LRSTACK(" Channel isn't free\r\n");
|
||||
return -1;
|
||||
}
|
||||
else if ( _respCd != LORALINK_ACK )
|
||||
{
|
||||
D_NWSTACK(" Not Acknowleged\r\n");
|
||||
D_LRSTACK(" Not Acknowleged\r\n");
|
||||
return -1;
|
||||
}
|
||||
return (int)pLen;
|
||||
@@ -472,7 +479,7 @@ int LoRaLink::recv(uint8_t* buf)
|
||||
/*
|
||||
if ( *buf == ESCAPE )
|
||||
{
|
||||
D_NWSTACK( " %02x",buf[0] );
|
||||
D_LRSTACK( " %02x",buf[0] );
|
||||
if ( read(fd, buf, 1) == 1 )
|
||||
{
|
||||
*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;
|
||||
}
|
||||
}
|
||||
@@ -545,7 +552,7 @@ bool SerialPort::send(unsigned char b)
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWSTACK( " %02x", b);
|
||||
D_LRSTACK(" %02x", b);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,11 @@ using namespace std;
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
//#define DEBUG_NWSTACK
|
||||
|
||||
#ifdef DEBUG_NWSTACK
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__); fflush(stdout)
|
||||
#ifdef DEBUG_NW
|
||||
#define D_LRSTACK(...) printf(__VA_ARGS__); fflush(stdout)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#define D_LRSTACK(...)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -173,7 +172,7 @@ public:
|
||||
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);
|
||||
int initialize(void);
|
||||
void initialize(void);
|
||||
const char* getDescription(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 <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <poll.h>
|
||||
#include "SensorNetwork.h"
|
||||
#include "MQTTSNGWProcess.h"
|
||||
|
||||
@@ -142,7 +145,7 @@ char* SensorNetAddress::sprint(char* buf)
|
||||
In Gateway version 1.0
|
||||
|
||||
getDescpription( ) is used by Gateway::initialize( )
|
||||
initialize( ) is used by ClientSendTask::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( )
|
||||
@@ -170,16 +173,15 @@ int SensorNetwork::broadcast(const uint8_t* payload, uint16_t payloadLength)
|
||||
|
||||
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
|
||||
* "UDP Multicast 225.1.1.1:1883 Gateway Port 10000".
|
||||
* 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];
|
||||
uint16_t multicastPortNo = 0;
|
||||
@@ -213,18 +215,22 @@ int SensorNetwork::initialize(void)
|
||||
if (theProcess->getParam("GatewayPortNo", param) == 0)
|
||||
{
|
||||
unicastPortNo = atoi(param);
|
||||
_description += " Gateway Port ";
|
||||
_description += ", Gateway Port:";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastTTL", param) == 0)
|
||||
{
|
||||
ttl = atoi(param);
|
||||
_description += " TTL: ";
|
||||
_description += ", TTL:";
|
||||
_description += param;
|
||||
}
|
||||
|
||||
/* Prepare UDP sockets */
|
||||
return UDPPort::open(ip.c_str(), multicastPortNo, unicastPortNo, ttl);
|
||||
/* setup UDP sockets */
|
||||
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)
|
||||
@@ -234,7 +240,7 @@ const char* SensorNetwork::getDescription(void)
|
||||
|
||||
SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||
{
|
||||
return &_clientAddr;
|
||||
return &_senderAddr;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
@@ -244,8 +250,7 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||
UDPPort::UDPPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdUnicast = -1;
|
||||
_sockfdMulticast = -1;
|
||||
memset(_pollFds, 0, sizeof(_pollFds));
|
||||
}
|
||||
|
||||
UDPPort::~UDPPort()
|
||||
@@ -255,22 +260,20 @@ UDPPort::~UDPPort()
|
||||
|
||||
void UDPPort::close(void)
|
||||
{
|
||||
if (_sockfdUnicast > 0)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
::close(_sockfdUnicast);
|
||||
_sockfdUnicast = -1;
|
||||
if (_pollFds[i].fd > 0)
|
||||
{
|
||||
::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;
|
||||
const int reuse = 1;
|
||||
int optval = 0;
|
||||
int sock = 0;
|
||||
|
||||
if (uniPortNo == 0 || multiPortNo == 0)
|
||||
{
|
||||
@@ -278,90 +281,87 @@ int UDPPort::open(const char* ipAddress, uint16_t multiPortNo, uint16_t uniPortN
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ip = inet_addr(ipAddress);
|
||||
_grpAddr.setAddress(ip, htons(multiPortNo));
|
||||
_clientAddr.setAddress(ip, htons(uniPortNo));
|
||||
_ttl = ttl;
|
||||
|
||||
/*------ Create unicast socket --------*/
|
||||
_sockfdUnicast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdUnicast < 0)
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
D_NWSTACK("error can't create unicast socket in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
sockaddr_in addru;
|
||||
addru.sin_family = AF_INET;
|
||||
addru.sin_port = htons(uniPortNo);
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(_sockfdUnicast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
|
||||
{
|
||||
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
_pollFds[0].fd = sock;
|
||||
_pollFds[0].events = POLLIN;
|
||||
|
||||
/*------ Create Multicast socket --------*/
|
||||
_sockfdMulticast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMulticast < 0)
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
D_NWSTACK("error can't create multicast socket in UDPPort::open\n");
|
||||
close();
|
||||
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;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _grpAddr.getPortNo();
|
||||
addrm.sin_port = htons(multiPortNo);
|
||||
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");
|
||||
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");
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ip_mreq mreq;
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _grpAddr.getIpAddress();
|
||||
_multicastAddr.setAddress(inet_addr(multicastIP), htons(multiPortNo));
|
||||
_pollFds[1].fd = sock;
|
||||
_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;
|
||||
}
|
||||
|
||||
@@ -372,52 +372,33 @@ int UDPPort::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr
|
||||
dest.sin_port = addr->getPortNo();
|
||||
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)
|
||||
{
|
||||
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);
|
||||
return status;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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(_sockfdUnicast, buf, len, 0, addr);
|
||||
rc = recvfrom(_pollFds[0].fd, 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;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user