This branch for debugging DTLS #90, #150, #195, #227

The purpose of this branch is to share work in process.
Change sellect() of UDP to poll()
Rewrite UDP6 for DTLS6

Known bug: can't reconnect DTLS

Signed-off-by: tomoaki <tomoaki@tomy-tech.com>
This commit is contained in:
tomoaki
2021-06-11 10:54:20 +09:00
parent 83c30d662f
commit 5fb4312aad
52 changed files with 5101 additions and 1790 deletions

207
.cproject
View File

@@ -1,354 +1,191 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> <?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings"> <storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227"> <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug"> <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/> <externalSettings/>
<extensions> <extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions> </extensions>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug"> <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath=""> <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/> <builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" 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.archiver.base.602829827" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.default" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> <option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="" valueType="string"/>
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNClient/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNClient/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}&quot;"/>
</option> </option>
<option id="gnu.cpp.compiler.option.debugging.sanitleak.778932189" name="Sanitize memory leak (-fsanitize=leak)" superClass="gnu.cpp.compiler.option.debugging.sanitleak" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.cpp.compiler.option.debugging.sanitpointers.435146187" name="Sanitize pointer operations (-fsanitize=pointer-compare -fsanitize=pointer-subtract)" superClass="gnu.cpp.compiler.option.debugging.sanitpointers" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.cpp.compiler.option.debugging.sanitaddress.501742254" name="Sanitize address (-fsanitize=address)" superClass="gnu.cpp.compiler.option.debugging.sanitaddress" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.1354093543" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="DTLS"/>
<listOptionValue builtIn="false" value="DEBUG_NW"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/> <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/> <option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.798283837" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="OPENSSL_API_COMPAT=30000"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1870583388" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType> </inputType>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="pthread"/>
<listOptionValue builtIn="false" value="ssl"/> <listOptionValue builtIn="false" value="ssl"/>
<listOptionValue builtIn="false" value="crypto"/> <listOptionValue builtIn="false" value="crypto"/>
<listOptionValue builtIn="false" value="pthread"/>
<listOptionValue builtIn="false" value="bluetooth"/> <listOptionValue builtIn="false" value="bluetooth"/>
</option> </option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.170974409" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.170974409" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="/usr/local/lib"/> <listOptionValue builtIn="false" value="/usr/local/lib"/>
</option> </option>
<option id="gnu.cpp.link.option.shared.1648098307" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType> </inputType>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool> </tool>
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry excluding="src/linux/udp6|src/linux/udp|GatewayTester|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="src/linux/rfcomm|src/linux/udp6|src/tests|GatewayTester|src/linux/xbee|GatewayTester/samples|src/mainLogmonitor.cpp|src/linux/loralink|GatewayTester/src" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway"/>
<entry excluding="samples|src" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway/GatewayTester"/>
<entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/> <entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration> </cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339"> <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release"> <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/> <externalSettings/>
<extensions> <extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions> </extensions>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.exe.release">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath=""> <folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> <builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> <tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/> <option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/> <option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/> <option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/>
</option> </option>
<option id="gnu.cpp.compiler.option.dialect.std.216116103" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/> <option id="gnu.cpp.compiler.option.dialect.std.216116103" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release"> <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1094525037" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/> <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1094525037" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="gnu.c.compiler.exe.release.option.debugging.level.162341902" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/> <option id="gnu.c.compiler.exe.release.option.debugging.level.162341902" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.456127079" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.456127079" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"> <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType> </inputType>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1623573602" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"> <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1623573602" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.68366124" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.68366124" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/> <listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/> <listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/> <listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
</option> </option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1879517971" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1879517971" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="/usr/local/lib"/> <listOptionValue builtIn="false" value="/usr/local/lib"/>
</option> </option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType> </inputType>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"> <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> <inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool> </tool>
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry excluding="MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/ClientPub|MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNGateway|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/GatewayTester/samples/ClientSub|MQTTSNClient|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src|MQTTSNPacket/src|MQTTSNGateway/GatewayTester|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/> <entry excluding="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="linux/udp6|linux/udp" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
<entry excluding="linux/rfcomm|linux/ble" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration> </cconfiguration>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/> <project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2"> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug"/> <configuration configurationName="Debug"/>
<configuration configurationName="Release"> <configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/> <resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="scannerConfiguration"> <storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079"> <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727"> <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=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536"> <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=""/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
</storageModule> </storageModule>
</cproject> </cproject>

View File

@@ -1,48 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project> <project>
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug"> <configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176156747064280842" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-152611677936340298" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/> <language-scope id="org.eclipse.cdt.core.g++"/>
</provider> </provider>
</extension> </extension>
</configuration> </configuration>
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release"> <configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176157551606184930" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-152611677936340298" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/> <language-scope id="org.eclipse.cdt.core.g++"/>
</provider> </provider>
</extension> </extension>
</configuration> </configuration>
</project> </project>

View File

@@ -20,7 +20,10 @@ CPPSRCS := \
$(SUBDIR)/LGwProxy.cpp \ $(SUBDIR)/LGwProxy.cpp \
$(SUBDIR)/LMqttsnClient.cpp \ $(SUBDIR)/LMqttsnClient.cpp \
$(SUBDIR)/LNetworkUdp.cpp \ $(SUBDIR)/LNetworkUdp.cpp \
$(SUBDIR)/LNetworkUdp6.cpp \
$(SUBDIR)/LNetworkRfcomm.cpp \ $(SUBDIR)/LNetworkRfcomm.cpp \
$(SUBDIR)/LNetworkDtls.cpp \
$(SUBDIR)/LNetworkDtls6.cpp \
$(SUBDIR)/LPublishManager.cpp \ $(SUBDIR)/LPublishManager.cpp \
$(SUBDIR)/LRegisterManager.cpp \ $(SUBDIR)/LRegisterManager.cpp \
$(SUBDIR)/LSubscribeManager.cpp \ $(SUBDIR)/LSubscribeManager.cpp \
@@ -38,11 +41,13 @@ CXX := g++
CPPFLAGS += CPPFLAGS +=
INCLUDES += -I$(SUBDIR) INCLUDES += -I$(SUBDIR)
DEFS := DEF1 :=
LIBS += DEF2 :=
DEFS := -D$(SN) $(DEF1) $(DEF2)
LIBS += -L/usr/local/lib -L/usr/local/opt/openssl
LDFLAGS := LDFLAGS :=
CXXFLAGS := -Wall -O3 -std=c++11 CXXFLAGS := -Wall -O3 -std=c++11
LDADD := -lbluetooth LDADD := -lbluetooth -lssl -lcrypto
OUTDIR := Build OUTDIR := Build
PROG := $(OUTDIR)/$(PROGTEST) PROG := $(OUTDIR)/$(PROGTEST)
@@ -76,23 +81,23 @@ $(PROGQOS): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/$(QOSAPPL).o
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp $(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $< $(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp $(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $< $(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp $(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $< $(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp $(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $< $(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $< $(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
clean: clean:
rm -rf $(OUTDIR) rm -rf $(OUTDIR)

View File

@@ -2,27 +2,6 @@
**sample/mainTest.cpp** is a Test sample coading. **sample/mainTest.cpp** is a Test sample coading.
Each test is described as one function. test1(), test2()... Each test is described as one function. test1(), test2()...
``` ```
/*------------------------------------------------------
* Test functions
*
* you can use 4 commands in Test functions
*
* 1) PUBLISH(const char* topicName,
* uint8_t* payload,
* uint16_t len,
* uint8_t qos,
* bool retain = false);
*
* 2) SUBSCRIBE(const char* topicName,
* TopicCallback onPublish,
* uint8_t qos);
*
* 3) UNSUBSCRIBE(const char* topicName);
*
* 4) DISCONNECT(uint16_t sleepInSecs);
*
*------------------------------------------------------*/
void test1(void) void test1(void)
{ {
char payload[300]; char payload[300];
@@ -36,8 +15,34 @@ void test2(void)
uint8_t qos = 1; uint8_t qos = 1;
SUBSCRIBE(topic2, on_publish02, qos); SUBSCRIBE(topic2, on_publish02, qos);
} }
*---------------------------------------------------------------------------
*
* 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 one by one. **TEST_LIST** is a test senario. Test functions are executed interactively.
``` ```
/*------------------------------------------------------ /*------------------------------------------------------
* A List of Test Tasks * A List of Test Tasks
@@ -54,80 +59,59 @@ TEST_LIST = {// e.g. TEST( Label, Test),
}; };
``` ```
## step1. Define a sensor network
**UDP** or **Bluetooth** is available as a sensor network. **UDP**, **DTLS**, **UDP6**, **DTLS6** or **Bluetooth** is available as a sensor network.
Uncomment a line \#define UDP or RFCOMM in LMqttsnClientApp.h file. ```
/*------------------------------------------------------
* 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
};
``` ```
/*======================================
* Program mode Flag
======================================*/
//#define CLIENT_MODE
#define UDP
//#define RFCOMM
```
## step2. Build ## How to Build
``` ```
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c copy codes from the github.
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester $ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
$ make $ ./build.sh [udp | udp6 | dtls | dtls6 | rfcomm]
$ make install
$ make clean
``` ```
MQTT-SNGatewayTester program is copied into ../../../ directory.
## **step3. Execute Gateway Tester.** ## Execute Gateway Tester
``` ```
$ cd ../../.. $ ./Build/MQTT-SNGatewayTester
$ ./MQTT-SNGatewayTester
*************************************************************************** ***************************************************************************
* MQTT-SN Gateway Tester * MQTT-SN Gateway Tester DTLS
* Part of Project Paho in Eclipse * Part of Project Paho in Eclipse
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/) * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
* *
* Author : Tomoaki YAMAGUCHI * Author : Tomoaki YAMAGUCHI
* Version: 0.0.0 * Version: 2.0.0
*************************************************************************** ***************************************************************************
Attempting to Connect the Broker..... Attempting to Connect the Broker.....
Execute "Step0:Connect" ? ( y/n ) :
sendto 225.1.1.1 :1883 03 01 00
recved 192.168.11.5 :1883 03 01 00
sendto 225.1.1.1 :1883 03 01 00
recved 192.168.11.5 :1883 03 01 00
recved 192.168.11.17 :10000 03 02 01
sendto 192.168.11.17 :10000 13 04 0c 01 03 84 47 61 74 65 77 61 79 54 65 73 74 65 72
recved 192.168.11.17 :10000 02 06
sendto 192.168.11.17 :10000 0c 07 00 77 69 6c 6c 54 6f 70 69 63
recved 192.168.11.17 :10000 02 08
sendto 192.168.11.17 :10000 0d 09 77 69 6c 6c 4d 65 73 73 61 67 65
recved 192.168.11.17 :10000 03 05 00
Connected to the Broker
Attempting OnConnect.....
sendto 192.168.11.17 :10000 13 12 20 00 01 74 79 34 74 77 2f 63 6c 69 65 6e 74 49 64
recved 192.168.11.17 :10000 08 13 20 00 01 00 01 00
SUBSCRIBE complete. ty4tw/clientId
OnConnect complete
Test Ready.
Execute Publish topic1 Test ? ( Y/N ) :
``` ```

View File

@@ -0,0 +1,22 @@
#!/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
make SN=RFCOMM $DEF1 $DEF2
elif [ $1 == "dtls" ] ; then
make SN=DTLS $DEF1 $DEF2
elif [ $1 == "dtls6" ] ; then
make SN=DTLS6 $DEF1 $DEF2
elif [ $1 == "clean" ] ; then
make clean
else
echo "Usage: build.sh [ udp | udp6 | rfcomm | dtls | dtls6] | clean"
fi

View File

@@ -51,17 +51,26 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "ClientPUB", // ClientId
"ClientPUB", // ClientId
{ 225, 1, 1, 1 }, // Multicast group IP { 225, 1, 1, 1 }, // Multicast group IP
1883, // Multicast group Port 1883, // Multicast group Port
20010, // Local PortNo 20010, // Local PortNo
}; };
/*------------------------------------------------------
* UDP6 Configuration (theNetcon)
*------------------------------------------------------*/
UDP6CONF = { "ClientPUB", // ClientId
"ff1e:feed:caca:dead::1", // Multicast group IP
"wlp4s0", // Network Interface
1883, // Multicast group Port
20020, // Local PortNo
};
/*------------------------------------------------------ /*------------------------------------------------------
* RFCOMM Configuration (theNetcon) * RFCOMM Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
RFCOMMCONF = { "GatewayTestClient", // ClientId RFCOMMCONF = { "ClientPUB", // ClientId
"60:57:18:06:8B:72", // GW Address "60:57:18:06:8B:72", // GW Address
1, // Rfcomm channel 1, // Rfcomm channel
}; };

View File

@@ -51,17 +51,26 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "QoS-1_Client01", // ClientId
"QoS-1_Client01", // ClientId
{ 225, 1, 1, 1 }, // Multicast group IP { 225, 1, 1, 1 }, // Multicast group IP
1883, // Multicast group Port 1883, // Multicast group Port
20001, // Local PortNo 20001, // Local PortNo
}; };
/*------------------------------------------------------
* UDP6 Configuration (theNetcon)
*------------------------------------------------------*/
UDP6CONF = { "QoS-1_Client01", // ClientId
"ff1e:feed:caca:dead::1", // Multicast group IP
"wlp4s0", // Network Interface
1883, // Multicast group Port
20020, // Local PortNo
};
/*------------------------------------------------------ /*------------------------------------------------------
* RFCOMM Configuration (theNetcon) * RFCOMM Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
RFCOMMCONF = { "GatewayTestClient", // ClientId RFCOMMCONF = { "QoS-1_Client01", // ClientId
"60:57:18:06:8B:72", // GW Address "60:57:18:06:8B:72", // GW Address
1, // Rfcomm channel 1, // Rfcomm channel
}; };

View File

@@ -51,17 +51,26 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "ClientSUB", // ClientId
"ClientSUB", // ClientId
{ 225, 1, 1, 1 }, // Multicast group IP { 225, 1, 1, 1 }, // Multicast group IP
1883, // Multicast group Port 1883, // Multicast group Port
20011, // Local PortNo 20011, // Local PortNo
}; };
/*------------------------------------------------------
* UDP6 Configuration (theNetcon)
*------------------------------------------------------*/
UDP6CONF = { "ClientSUB", // ClientId
"ff1e:feed:caca:dead::1", // Multicast group IP
"wlp4s0", // Network Interface
1883, // Multicast group Port
20020, // Local PortNo
};
/*------------------------------------------------------ /*------------------------------------------------------
* RFCOMM Configuration (theNetcon) * RFCOMM Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
RFCOMMCONF = { "GatewayTestClient", // ClientId RFCOMMCONF = { "ClientSUB", // ClientId
"60:57:18:06:8B:72", // GW Address "60:57:18:06:8B:72", // GW Address
1, // Rfcomm channel 1, // Rfcomm channel
}; };

View File

@@ -49,7 +49,7 @@ extern LMqttsnClient* theClient;
extern LScreen* theScreen; extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP,DTLS Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { "GatewayTestClient", // ClientId UDPCONF = { "GatewayTestClient", // ClientId
{ 225, 1, 1, 1 }, // Multicast group IP { 225, 1, 1, 1 }, // Multicast group IP
@@ -57,6 +57,16 @@ UDPCONF = { "GatewayTestClient", // ClientId
20020, // Local PortNo 20020, // Local PortNo
}; };
/*------------------------------------------------------
* UDP6, DTLS6 Configuration (theNetcon)
*------------------------------------------------------*/
UDP6CONF = { "GatewayTestClient", // ClientId
"ff1e:feed:caca:dead::1", // Multicast group IP
"wlp4s0", // Network Interface
1883, // Multicast group Port
20020, // Local PortNo
};
/*------------------------------------------------------ /*------------------------------------------------------
* RFCOMM Configuration (theNetcon) * RFCOMM Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/

View File

@@ -200,6 +200,15 @@ int LGwProxy::getConnectResponce(void)
{ {
_network.setGwAddress(); _network.setGwAddress();
_gwId = _mqttsnMsg[1]; _gwId = _mqttsnMsg[1];
#if defined(DTLS) || defined(DTLS6)
if (_network.sslConnect() < 0)
{
DISPLAY(
"\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce Can't connect the Gateway via SSL.\033[0m\033[0;37m\n\n");
return 0;
}
#endif
_status = GW_CONNECTING; _status = GW_CONNECTING;
} }
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ) else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)

View File

@@ -23,7 +23,10 @@
#include "LMqttsnClientApp.h" #include "LMqttsnClientApp.h"
#include "LNetworkUdp.h" #include "LNetworkUdp.h"
#include "LNetworkUdp6.h"
#include "LNetworkRfcomm.h" #include "LNetworkRfcomm.h"
#include "LNetworkDtls.h"
#include "LNetworkDtls6.h"
#include "LRegisterManager.h" #include "LRegisterManager.h"
#include "LTimer.h" #include "LTimer.h"
#include "LTopicTable.h" #include "LTopicTable.h"
@@ -43,6 +46,7 @@ using namespace std;
#define GW_SLEEPING 10 #define GW_SLEEPING 10
#define GW_DISCONNECTED 11 #define GW_DISCONNECTED 11
#define GW_SLEPT 12 #define GW_SLEPT 12
#define SSL_CONNECTING 13
#define GW_WAIT_PINGRESP 1 #define GW_WAIT_PINGRESP 1

View File

@@ -53,8 +53,14 @@ int main(int argc, char** argv)
printf("\n%s", PAHO_COPYRIGHT0); printf("\n%s", PAHO_COPYRIGHT0);
#if defined(UDP) #if defined(UDP)
printf(" UDP\n"); printf(" UDP\n");
#elif defined(UDP6)
printf(" UDP6\n");
#elif defined(RFCOMM) #elif defined(RFCOMM)
printf(" RFCOMM\n"); printf(" RFCOMM\n");
#elif defined(DTLS)
printf(" DTLS\n");
#elif defined(DTLS6)
printf(" DTLS6\n");
#else #else
printf("\n"); printf("\n");
#endif #endif

View File

@@ -17,17 +17,16 @@
#ifndef MQTTSNCLIENTAPP_H_ #ifndef MQTTSNCLIENTAPP_H_
#define MQTTSNCLIENTAPP_H_ #define MQTTSNCLIENTAPP_H_
/*======================================
* Debug Flag
======================================*/
//#define DEBUG_NW
//#define DEBUG_MQTTSN
/*====================================== /*======================================
* Program mode Flag * Program mode Flag
======================================*/ ======================================*/
//#define CLIENT_MODE //#define CLIENT_MODE
#define UDP
//#define RFCOMM
/*======================================
* Debug Flag
======================================*/
#define DEBUG_NW
//#define DEBUG_MQTTSN
/**************************************** /****************************************
MQTT-SN Parameters MQTT-SN Parameters
@@ -75,6 +74,15 @@ struct LUdpConfig
uint16_t uPortNo; uint16_t uPortNo;
}; };
struct LUdp6Config
{
const char* clientId;
const char* ipAddress;
const char *interface;
uint16_t gPortNo;
uint16_t uPortNo;
};
struct LRfcommConfig struct LRfcommConfig
{ {
const char* clientId; const char* clientId;
@@ -97,20 +105,40 @@ typedef enum
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig #define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig
#define MQTTSNCONF LMqttsnConfig theMqcon #define MQTTSNCONF LMqttsnConfig theMqcon
#ifdef UDP #if defined(UDP)
#define NETWORK_CONFIG UdpConfig theNetworkConfig
#define UDPCONF LUdpConfig theNetcon #define UDPCONF LUdpConfig theNetcon
#define RFCOMMCONF LRfcommConfig theConf #define UDP6CONF LUdp6Config theU6Conf
#define RFCOMMCONF LRfcommConfig theRfConf
#define SENSORNET_CONFIG_t LUdpConfig #define SENSORNET_CONFIG_t LUdpConfig
#else
#ifdef RFCOMM #elif defined(UDP6)
#define NETWORK_CONFIG BleConfig theNetworkConfig #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 RFCOMMCONF LRfcommConfig theNetcon
#define UDPCONF LUdpConfig theConf #define UDPCONF LUdpConfig theUConf
#define UDP6CONF LUdp6Config theU6Conf
#define SENSORNET_CONFIG_t LRfcommConfig #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 #endif
#error "UDP and RFCOMM are not defined in LMqttsnClientApp.h"
#endif
#define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__) #define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
#define PUBLISH(...) theClient->publish(__VA_ARGS__) #define PUBLISH(...) theClient->publish(__VA_ARGS__)

View File

@@ -0,0 +1,537 @@
/**************************************************************************************
* 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");
DISPLAY("\033[0m\033[0;31m\nerror 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");
DISPLAY("\033[0m\033[0;31m\nerror 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);
D_NWLOG("errno == %d in LDtlsPort::unicast\n", 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 = 0;
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)
{
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 || SO_REUSEPORT, &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)
{
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));
int stat = SSL_connect(_ssl);
if (stat != 1)
{
rc = -1;
D_NWLOG("SSL fail to connect\n");
}
else
{
D_NWLOG("SSL connected\n");
}
return rc;
}
int verify_cert(int ok, X509_STORE_CTX *ctx)
{
return 1;
}
#endif

View File

@@ -0,0 +1,117 @@
/**************************************************************************************
* 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
#define STAT_UNICAST 1
#define STAT_MULTICAST 2
#define STAT_SSL 3
using namespace std;
namespace linuxAsyncClient {
/*========================================
Class LDtlsPort
=======================================*/
class LDtlsPort
{
friend class LNetwork;
public:
LDtlsPort();
virtual ~LDtlsPort();
bool open(LUdpConfig* config);
int unicast(const uint8_t *buf, uint32_t length);
int multicast( const uint8_t* buf, uint32_t length );
int recv(uint8_t* buf, uint16_t len, bool nonblock, uint32_t* ipaddress, in_port_t* port );
int recv(uint8_t* buf, int flags);
bool checkRecvBuf();
bool isUnicast();
SSL* getSSL(void);
int sslConnect(uint32_t ipAddress, in_port_t port);
private:
void close();
int recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipaddress, in_port_t* port );
int _sockfdMcast;
int _sockfdSsl;
SSL_CTX *_ctx;
SSL *_ssl;
in_port_t _gPortNo;
in_port_t _uPortNo;
uint32_t _gIpAddr;
uint8_t _castStat;
bool _disconReq;
};
#define NO_ERROR 0
#define PACKET_EXCEEDS_LENGTH 1
/*===========================================
Class Network
============================================*/
class LNetwork: public LDtlsPort
{
public:
LNetwork();
~LNetwork();
int broadcast(const uint8_t* payload, uint16_t payloadLen);
int unicast(const uint8_t* payload, uint16_t payloadLen);
void setGwAddress(void);
void resetGwAddress(void);
bool initialize(LUdpConfig* config);
uint8_t* getMessage(int* len);
bool isBroadcastable();
int sslConnect(void);
private:
void setSleep();
int readApiFrame(void);
uint32_t _gwIpAddress;
uint32_t _ipAddress;
in_port_t _gwPortNo;
in_port_t _portNo;
int _returnCode;
bool _sleepflg;
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
};
} /* end of namespace */
#endif /* DTLS */
#endif /* NETWORKDTLS_H_ */

View File

@@ -0,0 +1,533 @@
/**************************************************************************************
* 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 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)
{
_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;
memset(_pollfds, 0, sizeof(_pollfds));
_sock = 0;
_castStat = 0;
_ifIndex = 0;
_gIpAddrStr = NULL;
}
LDtls6Port::~LDtls6Port()
{
close();
if (_gIpAddrStr)
{
free(_gIpAddrStr);
}
}
void LDtls6Port::close()
{
for (int i = 0; i < 2; i++)
{
if (_pollfds[i].fd > 0)
{
::close(_pollfds[i].fd);
_pollfds[i].fd = 0;
}
}
}
bool LDtls6Port::open(LUdp6Config *config)
{
int optval = 1;
int sock = 0;
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 */
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 = 0;
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;
}
bool LDtls6Port::isUnicast()
{
return (_sock == _pollfds[0].fd && _sock > 0);
}
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 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 LDtls6Port::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 LDtls6Port::checkRecvBuf()
{
uint8_t buf[2];
int cnt = poll(_pollfds, 2, 2000); // Timeout 2secs
if (cnt == 0)
{
return false;
}
if (_pollfds[0].revents & POLLIN)
{
if (::recv(_pollfds[0].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
{
_castStat = STAT_SSL;
_sock = _pollfds[0].fd;
return true;
}
}
else if (_pollfds[1].revents & POLLIN)
{
if (::recv(_pollfds[1].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
{
_castStat = STAT_MULTICAST;
_sock = _pollfds[1].fd;
return true;
}
}
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(_sock, 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, uint16_t portNo)
{
int optval = 1;
int sock = _pollfds[0].fd;
if (_ssl != 0)
{
SSL_free(_ssl);
}
if (sock > 0)
{
::close(sock);
}
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock <= 0)
{
return -1;
}
optval = 1;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR || SO_REUSEPORT, &optval, sizeof(optval));
if (_ifIndex > 0)
{
#ifdef __APPLE__
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &_ifIndex, sizeof(_ifIndex));
#else
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, _interfaceName.c_str(), _interfaceName.size());
#endif
}
struct sockaddr_in6 addr;
addr.sin6_family = AF_INET6;
addr.sin6_port = _uPortNo;
addr.sin6_addr = in6addr_any;
if (::bind(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0)
{
return -1;
}
_pollfds[0].fd = sock;
_pollfds[0].events = POLLIN;
uint16_t listenPort = htons(portNo);
struct sockaddr_in6 dest;
dest.sin6_family = AF_INET6;
dest.sin6_port = htons(listenPort);
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
int rc = 0;
BIO *cbio = BIO_new_dgram(sock, BIO_NOCLOSE);
connect(sock, (sockaddr*) &dest, sizeof(sockaddr_in6));
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest);
_ssl = SSL_new(_ctx);
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
errno = 0;
int stat = SSL_connect(_ssl);
if (stat != 1)
{
rc = -1;
D_NWLOG("SSL fail to connect %s\n",strerror(errno));
}
else
{
D_NWLOG("SSL connected\n");
}
return rc;
}
int verify_cert(int ok, X509_STORE_CTX *ctx)
{
return 1;
}
#endif

View File

@@ -0,0 +1,121 @@
/**************************************************************************************
* 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_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 );
SSL_CTX *_ctx;
SSL *_ssl;
pollfd _pollfds[2];
in_port_t _gPortNo;
in_port_t _uPortNo;
sockaddr_in6 _gIpAddr;
char *_gIpAddrStr;
uint32_t _ifIndex;
string _interfaceName;
uint8_t _castStat;
int _sock;
bool _disconReq;
};
#define NO_ERROR 0
#define PACKET_EXCEEDS_LENGTH 1
/*===========================================
Class Network
============================================*/
class LNetwork: public LDtls6Port
{
public:
LNetwork();
~LNetwork();
int broadcast(const uint8_t* payload, uint16_t payloadLen);
int unicast(const uint8_t* payload, uint16_t payloadLen);
void setGwAddress(void);
void resetGwAddress(void);
bool initialize(LUdp6Config* config);
uint8_t* getMessage(int* len);
bool isBroadcastable();
int sslConnect(void);
private:
void setSleep();
int readApiFrame(void);
in6_addr _gwIpAddress;
in6_addr _ipAddress;
in_port_t _gwPortNo;
in_port_t _portNo;
int _returnCode;
bool _sleepflg;
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
};
} /* end of namespace */
#endif /* DTLS6 */
#endif /* NETWORKDTLS6_H_ */

View File

@@ -13,7 +13,6 @@
* Contributors: * Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/ **************************************************************************************/
#include "LMqttsnClientApp.h"
#ifdef RFCOMM #ifdef RFCOMM
#include <stdio.h> #include <stdio.h>
@@ -29,6 +28,7 @@
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h> #include <bluetooth/rfcomm.h>
#include "LMqttsnClientApp.h"
#include "LNetworkRfcomm.h" #include "LNetworkRfcomm.h"
#include "LTimer.h" #include "LTimer.h"
#include "LScreen.h" #include "LScreen.h"

View File

@@ -17,7 +17,6 @@
#ifndef NETWORKRFCOMM_H_ #ifndef NETWORKRFCOMM_H_
#define NETWORKRFCOMM_H_ #define NETWORKRFCOMM_H_
#include "LMqttsnClientApp.h"
#ifdef RFCOMM #ifdef RFCOMM
#include <sys/time.h> #include <sys/time.h>

View File

@@ -13,7 +13,6 @@
* Contributors: * Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/ **************************************************************************************/
#include "LMqttsnClientApp.h"
#ifdef UDP #ifdef UDP
#include <stdio.h> #include <stdio.h>
@@ -27,11 +26,11 @@
#include <fcntl.h> #include <fcntl.h>
#include <termios.h> #include <termios.h>
#include "LMqttsnClientApp.h"
#include "LNetworkUdp.h" #include "LNetworkUdp.h"
#include "LTimer.h" #include "LTimer.h"
#include "LScreen.h" #include "LScreen.h"
using namespace std; using namespace std;
using namespace linuxAsyncClient; using namespace linuxAsyncClient;
@@ -42,39 +41,51 @@ extern bool theClientMode;
/*========================================= /*=========================================
Class LNetwork Class LNetwork
=========================================*/ =========================================*/
LNetwork::LNetwork(){ LNetwork::LNetwork()
{
_sleepflg = false; _sleepflg = false;
resetGwAddress(); resetGwAddress();
} }
LNetwork::~LNetwork(){ LNetwork::~LNetwork()
{
} }
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen){ int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
{
return LUdpPort::multicast(xmitData, (uint32_t) dataLen); return LUdpPort::multicast(xmitData, (uint32_t) dataLen);
} }
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen){ int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
{
return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo); return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
} }
uint8_t* LNetwork::getMessage(int *len)
uint8_t* LNetwork::getMessage(int* len){ {
*len = 0; *len = 0;
if (checkRecvBuf()){ if (checkRecvBuf())
{
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo); uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
if(_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo)){ if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
{
return 0; return 0;
} }
if(recvLen < 0){ if (recvLen < 0)
{
*len = recvLen; *len = recvLen;
return 0; return 0;
}else{ }
if(_rxDataBuf[0] == 0x01){ else
{
if (_rxDataBuf[0] == 0x01)
{
*len = getUint16(_rxDataBuf + 1); *len = getUint16(_rxDataBuf + 1);
}else{ }
else
{
*len = _rxDataBuf[0]; *len = _rxDataBuf[0];
} }
//if(recvLen != *len){ //if(recvLen != *len){
@@ -88,27 +99,31 @@ uint8_t* LNetwork::getMessage(int* len){
return 0; return 0;
} }
void LNetwork::setGwAddress(void){ void LNetwork::setGwAddress(void)
{
_gwPortNo = _portNo; _gwPortNo = _portNo;
_gwIpAddress = _ipAddress; _gwIpAddress = _ipAddress;
} }
void LNetwork::setFixedGwAddress(void){ void LNetwork::setFixedGwAddress(void)
{
_gwPortNo = LUdpPort::_gPortNo; _gwPortNo = LUdpPort::_gPortNo;
_gwIpAddress = LUdpPort::_gIpAddr; _gwIpAddress = LUdpPort::_gIpAddr;
} }
void LNetwork::resetGwAddress(void){ void LNetwork::resetGwAddress(void)
{
_gwIpAddress = 0; _gwIpAddress = 0;
_gwPortNo = 0; _gwPortNo = 0;
} }
bool LNetwork::initialize(LUdpConfig *config)
bool LNetwork::initialize(LUdpConfig* config){ {
return LUdpPort::open(config); return LUdpPort::open(config);
} }
void LNetwork::setSleep(){ void LNetwork::setSleep()
{
_sleepflg = true; _sleepflg = true;
} }
@@ -132,8 +147,8 @@ LUdpPort::~LUdpPort()
close(); close();
} }
void LUdpPort::close()
void LUdpPort::close(){ {
if (_sockfdMcast > 0) if (_sockfdMcast > 0)
{ {
::close(_sockfdMcast); ::close(_sockfdMcast);
@@ -148,8 +163,7 @@ void LUdpPort::close(){
bool LUdpPort::open(LUdpConfig *config) bool LUdpPort::open(LUdpConfig *config)
{ {
const int reuse = 1; int optval = 0;
char loopch = 1;
uint8_t sav = config->ipAddress[3]; uint8_t sav = config->ipAddress[3];
config->ipAddress[3] = config->ipAddress[0]; config->ipAddress[3] = config->ipAddress[0];
@@ -162,46 +176,46 @@ bool LUdpPort::open(LUdpConfig* config)
_gIpAddr = getUint32((const uint8_t*) config->ipAddress); _gIpAddr = getUint32((const uint8_t*) config->ipAddress);
_uPortNo = htons(config->uPortNo); _uPortNo = htons(config->uPortNo);
if( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){ if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
{
return false; return false;
} }
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0); _sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
if (_sockfdUcast < 0){ if (_sockfdUcast < 0)
{
return false; return false;
} }
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); optval = 1;
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
struct sockaddr_in addr; sockaddr_in addr;
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = _uPortNo; addr.sin_port = _uPortNo;
addr.sin_addr.s_addr = INADDR_ANY; addr.sin_addr.s_addr = INADDR_ANY;
if( ::bind ( _sockfdUcast, (struct sockaddr*)&addr, sizeof(addr)) <0){ if (::bind(_sockfdUcast, (struct sockaddr*) &addr, sizeof(addr)) < 0)
{
return false; return false;
} }
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); _sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (_sockfdMcast < 0){ if (_sockfdMcast < 0)
{
return false; return false;
} }
struct sockaddr_in addrm; sockaddr_in addrm;
addrm.sin_family = AF_INET; addrm.sin_family = AF_INET;
addrm.sin_port = _gPortNo; addrm.sin_port = _gPortNo;
addrm.sin_addr.s_addr = htonl(INADDR_ANY); addrm.sin_addr.s_addr = INADDR_ANY;
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); optval = 1;
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if( ::bind ( _sockfdMcast, (struct sockaddr*)&addrm, sizeof(addrm)) <0){ if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
return false; {
}
if(setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
DISPLAY("\033[0m\033[0;31m\nerror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
close();
return false; return false;
} }
@@ -209,36 +223,47 @@ bool LUdpPort::open(LUdpConfig* config)
mreq.imr_interface.s_addr = INADDR_ANY; mreq.imr_interface.s_addr = INADDR_ANY;
mreq.imr_multiaddr.s_addr = _gIpAddr; mreq.imr_multiaddr.s_addr = _gIpAddr;
if( setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){ if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n"); D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
DISPLAY("\033[0m\033[0;31m\nerror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n"); close();
return false;
}
optval= 1;
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
{
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
close(); close();
return false; return false;
} }
return true; return true;
} }
bool LUdpPort::isUnicast(){ bool LUdpPort::isUnicast()
{
return (_castStat == STAT_UNICAST); return (_castStat == STAT_UNICAST);
} }
int LUdpPort::unicast(const uint8_t *buf, uint32_t length, uint32_t ipAddress, uint16_t port)
int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port ){ {
struct sockaddr_in dest; struct sockaddr_in dest;
dest.sin_family = AF_INET; dest.sin_family = AF_INET;
dest.sin_port = port; dest.sin_port = port;
dest.sin_addr.s_addr = ipAddress; dest.sin_addr.s_addr = ipAddress;
int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest)); int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
if( status < 0){ if (status < 0)
{
D_NWLOG("errno == %d in UdpPort::unicast\n", errno); D_NWLOG("errno == %d in UdpPort::unicast\n", errno);
DISPLAY("errno == %d in UdpPort::unicast\n", errno);
}else{
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
for(uint16_t i = 0; i < length ; i++){
D_NWLOG(" %02x", *(buf + i));
} }
D_NWLOG("\n"); else
{
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
for (uint16_t i = 0; i < length; i++)
{
D_NWLOG(" %02x", *(buf + i));
} D_NWLOG("\n");
if (!theClientMode) if (!theClientMode)
{ {
@@ -246,7 +271,8 @@ int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, u
int pos = 0; int pos = 0;
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port)); sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
pos = strlen(sbuf); pos = strlen(sbuf);
for(uint16_t i = 0; i < length ; i++){ for (uint16_t i = 0; i < length; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i)); sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
{ {
@@ -255,32 +281,32 @@ int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, u
pos += 3; pos += 3;
} }
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n"); sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
} }
} }
return status; return status;
} }
int LUdpPort::multicast(const uint8_t *buf, uint32_t length)
int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){ {
struct sockaddr_in dest; struct sockaddr_in dest;
dest.sin_family = AF_INET; dest.sin_family = AF_INET;
dest.sin_port = _gPortNo; dest.sin_port = _gPortNo;
dest.sin_addr.s_addr = _gIpAddr; dest.sin_addr.s_addr = _gIpAddr;
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest)); int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
if( status < 0){ if (status < 0)
{
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno); D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
return errno; return errno;
}else{ }
else
{
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo)); D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
for(uint16_t i = 0; i < length ; i++){ for (uint16_t i = 0; i < length; i++)
{
D_NWLOG(" %02x", *(buf + i)); D_NWLOG(" %02x", *(buf + i));
DISPLAY(" %02x", *(buf + i)); } D_NWLOG("\n");
}
D_NWLOG("\n");
if (!theClientMode) if (!theClientMode)
{ {
@@ -288,7 +314,8 @@ int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
int pos = 0; int pos = 0;
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo)); sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
pos = strlen(sbuf); pos = strlen(sbuf);
for(uint16_t i = 0; i < length ; i++){ for (uint16_t i = 0; i < length; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i)); sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
{ {
@@ -304,7 +331,8 @@ int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
} }
bool LUdpPort::checkRecvBuf(){ bool LUdpPort::checkRecvBuf()
{
struct timeval timeout; struct timeval timeout;
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 50000; // 50 msec timeout.tv_usec = 50000; // 50 msec
@@ -317,21 +345,29 @@ bool LUdpPort::checkRecvBuf(){
FD_SET(_sockfdUcast, &recvfds); FD_SET(_sockfdUcast, &recvfds);
FD_SET(_sockfdMcast, &recvfds); FD_SET(_sockfdMcast, &recvfds);
if(_sockfdMcast > _sockfdUcast){ if (_sockfdMcast > _sockfdUcast)
{
maxSock = _sockfdMcast; maxSock = _sockfdMcast;
}else{ }
else
{
maxSock = _sockfdUcast; maxSock = _sockfdUcast;
} }
select(maxSock + 1, &recvfds, 0, 0, &timeout); select(maxSock + 1, &recvfds, 0, 0, &timeout);
if(FD_ISSET(_sockfdUcast, &recvfds)){ if (FD_ISSET(_sockfdUcast, &recvfds))
if( ::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){ {
if (::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
{
_castStat = STAT_UNICAST; _castStat = STAT_UNICAST;
return true; return true;
} }
}else if(FD_ISSET(_sockfdMcast, &recvfds)){ }
if( ::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){ else if (FD_ISSET(_sockfdMcast, &recvfds))
{
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
{
_castStat = STAT_MULTICAST; _castStat = STAT_MULTICAST;
return true; return true;
} }
@@ -340,36 +376,47 @@ bool LUdpPort::checkRecvBuf(){
return false; return false;
} }
int LUdpPort::recv(uint8_t* buf, uint16_t len, bool flg, uint32_t* ipAddressPtr, uint16_t* portPtr){ int LUdpPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, uint16_t *portPtr)
{
int flags = flg ? MSG_DONTWAIT : 0; int flags = flg ? MSG_DONTWAIT : 0;
return recvfrom(buf, len, flags, ipAddressPtr, portPtr); return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
} }
int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){ int LUdpPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, uint16_t *portPtr)
{
struct sockaddr_in sender; struct sockaddr_in sender;
int status; int status;
socklen_t addrlen = sizeof(sender); socklen_t addrlen = sizeof(sender);
memset(&sender, 0, addrlen); memset(&sender, 0, addrlen);
if(isUnicast()){ if (isUnicast())
{
D_NWLOG("Ucast ");
status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen); status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
}else if(_castStat == STAT_MULTICAST){ }
else if (_castStat == STAT_MULTICAST)
{
D_NWLOG("Mcast ");
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen); status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
}else{ }
else
{
return 0; return 0;
} }
if (status < 0 && errno != EAGAIN) { if (status < 0 && errno != EAGAIN)
{
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno); D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno); }
}else if(status > 0){ else if (status > 0)
{
*ipAddressPtr = sender.sin_addr.s_addr; *ipAddressPtr = sender.sin_addr.s_addr;
*portPtr = sender.sin_port; *portPtr = sender.sin_port;
D_NWLOG("\nrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr)); D_NWLOG("recved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
for(uint16_t i = 0; i < status ; i++){ for (uint16_t i = 0; i < status; i++)
{
D_NWLOG(" %02x", *(buf + i)); D_NWLOG(" %02x", *(buf + i));
} } D_NWLOG("\n");
D_NWLOG("\n");
if (!theClientMode) if (!theClientMode)
{ {
@@ -377,7 +424,8 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
int pos = 0; int pos = 0;
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), htons(*portPtr)); sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), htons(*portPtr));
pos = strlen(sbuf); pos = strlen(sbuf);
for(uint16_t i = 0; i < status ; i++){ for (uint16_t i = 0; i < status; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i)); sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
{ {
@@ -389,7 +437,9 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
theScreen->display(sbuf); theScreen->display(sbuf);
} }
return status; return status;
}else{ }
else
{
return 0; return 0;
} }
return status; return status;

View File

@@ -17,7 +17,6 @@
#ifndef NETWORKUDP_H_ #ifndef NETWORKUDP_H_
#define NETWORKUDP_H_ #define NETWORKUDP_H_
#include "LMqttsnClientApp.h"
#ifdef UDP #ifdef UDP
#include <sys/time.h> #include <sys/time.h>
@@ -30,7 +29,6 @@
#include <string> #include <string>
#include <arpa/inet.h> #include <arpa/inet.h>
#define SOCKET_MAXHOSTNAME 200 #define SOCKET_MAXHOSTNAME 200
#define SOCKET_MAXCONNECTIONS 5 #define SOCKET_MAXCONNECTIONS 5
#define SOCKET_MAXRECV 500 #define SOCKET_MAXRECV 500

View File

@@ -0,0 +1,433 @@
/**************************************************************************************
* Copyright (c) 2021, Tomoaki Yamaguchi
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/
#ifdef UDP6
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <netinet/in.h>
#include <net/if.h>
#include "LMqttsnClientApp.h"
#include "LNetworkUdp6.h"
#include "LTimer.h"
#include "LScreen.h"
using namespace std;
using namespace linuxAsyncClient;
extern uint16_t getUint16(const uint8_t *pos);
extern uint32_t getUint32(const uint8_t *pos);
extern LScreen *theScreen;
extern bool theClientMode;
/*=========================================
Class LNetwork
=========================================*/
LNetwork::LNetwork()
{
_sleepflg = false;
resetGwAddress();
}
LNetwork::~LNetwork()
{
}
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
{
return LUdp6Port::multicast(xmitData, (uint32_t) dataLen);
}
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
{
return LUdp6Port::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
}
uint8_t* LNetwork::getMessage(int *len)
{
*len = 0;
if (checkRecvBuf())
{
uint16_t recvLen = LUdp6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
int diffAddr = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
if (isUnicast() && diffAddr && (_portNo != _gwPortNo))
{
return 0;
}
if (recvLen < 0)
{
*len = recvLen;
return 0;
}
else
{
if (_rxDataBuf[0] == 0x01)
{
*len = getUint16(_rxDataBuf + 1);
}
else
{
*len = _rxDataBuf[0];
}
return _rxDataBuf;
}
}
return 0;
}
void LNetwork::setGwAddress(void)
{
memcpy(_gwIpAddress.s6_addr, _ipAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
_gwPortNo = _portNo;
}
void LNetwork::resetGwAddress(void)
{
memset(_gwIpAddress.s6_addr, 0, sizeof(_gwIpAddress.s6_addr));
_gwPortNo = 0;
}
bool LNetwork::initialize(LUdp6Config *config)
{
return LUdp6Port::open(config);
}
void LNetwork::setSleep()
{
_sleepflg = true;
}
bool LNetwork::isBroadcastable()
{
return true;
}
/*=========================================
Class udp6Stack
=========================================*/
LUdp6Port::LUdp6Port()
{
_disconReq = false;
memset(_pollfds, 0, sizeof(_pollfds));
_sock = 0;
_interface = NULL;
_gIpAddrStr = NULL;
}
LUdp6Port::~LUdp6Port()
{
close();
if (_gIpAddrStr)
{
free(_gIpAddrStr);
}
if (_interface)
{
free(_interface);
}
}
void LUdp6Port::close()
{
for (int i = 0; i < 2; i++)
{
if (_pollfds[i].fd > 0)
{
::close(_pollfds[i].fd);
_pollfds[i].fd = 0;
}
}
}
bool LUdp6Port::open(LUdp6Config *config)
{
int optval = 1;
int sock = 0;
uint32_t ifindex = 0;
sockaddr_in6 addr6;
_gPortNo = htons(config->gPortNo);
_uPortNo = htons(config->uPortNo);
if (_gPortNo == 0 || _uPortNo == 0)
{
return false;
}
/* create a unicast socket */
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
{
return false;
}
optval = 1;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if (strlen(config->interface) > 0)
{
ifindex = if_nametoindex(config->interface);
#ifdef __APPLE__
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
#else
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, config->interface, strlen(config->interface));
#endif
}
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = _uPortNo;
addr6.sin6_addr = in6addr_any;
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
{
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
return false;
}
_pollfds[0].fd = sock;
_pollfds[0].events = POLLIN;
/* create a multicast socket */
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
{
return false;
}
optval = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = _gPortNo;
addr6.sin6_addr = in6addr_any;
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
{
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
return false;
}
ipv6_mreq addrm;
addrm.ipv6mr_interface = ifindex;
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
{
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
close();
return false;
}
optval = 1;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
{
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
close();
return false;
}
_pollfds[1].fd = sock;
_pollfds[1].events = POLLIN;
_gIpAddr.sin6_family = AF_INET6;
_gIpAddr.sin6_port = _gPortNo;
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
_gIpAddrStr = strdup(config->ipAddress);
return true;
}
int LUdp6Port::unicast(const uint8_t *buf, uint32_t length, in6_addr ipAddress, uint16_t port)
{
struct sockaddr_in6 dest;
dest.sin6_family = AF_INET6;
dest.sin6_port = port;
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
char addrBuf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
D_NWLOG("unicast to [%s]:%-6u", addrBuf, htons(port));
int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
if (status < 0)
{
D_NWLOG(" errno = %d %s in Udp6Port::unicast\n", errno, strerror(errno));
}
else
{
for (uint16_t i = 0; i < length; i++)
{
D_NWLOG(" %02x", *(buf + i));
}
D_NWLOG("\n");
if (!theClientMode)
{
char sbuf[SCREEN_BUFF_SIZE];
int pos = 0;
sprintf(sbuf, "\033[0;34municast to [%s[:%-6u", addrBuf, htons(port));
pos = strlen(sbuf);
for (uint16_t i = 0; i < length; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
{
break;
}
pos += 3;
}
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
}
}
return status;
}
int LUdp6Port::multicast(const uint8_t *buf, uint32_t length)
{
char sbuf[SCREEN_BUFF_SIZE];
char portStr[8];
sprintf(portStr, "%d", ntohs(_gPortNo));
int status = ::sendto(_pollfds[1].fd, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
if (status < 0)
{
D_NWLOG("multicast to [%s]:%-6s ", _gIpAddrStr, portStr);
D_NWLOG("\033[0m\033[0;31merrno = %d %s in Udp6Port::multicast\033[0m\033[0;37m\n", errno, strerror(errno));
return errno;
}
else
{
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
for (uint16_t i = 0; i < length; i++)
{
D_NWLOG(" %02x", *(buf + i));
}
D_NWLOG("\n");
if (!theClientMode)
{
memset(sbuf, 0, SCREEN_BUFF_SIZE);
int pos = 0;
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
pos = strlen(sbuf);
for (uint16_t i = 0; i < length; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
{
break;
}
pos += 3;
}
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
}
return status;
}
}
bool LUdp6Port::checkRecvBuf()
{
uint8_t buf[2];
int cnt = poll(_pollfds, 2, 2000); // Timeout 2secs
if (cnt == 0)
{
return false;
}
for (int i = 0; i < 2; i++)
{
if (_pollfds[i].revents & POLLIN)
{
if (::recv(_pollfds[i].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
{
_sock = _pollfds[i].fd;
return true;
}
}
}
return false;
}
int LUdp6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, uint16_t *portPtr)
{
int flags = flg ? MSG_DONTWAIT : 0;
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
}
int LUdp6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, uint16_t *portPtr)
{
struct sockaddr_in6 sender;
int status;
socklen_t addrlen = sizeof(sender);
memset(&sender, 0, addrlen);
char addrBuf[INET6_ADDRSTRLEN];
status = ::recvfrom(_sock, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
if (status < 0 && errno != EAGAIN)
{
D_NWLOG("\033[0m\033[0;31merrno == %d in Udp6Port::recvfrom \033[0m\033[0;37m\n", errno);
}
if (status > 0)
{
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
*portPtr = sender.sin6_port;
if (!theClientMode)
{
char sbuf[SCREEN_BUFF_SIZE];
int pos = 0;
sprintf(sbuf, "\033[0;34mrecv from [%s]:%-6u", addrBuf, htons(*portPtr));
pos = strlen(sbuf);
for (uint16_t i = 0; i < status; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
{
break;
}
pos += 3;
}
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
}
return status;
}
else
{
return 0;
}
return status;
}
bool LUdp6Port::isUnicast(void)
{
return (_sock == _pollfds[0].fd && _sock > 0);
}
#endif /* UDP6 */

View File

@@ -0,0 +1,113 @@
/**************************************************************************************
* Copyright (c) 2021, Tomoaki Yamaguchi
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/
#ifndef NETWORKUDP6_H_
#define NETWORKUDP6_H_
#ifdef UDP6
#include <sys/time.h>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>
#include <poll.h>
#define SOCKET_MAXHOSTNAME 200
#define SOCKET_MAXCONNECTIONS 5
#define SOCKET_MAXRECV 500
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
#define STAT_UNICAST 1
#define STAT_MULTICAST 2
using namespace std;
namespace linuxAsyncClient {
/*========================================
Class LUpd6Port
=======================================*/
class LUdp6Port
{
friend class LNetwork;
public:
LUdp6Port();
virtual ~LUdp6Port();
bool open(LUdp6Config *config);
int unicast(const uint8_t *buf, uint32_t length, in6_addr ipaddress, uint16_t port);
int multicast( const uint8_t* buf, uint32_t length );
int recv(uint8_t *buf, uint16_t len, bool nonblock, in6_addr *ipaddress, uint16_t *port);
int recv(uint8_t* buf, int flags);
bool checkRecvBuf();
bool isUnicast();
private:
void close();
int recvfrom(uint8_t *buf, uint16_t len, int flags, in6_addr *ipaddress, uint16_t *port);
pollfd _pollfds[2];
uint16_t _gPortNo;
uint16_t _uPortNo;
sockaddr_in6 _gIpAddr;
char *_gIpAddrStr;
char* _interface;
int _sock;
bool _disconReq;
};
#define NO_ERROR 0
#define PACKET_EXCEEDS_LENGTH 1
/*===========================================
Class Network
============================================*/
class LNetwork: public LUdp6Port
{
public:
LNetwork();
~LNetwork();
int broadcast(const uint8_t* payload, uint16_t payloadLen);
int unicast(const uint8_t* payload, uint16_t payloadLen);
void setGwAddress(void);
void resetGwAddress(void);
bool initialize(LUdp6Config *config);
uint8_t* getMessage(int* len);
bool isBroadcastable();
private:
void setSleep();
int readApiFrame(void);
in6_addr _gwIpAddress;
in6_addr _ipAddress;
uint16_t _gwPortNo;
uint16_t _portNo;
int _returnCode;
bool _sleepflg;
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
};
} /* end of namespace */
#endif /* UDP6 */
#endif /* NETWORKUDP_H_ */

View File

@@ -1,164 +0,0 @@
PROGNAME := MQTT-SNGateway
APPL := mainGateway
LPROGNAME := MQTT-SNLogmonitor
LAPPL := mainLogmonitor
TESTPROGNAME := testPFW
TESTAPPL := mainTestProcess
CONFIG := gateway.conf
CLIENTS := clients.conf
PREDEFTOPIC := predefinedTopic.conf
SRCDIR := src
SUBDIR := ../MQTTSNPacket/src
OS := linux
SENSORNET := udp
TEST := tests
INSTALL_DIR=../../
CONFIG_DIR=../../
CPPSRCS := \
$(SRCDIR)/MQTTGWConnectionHandler.cpp \
$(SRCDIR)/MQTTGWPacket.cpp \
$(SRCDIR)/MQTTGWPublishHandler.cpp \
$(SRCDIR)/MQTTGWSubscribeHandler.cpp \
$(SRCDIR)/MQTTSNGateway.cpp \
$(SRCDIR)/MQTTSNGWBrokerRecvTask.cpp \
$(SRCDIR)/MQTTSNGWBrokerSendTask.cpp \
$(SRCDIR)/MQTTSNGWClient.cpp \
$(SRCDIR)/MQTTSNGWClientRecvTask.cpp \
$(SRCDIR)/MQTTSNGWClientSendTask.cpp \
$(SRCDIR)/MQTTSNGWConnectionHandler.cpp \
$(SRCDIR)/MQTTSNGWLogmonitor.cpp \
$(SRCDIR)/MQTTSNGWPacket.cpp \
$(SRCDIR)/MQTTSNGWPacketHandleTask.cpp \
$(SRCDIR)/MQTTSNGWProcess.cpp \
$(SRCDIR)/MQTTSNGWPublishHandler.cpp \
$(SRCDIR)/MQTTSNGWSubscribeHandler.cpp \
$(SRCDIR)/MQTTSNGWEncapsulatedPacket.cpp \
$(SRCDIR)/MQTTSNGWForwarder.cpp \
$(SRCDIR)/MQTTSNGWQoSm1Proxy.cpp \
$(SRCDIR)/MQTTSNGWAdapter.cpp \
$(SRCDIR)/MQTTSNGWAggregater.cpp \
$(SRCDIR)/MQTTSNGWClientList.cpp \
$(SRCDIR)/MQTTSNGWTopic.cpp \
$(SRCDIR)/MQTTSNGWAdapterManager.cpp \
$(SRCDIR)/MQTTSNAggregateConnectionHandler.cpp \
$(SRCDIR)/MQTTSNGWMessageIdTable.cpp \
$(SRCDIR)/MQTTSNGWAggregateTopicTable.cpp \
$(SRCDIR)/$(OS)/$(SENSORNET)/SensorNetwork.cpp \
$(SRCDIR)/$(OS)/Timer.cpp \
$(SRCDIR)/$(OS)/Network.cpp \
$(SRCDIR)/$(OS)/Threading.cpp \
$(SRCDIR)/$(TEST)/TestProcess.cpp \
$(SRCDIR)/$(TEST)/TestQue.cpp \
$(SRCDIR)/$(TEST)/TestTree23.cpp \
$(SRCDIR)/$(TEST)/TestTopics.cpp \
$(SRCDIR)/$(TEST)/TestTopicIdMap.cpp \
$(SRCDIR)/$(TEST)/TestTask.cpp
CSRCS := $(SUBDIR)/MQTTSNConnectClient.c \
$(SUBDIR)/MQTTSNConnectServer.c \
$(SUBDIR)/MQTTSNDeserializePublish.c \
$(SUBDIR)/MQTTSNPacket.c \
$(SUBDIR)/MQTTSNSearchClient.c \
$(SUBDIR)/MQTTSNSearchServer.c \
$(SUBDIR)/MQTTSNSerializePublish.c \
$(SUBDIR)/MQTTSNSubscribeClient.c \
$(SUBDIR)/MQTTSNSubscribeServer.c \
$(SUBDIR)/MQTTSNUnsubscribeClient.c \
$(SUBDIR)/MQTTSNUnsubscribeServer.c
CPPFLAGS +=
INCLUDE :=
INCLUDES += $(INCLUDE) -I$(SRCDIR) \
-I$(SRCDIR)/$(OS) \
-I$(SRCDIR)/$(OS)/$(SENSORNET) \
-I$(SUBDIR) \
-I$(SRCDIR)/$(TEST) \
-I/usr/local/opt/openssl/include/
# preprocessor defines
DEFS :=
CXX := g++
LIB :=
LIBS += $(LIB) -L/usr/local/lib -L/usr/local/opt/openssl/lib/
LDFLAGS :=
CXXFLAGS := -Wall -O3 -std=c++11
LDADD := -lpthread -lssl -lcrypto
OUTDIR := Build
PROG := $(OUTDIR)/$(PROGNAME)
LPROG := $(OUTDIR)/$(LPROGNAME)
TPROG := $(OUTDIR)/$(TESTPROGNAME)
OBJS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.o)
OBJS += $(CSRCS:%.c=$(OUTDIR)/%.o)
DEPS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.d)
DEPS += $(CSRCS:%.c=$(OUTDIR)/%.d)
.PHONY: install clean exectest
all: $(PROG) $(LPROG) $(TPROG)
monitor: $(LPROG)
test: $(TPROG) $(LPROG) exectest
-include $(DEPS)
$(PROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(APPL).o
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
$(LPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(LAPPL).o
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
$(TPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/$(APPL).o:$(SRCDIR)/$(APPL).cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o:$(SRCDIR)/$(TEST)/$(TESTAPPL).cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SRCDIR)/$(LAPPL).o:$(SRCDIR)/$(LAPPL).cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.c
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
clean:
rm -rf $(OUTDIR)
install:
cp -pf $(PROG) $(INSTALL_DIR)
cp -pf $(LPROG) $(INSTALL_DIR)
cp -pf $(CONFIG) $(CONFIG_DIR)
cp -pf $(CLIENTS) $(CONFIG_DIR)
cp -pf $(PREDEFTOPIC) $(CONFIG_DIR)
exectest:
./$(OUTDIR)/$(TESTPROGNAME) -f ./gateway.conf

View File

@@ -1,142 +1,211 @@
MQTT-SN Transparent / Aggregating Gateway # MQTT-SN Transparent / Aggregating Gateway
MQTT-SN requires a MQTT-SN Gateway which acts as a protocol converter to convert MQTT-SN messages to MQTT messages.
**MQTT-SN** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP). MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf. This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
### step1. Build the gateway
### **step1. Build the gateway** copy and expand source code then,
```` ```
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway $ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
```
In order to build a gateway, one sensor network argument is required.
```
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm] $ ./build.sh [udp|udp6|xbee|loralink|rfcomm]
```
```` MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin directory.
In order to build a gateway, an argument is required.
MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in the Build directory. ### step2. Execute the Gateway.
### **step2. Execute the Gateway.** ```
````
$ cd bin $ cd bin
$ ./MQTT-SNGateway $ ./MQTT-SNGateway
```` ```
If you get the error message as follows: If you get the error message as follows:
````
RingBuffer can't create a shared memory. RingBuffer can't create a shared memory. ABORT Gateway!!!
ABORT Gateway!!!
````
You have to start using sudo command only once for the first time. You have to start using sudo command only once for the first time.
```` ```
$ sudo ./MQTT-SNGateway $ sudo ./MQTT-SNGateway
```` ```
## Contents of the gateway configuration file
**gateway.conf** is in bin directory. It's contents are follows:
### **How to Change the configuration of the gateway** ```
**gateway.conf** Contents are follows: #**************************************************************************
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
<pre><dev> #
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# and Eclipse Distribution License v1.0 which accompany this distribution.
#
# The Eclipse Public License is available at
# http://www.eclipse.org/legal/epl-v10.html
# and the Eclipse Distribution License is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#***************************************************************************
#
# config file of MQTT-SN Gateway # config file of MQTT-SN Gateway
# #
GatewayID=1
GatewayName=PahoGateway-01
MaxNumberOfClients=30
KeepAlive=60
#LoginID=your_ID
#Password=your_Password
BrokerName=mqtt.eclipseprojects.io BrokerName=mqtt.eclipseprojects.io
BrokerPortNo=1883 BrokerPortNo=1883
BrokerSecurePortNo=8883 BrokerSecurePortNo=8883
```
**GatewayID** is a gateway ID which used by GWINFO message.
**GatewayName** is a name of the gateway.
**MaxNumberOfClients** is a maxmum number of clients. Clients are dynamically allocated.
**KeepAlive** is KeepAlive time in seconds.
**LoginID** is used by CONNECT message.
**Password** is used by CONNECT message.
**BrokerName**is a domain name or IP address of a broker.
**BrokerPortNo** is a broker's port no.
**BrokerSecurePortNo** is a broker's port no of TLS connection.
```
#
# CertsKey for TLS connections to a broker
#
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
#RootCApath=/etc/ssl/certs/
#CertsKey=/path/to/certKey.pem
#PrivateKey=/path/to/privateKey.pem
```
**RootCAfile** is a CA file name.
**RootCApath** is a CA path. **SSL_CTX_load_verify_locations(ctx, CAfile, CApath)** function requires these parameters.
**CertsKey** is a certificate pem file.
**PrivateKey** is a private key pem file.
Clients can connect to the broker via TLS by setting '**Secure Connection**' for each client in the client conf file.
```
# #
# When AggregatingGateway=YES or ClientAuthentication=YES, # When AggregatingGateway=YES or ClientAuthentication=YES,
# All clients must be specified by the ClientList File # All clients must be specified by the ClientList File
# #
ClientAuthentication=NO
AggregatingGateway=NO AggregatingGateway=NO
QoS-1=NO QoS-1=NO
Forwarder=NO Forwarder=NO
MaxNumberOfClients=30;
#ClientsList=/path/to/your_clients.conf
PredefinedTopic=NO PredefinedTopic=NO
#PredefinedTopicList=/path/to/your_predefinedTopic.conf ClientAuthentication=NO
#RootCAfile=/etc/ssl/certs/ca-certificates.crt ClientsList=/path/to/your_clients.conf
#RootCApath=/etc/ssl/certs/ PredefinedTopicList=/path/to/your_predefinedTopic.conf
#CertsFile=/path/to/certKey.pem ```
#PrivateKey=/path/to/privateKey.pem The gateway runs as a aggregating gateway when **AggregatingGateway** is 'YES'.
If **QoS-1** is 'YES, the gateway prepares a proxy for the QoS-1 client. QoS-1 client has a 'QoS-1' parameter in a clients.conf file. For QoS-1 clients, set the QoS-1 parameters in the clients.conf file.
GatewayID=1 If **Forwarder** is 'YES', the gateway prepare a forwarder agent.
GatewayName=PahoGateway-01 If **ClientAuthentication** is 'YES', the client cannot connect unless it is registered in the clients.conf file.
KeepAlive=900 **ClientsList** defines clients and those address so on.
#LoginID=your_ID **PredefinedTopicList** file defines Predefined Topic.
#Password=your_Password
# UDP ```
#==============================
# SensorNetworks parameters
#==============================
#
# UDP | DTLS
#
GatewayPortNo=10000 GatewayPortNo=10000
MulticastIP=225.1.1.1
MulticastPortNo=1883 MulticastPortNo=1883
MulticastIP=225.1.1.1
MulticastTTL=1 MulticastTTL=1
```
**GatewayPortNo** is a unicast port no of the gateway.
**MulticastIP** and **MulticastPortNo** are for GWSEARCH messages. Clients can get the gateway address (Gateway IP address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
Client needs to know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
**MulticastTTL** is a multicast TTL.
```
#
# UDP6 | DTLS6
#
# UDP6 GatewayIPv6PortNo=10000
GatewayUDP6Bind=FFFF:FFFE::1 MulticastIPv6PortNo=1883
GatewayUDP6Port=10000 MulticastIPv6=ff1e:feed:caca:dead::feed:caca:dead
GatewayUDP6Broadcast=FF02::1 MulticastIPv6If=wlp4s0
GatewayUDP6If=wpan0 MulticastHops=1
GatewayUDP6Hops=1 ```
**GatewayIPv6PortNo** is a unicast port no of the gateway.
**MulticastIPv6PortNo** and **MulticastIPv6** are for GWSEARCH messages. Set the Global scope Multicast address so that the Global address is used for sending GWINFO.
Clients can get the gateway address (Gateway IPv6 address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
**MulticastIPv6If** is a multicast interface name.
**MulticastHops** is a multicast hops.
```
#
# DTLS | DTLS6 DTLS CertsKey
#
DtlsCertsKey=/etc/ssl/certs/gateway.pem
DtlsPrivKey=/etc/ssl/private/privkey.pem
```
**DtlsCertsKey** is a certs Key pem file for DTLS connection.
**DtlsPrivKey** is a private key pem file for DTLS connection.
```
#
# XBee # XBee
#
Baudrate=38400 Baudrate=38400
SerialDevice=/dev/ttyUSB0 SerialDevice=/dev/ttyUSB0
ApiMode=2 ApiMode=2
```
**Baudrate** is a baudrate of xbee.
```
#
# LoRaLink # LoRaLink
#
BaudrateLoRaLink=115200 BaudrateLoRaLink=115200
DeviceRxLoRaLink=/dev/ttyLoRaLinkRx DeviceRxLoRaLink=/dev/loralinkRx
DeviceTxLoRaLink=/dev/ttyLoRaLinkTx DeviceTxLoRaLink=/dev/loralinkTx
```
https://github.com/ty4tw/MQTT-SN-LoRa
```
#
# Bluetooth RFCOMM # Bluetooth RFCOMM
#
RFCOMMAddress=60:57:18:06:8B:72.* RFCOMMAddress=60:57:18:06:8B:72.*
```
**RFCOMMAddress** is a bluetooth mac address and channel. channel should be * for the gateway.
```
#
# LOG # LOG
ShearedMemory=NO; #
</dev></pre> ShearedMemory=NO
```
**BrokerName** to specify a domain name of the Broker, and **BrokerPortNo** is a port No of the Broker. **BrokerSecurePortNo** is for TLS connection. ### How to monitor the gateway from a remote terminal.
**MulticastIP** and **MulticastPortNo** is a multicast address for GWSEARCH messages. Gateway is waiting GWSEARCH and when receiving it send GWINFO message via MulticastIP address. Clients can get the gateway address (Gateway IP address and **GatewayPortNo**) from GWINFO message by means of std::recvfrom().
Client should know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
**GatewayId** is used by GWINFO message.
**KeepAlive** is a duration of ADVERTISE message in seconds.
when **AggregatingGateway** or **ClientAuthentication** is **YES**, All clients which connect to the gateway must be declared by a **ClientsList** file.
Format of the file is ClientId and SensorNetwork Address. e.g. IP address and Port No etc, in CSV. more detail see clients.conf.
When **QoS-1** is **YES**, QoS-1 PUBLISH is available. All clients which send QoS-1 PUBLISH must be specified by Client.conf file.
When **PredefinedTopic** is **YES**, **Pre-definedTopicId**s specified by **PredefinedTopicList** are effective. This file defines Pre-definedTopics of the clients. In this file, ClientID,TopicName and TopicID are declared in CSV format.
When **Forwarder** is **YES**, Forwarder Encapsulation Message is available. Connectable Forwarders must be declared by a **ClientsList** file.
**MaxNumberOfClients** Maximum number of clients allocated.
### ** How to monitor the gateway from remote. **
Change gateway.conf as follows: Change gateway.conf as follows:
``` ```
# LOG # LOG
ShearedMemory=YES; ShearedMemory=YES;
```` ```
Restart the gateway with sudo only once to create shared memories. Restart the gateway with sudo only once to create shared memories.
open ssh terminal and execute LogMonitor. open ssh terminal and execute LogMonitor.
``` ```
$ cd bin $ cd bin
$ ./MQTT-SNLogmonitor $ ./MQTT-SNLogmonitor
``` ```
Now you can get the Log on your terminal. Now you can get the Log on your terminal.
## ** Tips ** ##### Tips
Uncomment the line 62, 63 in MQTTSNDefines.h then you can get more precise logs. Use compiler definitions then you can get more precise logs.
**-DDEBUG_NW** is a flag for debug logs of Sensor network.
**-DDEBUG_MQTTSN** is a flag for debug logs of MQTT-SN message haandling.
One or both flags can be specified.
``` ```
/*================================= ./build.sh udp -DDEBUG -DDEBUG_NW
* Log controls
==================================*/
//#define DEBUG // print out log for debug
//#define DEBUG_NWSTACK // print out SensorNetwork log
``` ```

View File

@@ -1,19 +1,42 @@
#!/bin/bash #!/bin/bash
if [ $# -eq 0 ]; then build () {
echo "Usage: build.sh [ udp | udp6 | xbee | loralink | rfcomm ]" echo "Start building MQTT-SN Gateway $1"
else
echo "Start building MQTT-SN Gateway"
SCRIPT_DIR=$(cd $(dirname $0); pwd)
cd $SCRIPT_DIR/.. cd $SCRIPT_DIR/..
rm -rf build.gateway BDIR='build.gateway'
mkdir build.gateway if [ ! -d ./$BDIR ]; then
cd build.gateway mkdir $BDIR
cmake .. -DSENSORNET=$1 fi
cd $BDIR
cmake .. -DSENSORNET=$1 -DDEFS="${2} ${3}"
make MQTTSNPacket make MQTTSNPacket
make MQTT-SNGateway make MQTT-SNGateway
make MQTT-SNLogmonitor make MQTT-SNLogmonitor
cd ../MQTTSNGateway cd ../MQTTSNGateway
cp *.conf ./bin/ 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 fi

View File

@@ -1,5 +1,5 @@
#************************************************************************** #**************************************************************************
# Copyright (c) 2016-2019, Tomoaki Yamaguchi # Copyright (c) 2016-2021, Tomoaki Yamaguchi
# #
# All rights reserved. This program and the accompanying materials # All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0 # are made available under the terms of the Eclipse Public License v1.0
@@ -14,64 +14,96 @@
# config file of MQTT-SN Gateway # config file of MQTT-SN Gateway
# #
GatewayID=1
GatewayName=PahoGateway-01
MaxNumberOfClients=30
KeepAlive=60
#LoginID=your_ID
#Password=your_Password
BrokerName=mqtt.eclipseprojects.io BrokerName=mqtt.eclipseprojects.io
BrokerPortNo=1883 BrokerPortNo=1883
BrokerSecurePortNo=8883 BrokerSecurePortNo=8883
# #
# When AggregatingGateway=YES or ClientAuthentication=YES, # CertsKey for TLS connections to a broker
# All clients must be specified by the ClientList File
# #
ClientAuthentication=NO
AggregatingGateway=NO
QoS-1=NO
Forwarder=NO
MaxNumberOfClients=30;
#ClientsList=/path/to/your_clients.conf
PredefinedTopic=NO
PredefinedTopicList=/path/to/your_predefinedTopic.conf
#RootCAfile=/etc/ssl/certs/ca-certificates.crt #RootCAfile=/etc/ssl/certs/ca-certificates.crt
#RootCApath=/etc/ssl/certs/ #RootCApath=/etc/ssl/certs/
#CertsKey=/path/to/certKey.pem #CertsKey=/path/to/certKey.pem
#PrivateKey=/path/to/privateKey.pem #PrivateKey=/path/to/privateKey.pem
GatewayID=1 #
GatewayName=PahoGateway-01 # When AggregatingGateway=YES or ClientAuthentication=YES,
KeepAlive=900 # All clients must be specified by the ClientList File
#LoginID=your_ID #
#Password=your_Password
AggregatingGateway=NO
QoS-1=NO
Forwarder=NO
PredefinedTopic=NO
ClientAuthentication=NO
ClientsList=/path/to/your_clients.conf
PredefinedTopicList=/path/to/your_predefinedTopic.conf
# UDP #==============================
# SensorNetworks parameters
#==============================
#
# UDP | DTLS
#
GatewayPortNo=10000 GatewayPortNo=10000
MulticastIP=225.1.1.1
MulticastPortNo=1883 MulticastPortNo=1883
MulticastIP=225.1.1.1
MulticastTTL=1 MulticastTTL=1
# UDP6 #
GatewayUDP6Bind=FFFF:FFFE::1 # UDP6 | DTLS6
GatewayUDP6Port=10000 #
GatewayUDP6Broadcast=FF02::1
GatewayUDP6If=wpan0
GatewayUDP6Hops=1
GatewayIPv6PortNo=10000
MulticastIPv6PortNo=1883
MulticastIPv6=ff1e:feed:caca:dead::1
MulticastIPv6If=wlp4s0
MulticastHops=1
#
# DTLS | DTLS6
#
DtlsCertsKey=/etc/ssl/certs/gateway.pem
DtlsPrivKey=/etc/ssl/private/privkey.pem
DtlsSSLPortNo=10001
#
# XBee # XBee
#
Baudrate=38400 Baudrate=38400
SerialDevice=/dev/ttyUSB0 SerialDevice=/dev/ttyUSB0
ApiMode=2 ApiMode=2
#
# LoRaLink # LoRaLink
#
BaudrateLoRaLink=115200 BaudrateLoRaLink=115200
DeviceRxLoRaLink=/dev/loralinkRx DeviceRxLoRaLink=/dev/loralinkRx
DeviceTxLoRaLink=/dev/loralinkTx DeviceTxLoRaLink=/dev/loralinkTx
#
# Bluetooth RFCOMM # Bluetooth RFCOMM
#
RFCOMMAddress=60:57:18:06:8B:72.* RFCOMMAddress=60:57:18:06:8B:72.*
#
# LOG # LOG
ShearedMemory=NO; #
ShearedMemory=NO

View File

@@ -35,6 +35,9 @@ IF(NOT DEFINED SENSORNET)
ENDIF() ENDIF()
MESSAGE(STATUS "SENSORNET: " ${SENSORNET}) MESSAGE(STATUS "SENSORNET: " ${SENSORNET})
ADD_DEFINITIONS(${DEFS})
MESSAGE(STATUS "Definitions: " ${DEFS})
ADD_LIBRARY(mqtt-sngateway_common ADD_LIBRARY(mqtt-sngateway_common
MQTTGWConnectionHandler.cpp MQTTGWConnectionHandler.cpp
MQTTGWPacket.cpp MQTTGWPacket.cpp
@@ -74,8 +77,11 @@ ADD_LIBRARY(mqtt-sngateway_common
${OS}/Threading.h ${OS}/Threading.h
) )
# linux
link_directories("/usr/local/lib") link_directories("/usr/local/lib")
link_directories("/usr/local/opt/openssl/lib")
# Mac
link_directories("/usr/local/opt/openssl")
TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
@@ -84,7 +90,7 @@ TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
${OS} ${OS}
${OS}/${SENSORNET} ${OS}/${SENSORNET}
../../MQTTSNPacket/src ../../MQTTSNPacket/src
/usr/local/opt/openssl/include /usr/local/include
) )
IF(SENSORNET MATCHES "rfcomm") IF(SENSORNET MATCHES "rfcomm")

View File

@@ -17,6 +17,7 @@
#include "MQTTSNGWBrokerRecvTask.h" #include "MQTTSNGWBrokerRecvTask.h"
#include "MQTTSNGWClient.h" #include "MQTTSNGWClient.h"
#include "MQTTSNGWClientList.h" #include "MQTTSNGWClientList.h"
#include "MQTTSNGateway.h"
#include <unistd.h> #include <unistd.h>
using namespace std; using namespace std;

View File

@@ -58,6 +58,7 @@ ClientList::~ClientList()
void ClientList::initialize(bool aggregate) void ClientList::initialize(bool aggregate)
{ {
_maxClients = _gateway->getGWParams()->maxClients;
_clientsPool->allocate(_gateway->getGWParams()->maxClients); _clientsPool->allocate(_gateway->getGWParams()->maxClients);
if (_gateway->getGWParams()->clientAuthentication) if (_gateway->getGWParams()->clientAuthentication)
@@ -380,6 +381,7 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
{ {
client->setQoSm1(); client->setQoSm1();
} }
client->getNetwork()->setSecure(secure);
_mutex.lock(); _mutex.lock();
@@ -402,16 +404,18 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate) Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
{ {
Client *client = nullptr;
if (topicId == 0) if (topicId == 0)
{ {
WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str()); WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
return nullptr; goto exit;
} }
if (strcmp(clientId->cstring, common_topic) == 0) if (strcmp(clientId->cstring, common_topic) == 0)
{ {
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId); _gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
return nullptr; goto exit;
} }
else else
{ {
@@ -419,48 +423,20 @@ Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicNa
if (_authorize && client == nullptr) if (_authorize && client == nullptr)
{ {
return nullptr; goto exit;
} }
/* anonimous clients */ client = createClient(NULL, clientId, aggregate);
if (_clientCnt > MAX_CLIENTS) if (client)
{ {
return nullptr; // full of clients
}
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();
}
// create Topic & Add it // create Topic & Add it
client->getTopics()->add((const char*) topicName.c_str(), topicId); client->getTopics()->add((const char*) topicName.c_str(), topicId);
client->_hasPredefTopic = true; client->_hasPredefTopic = true;
return client;
} }
} }
exit:
return client;
}
uint16_t ClientList::getClientCount() uint16_t ClientList::getClientCount()
{ {
@@ -517,15 +493,17 @@ void ClientsPool::allocate(int maxClients)
Client* ClientsPool::getClient(void) Client* ClientsPool::getClient(void)
{ {
Client *cl = nullptr;
while (_firstClient != nullptr) while (_firstClient != nullptr)
{ {
Client* cl = _firstClient; cl = _firstClient;
_firstClient = cl->_nextClient; _firstClient = cl->_nextClient;
cl->_nextClient = nullptr; cl->_nextClient = nullptr;
_clientCnt--; _clientCnt--;
return cl; break;
} }
return nullptr; return cl;
} }
void ClientsPool::setClient(Client* client) void ClientsPool::setClient(Client* client)

View File

@@ -83,6 +83,7 @@ private:
Client* _endClient; Client* _endClient;
Mutex _mutex; Mutex _mutex;
uint16_t _clientCnt; uint16_t _clientCnt;
uint16_t _maxClients;
bool _authorize { false }; bool _authorize { false };
}; };

View File

@@ -37,7 +37,7 @@ namespace MQTTSNGW
/*================================= /*=================================
* MQTT-SN Parametrs * MQTT-SN Parametrs
==================================*/ ==================================*/
#define MAX_CLIENTS (100) // Number of Clients can be handled. #define MAX_CLIENTS (100) // Default number of Clients can be handled.
#define MAX_CLIENTID_LENGTH (64) // Max length of clientID #define MAX_CLIENTID_LENGTH (64) // Max length of clientID
#define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages #define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages
#define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size #define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size
@@ -60,13 +60,19 @@ typedef unsigned int uint32_t;
/*================================= /*=================================
* Log controls * Log controls
==================================*/ ==================================*/
//#define DEBUG // print out log for debug //#define DEBUG_MQTTSN // print out log for debug
//#define DEBUG_NWSTACK // print out SensorNetwork log //#define DEBUG_NW // print out SensorNetwork log
#ifdef DEBUG #ifdef DEBUG_MQTTSN
#define DEBUGLOG(...) printf(__VA_ARGS__) #define DEBUGLOG(...) printf(__VA_ARGS__)
#else #else
#define DEBUGLOG(...) #define DEBUGLOG(...)
#endif #endif
#ifdef DEBUG_NW
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
} }
#endif /* MQTTSNGWDEFINES_H_ */ #endif /* MQTTSNGWDEFINES_H_ */

View File

@@ -100,10 +100,6 @@ int MQTTSNPacket::recv(SensorNetwork* network)
{ {
len = desirialize(buf, len); len = desirialize(buf, len);
} }
else
{
len = 0;
}
return len; return len;
} }

View File

@@ -22,6 +22,7 @@
namespace MQTTSNGW namespace MQTTSNGW
{ {
class SensorNetwork;
class MQTTSNPacket class MQTTSNPacket
{ {

View File

@@ -38,6 +38,7 @@ using namespace MQTTSNGW;
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs #define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
char* currentDateTime(void); char* currentDateTime(void);
/*===================================== /*=====================================
Class PacketHandleTask Class PacketHandleTask
=====================================*/ =====================================*/

View File

@@ -16,6 +16,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string>
#include <stdarg.h> #include <stdarg.h>
#include <signal.h> #include <signal.h>
#include <Timer.h> #include <Timer.h>
@@ -156,6 +157,8 @@ int Process::getParam(const char* parameter, char* value)
{ {
char str[MQTTSNGW_PARAM_MAX]; char str[MQTTSNGW_PARAM_MAX];
char param[MQTTSNGW_PARAM_MAX]; char param[MQTTSNGW_PARAM_MAX];
memset(str, 0, sizeof(str));
memset(param, 0, sizeof(param));
FILE *fp; FILE *fp;
int i = 0, j = 0; int i = 0, j = 0;
@@ -166,24 +169,38 @@ int Process::getParam(const char* parameter, char* value)
throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0); throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
} }
int paramlen = strlen(parameter);
while (true) while (true)
{ {
int pos = 0;
int len = 0;
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL) if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
{ {
fclose(fp); fclose(fp);
return -3; return -3;
} }
if (!strncmp(str, parameter, strlen(parameter))) if (str[0] == '#' || str[0] == '\n')
{ {
while (str[i++] != '=') continue;
{
;
} }
while (str[i] != '\n')
len = strlen(str);
for (pos = 0; i < len; pos++)
{ {
param[j++] = str[i++]; if (str[pos] == '=')
{
break;
} }
param[j] = '\0'; }
if (pos == paramlen)
{
if (strncmp(str, parameter, paramlen) == 0)
{
strcpy(param, str + pos + 1);
param[len - pos - 2] = '\0';
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--) for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
; ;
@@ -202,6 +219,7 @@ int Process::getParam(const char* parameter, char* value)
return 0; return 0;
} }
} }
}
fclose(fp); fclose(fp);
return -2; return -2;
} }

View File

@@ -32,9 +32,9 @@ MQTTSNGW::Gateway* theGateway = nullptr;
Gateway::Gateway(void) Gateway::Gateway(void)
{ {
theGateway = this;
theMultiTaskProcess = this; theMultiTaskProcess = this;
theProcess = this; theProcess = this;
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
_clientList = new ClientList(this); _clientList = new ClientList(this);
_adapterManager = new AdapterManager(this); _adapterManager = new AdapterManager(this);
_topics = new Topics(); _topics = new Topics();
@@ -95,15 +95,21 @@ Gateway::~Gateway()
{ {
free(_params.configName); free(_params.configName);
} }
if (_params.qosMinusClientListName) if (_params.qosMinusClientListName)
{ {
free(_params.qosMinusClientListName); free(_params.qosMinusClientListName);
} }
if (_params.rfcommAddr)
if (_params.bleAddress)
{ {
free(_params.bleAddress); free(_params.rfcommAddr);
}
if (_params.gwCertskey)
{
free(_params.gwCertskey);
}
if (_params.gwPrivatekey)
{
free(_params.gwPrivatekey);
} }
if (_adapterManager) if (_adapterManager)
@@ -114,7 +120,6 @@ Gateway::~Gateway()
{ {
delete _clientList; delete _clientList;
} }
if (_topics) if (_topics)
{ {
delete _topics; delete _topics;
@@ -178,6 +183,14 @@ void Gateway::initialize(int argc, char** argv)
{ {
_params.rootCAfile = strdup(param); _params.rootCAfile = strdup(param);
} }
if (getParam("DtlsCertsKey", param) == 0)
{
_params.gwCertskey = strdup(param);
}
if (getParam("DtlsPrivKey", param) == 0)
{
_params.gwPrivatekey = strdup(param);
}
if (getParam("GatewayID", param) == 0) if (getParam("GatewayID", param) == 0)
{ {
@@ -282,11 +295,14 @@ void Gateway::initialize(int argc, char** argv)
_params.maxClients = atoi(param); _params.maxClients = atoi(param);
} }
if (getParam("BleAddress", param) == 0) if (getParam("RFCOMMAddress", param) == 0)
{ {
_params.bleAddress = strdup(param); _params.rfcommAddr = strdup(param);
} }
/* Setup max PacketEventQue size */
_packetEventQue.setMaxSize(_params.maxInflightMsgs * _params.maxClients);
/* Initialize adapters */ /* Initialize adapters */
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1); _adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
@@ -308,7 +324,6 @@ void Gateway::run(void)
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3); WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION); WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
WRITELOG("%s\n", PAHO_COPYRIGHT4); WRITELOG("%s\n", PAHO_COPYRIGHT4);
WRITELOG("\n%s %s has been started.\n\n", currentDateTime(), _params.gatewayName);
WRITELOG(" ConfigFile : %s\n", _params.configName); WRITELOG(" ConfigFile : %s\n", _params.configName);
if (_params.clientListName) if (_params.clientListName)
@@ -321,13 +336,18 @@ void Gateway::run(void)
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName); WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
} }
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure); WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
WRITELOG(" Max number of Clients: %d\n", _params.maxClients);
WRITELOG(" RootCApath : %s\n", _params.rootCApath); WRITELOG(" RootCApath : %s\n", _params.rootCApath);
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile); WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
WRITELOG(" CertKey : %s\n", _params.certKey); WRITELOG(" CertKey : %s\n", _params.certKey);
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey); WRITELOG(" PrivateKey : %s\n", _params.privateKey);
WRITELOG(" SensorN/W : %s\n", _sensorNetwork.getDescription());
#ifdef DTLS
WRITELOG(" DtlsCertsKey: %s\n", _params.gwCertskey);
WRITELOG(" DtlsPrivKey : %s\n", _params.gwPrivatekey);
#endif
WRITELOG(" Max Clients : %d\n\n", _params.maxClients);
WRITELOG("%s %s starts running.\n\n", currentDateTime(), _params.gatewayName);
_stopFlg = false; _stopFlg = false;
@@ -408,12 +428,12 @@ bool Gateway::hasSecureConnection(void)
{ {
return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile); return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
} }
/*===================================== /*=====================================
Class EventQue Class EventQue
=====================================*/ =====================================*/
EventQue::EventQue() EventQue::EventQue()
{ {
} }
EventQue::~EventQue() EventQue::~EventQue()

View File

@@ -168,7 +168,9 @@ public:
bool qosMinus1 { false }; bool qosMinus1 { false };
bool forwarder { false }; bool forwarder { false };
int maxClients {0}; int maxClients {0};
char* bleAddress { nullptr }; char* rfcommAddr { nullptr };
char* gwCertskey { nullptr };
char* gwPrivatekey { nullptr };
}; };
/*===================================== /*=====================================
@@ -197,10 +199,10 @@ public:
int getParam(const char* parameter, char* value); int getParam(const char* parameter, char* value);
char* getClientListFileName(void); char* getClientListFileName(void);
char* getPredefinedTopicFileName(void); char* getPredefinedTopicFileName(void);
bool hasSecureConnection(void); bool hasSecureConnection(void);
Topics* getTopics(void); Topics* getTopics(void);
bool IsStopping(void); bool IsStopping(void);
void requestSensorNetSubTask(void);
private: private:
GatewayParams _params; GatewayParams _params;
@@ -214,7 +216,6 @@ private:
Topics* _topics; Topics* _topics;
bool _stopFlg; bool _stopFlg;
}; };
} }
#endif /* MQTTSNGATEWAY_H_ */ #endif /* MQTTSNGATEWAY_H_ */

View File

@@ -656,3 +656,7 @@ bool Network::isSecure()
return _secureFlg; return _secureFlg;
} }
void Network::setSecure(bool secureFlg)
{
_secureFlg = secureFlg;
}

View File

@@ -80,6 +80,7 @@ public:
bool isValid(void); bool isValid(void);
bool isSecure(void); bool isSecure(void);
int getSock(void); int getSock(void);
void setSecure(bool secureFlg);
private: private:
static SSL_CTX* _ctx; static SSL_CTX* _ctx;

File diff suppressed because it is too large Load Diff

View 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);
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);
int searchClient(SensorNetAddress *addr);
private:
pollfd *_pollfds;
SSL **_ssls;
SensorNetAddress **_clientAddr;
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);
void close();
private:
int openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, uint16_t listenPortNo, uint32_t ttl);
int openV6(string *ipAddress, string *interface, uint16_t multiPortNo, uint16_t uniPortNo, uint16_t listenPortNo,
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_ */

View File

@@ -383,7 +383,7 @@ bool LoRaLink::readApiFrame(LoRaLinkFrame_t* api, LoRaLinkReadParameters_t* para
int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t pLen, SensorNetAddress* addr) int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t pLen, SensorNetAddress* addr)
{ {
D_NWSTACK("\r\n===> Send: "); D_LRSTACK("\r\n===> Send: ");
uint8_t buf[2] = { 0 }; uint8_t buf[2] = { 0 };
uint8_t chks = 0; uint8_t chks = 0;
uint16_t len = pLen + 3; // 3 = DestAddr[1] + PayloadType[1] + Crc[1] uint16_t len = pLen + 3; // 3 = DestAddr[1] + PayloadType[1] + Crc[1]
@@ -404,7 +404,7 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
send(type); send(type);
chks += type; chks += type;
D_NWSTACK("\r\n Payload: "); D_LRSTACK("\r\n Payload: ");
for ( uint8_t i = 0; i < pLen; i++ ){ for ( uint8_t i = 0; i < pLen; i++ ){
send(payload[i]); // Payload send(payload[i]); // Payload
@@ -412,21 +412,21 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
} }
chks = 0xff - chks; chks = 0xff - chks;
D_NWSTACK(" checksum "); D_LRSTACK(" checksum ");
send(chks); send(chks);
D_NWSTACK("\r\n"); D_LRSTACK("\r\n");
/* wait ACK */ /* wait ACK */
_sem.timedwait(LORALINK_TIMEOUT_ACK); _sem.timedwait(LORALINK_TIMEOUT_ACK);
if ( _respCd == LORALINK_NO_FREE_CH ) if ( _respCd == LORALINK_NO_FREE_CH )
{ {
D_NWSTACK(" Channel isn't free\r\n"); D_LRSTACK(" Channel isn't free\r\n");
return -1; return -1;
} }
else if ( _respCd != LORALINK_ACK ) else if ( _respCd != LORALINK_ACK )
{ {
D_NWSTACK(" Not Acknowleged\r\n"); D_LRSTACK(" Not Acknowleged\r\n");
return -1; return -1;
} }
return (int)pLen; return (int)pLen;
@@ -479,7 +479,7 @@ int LoRaLink::recv(uint8_t* buf)
/* /*
if ( *buf == ESCAPE ) if ( *buf == ESCAPE )
{ {
D_NWSTACK( " %02x",buf[0] ); D_LRSTACK( " %02x",buf[0] );
if ( read(fd, buf, 1) == 1 ) if ( read(fd, buf, 1) == 1 )
{ {
*buf = PAD ^ *buf; *buf = PAD ^ *buf;
@@ -491,7 +491,7 @@ int LoRaLink::recv(uint8_t* buf)
} }
*/ */
D_NWSTACK( " %02x",buf[0] ); D_LRSTACK(" %02x", buf[0]);
return 0; return 0;
} }
} }
@@ -552,7 +552,7 @@ bool SerialPort::send(unsigned char b)
} }
else else
{ {
D_NWSTACK( " %02x", b); D_LRSTACK(" %02x", b);
return true; return true;
} }
} }

View File

@@ -25,12 +25,11 @@ using namespace std;
namespace MQTTSNGW namespace MQTTSNGW
{ {
//#define DEBUG_NWSTACK
#ifdef DEBUG_NWSTACK #ifdef DEBUG_NW
#define D_NWSTACK(...) printf(__VA_ARGS__); fflush(stdout) #define D_LRSTACK(...) printf(__VA_ARGS__); fflush(stdout)
#else #else
#define D_NWSTACK(...) #define D_LRSTACK(...)
#endif #endif

View File

@@ -26,12 +26,6 @@ using namespace std;
namespace MQTTSNGW namespace MQTTSNGW
{ {
#ifdef DEBUG_NWSTACK
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
#define MAX_RFCOMM_CH 30 #define MAX_RFCOMM_CH 30
/*=========================================== /*===========================================

View File

@@ -20,10 +20,13 @@
#include <netinet/ip.h> #include <netinet/ip.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <string.h> #include <string.h>
#include <regex> #include <regex>
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#include <poll.h>
#include "SensorNetwork.h" #include "SensorNetwork.h"
#include "MQTTSNGWProcess.h" #include "MQTTSNGWProcess.h"
@@ -212,17 +215,17 @@ void SensorNetwork::initialize(void)
if (theProcess->getParam("GatewayPortNo", param) == 0) if (theProcess->getParam("GatewayPortNo", param) == 0)
{ {
unicastPortNo = atoi(param); unicastPortNo = atoi(param);
_description += " Gateway Port "; _description += ", Gateway Port:";
_description += param; _description += param;
} }
if (theProcess->getParam("MulticastTTL", param) == 0) if (theProcess->getParam("MulticastTTL", param) == 0)
{ {
ttl = atoi(param); ttl = atoi(param);
_description += " TTL: "; _description += ", TTL:";
_description += param; _description += param;
} }
/* Prepare UDP sockets */ /* setup UDP sockets */
errno = 0; errno = 0;
if ( UDPPort::open(ip.c_str(), multicastPortNo, unicastPortNo, ttl) < 0 ) if ( UDPPort::open(ip.c_str(), multicastPortNo, unicastPortNo, ttl) < 0 )
{ {
@@ -247,9 +250,7 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void)
UDPPort::UDPPort() UDPPort::UDPPort()
{ {
_disconReq = false; _disconReq = false;
_sockfdUnicast = -1; memset(_pollFds, 0, sizeof(_pollFds));
_sockfdMulticast = -1;
_ttl = 0;
} }
UDPPort::~UDPPort() UDPPort::~UDPPort()
@@ -259,22 +260,20 @@ UDPPort::~UDPPort()
void UDPPort::close(void) void UDPPort::close(void)
{ {
if (_sockfdUnicast > 0) for (int i = 0; i < 2; i++)
{ {
::close(_sockfdUnicast); if (_pollFds[i].fd > 0)
_sockfdUnicast = -1; {
::close(_pollFds[i].fd);
_pollFds[i].fd = 0;
} }
if (_sockfdMulticast > 0)
{
::close(_sockfdMulticast);
_sockfdMulticast = -1;
} }
} }
int UDPPort::open(const char* ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, unsigned int ttl) int UDPPort::open(const char *multicastIP, uint16_t multiPortNo, uint16_t uniPortNo, unsigned int ttl)
{ {
char loopch = 0; int optval = 0;
const int reuse = 1; int sock = 0;
if (uniPortNo == 0 || multiPortNo == 0) if (uniPortNo == 0 || multiPortNo == 0)
{ {
@@ -282,90 +281,87 @@ int UDPPort::open(const char* ipAddress, uint16_t multiPortNo, uint16_t uniPortN
return -1; return -1;
} }
uint32_t ip = inet_addr(ipAddress);
_multicastAddr.setAddress(ip, htons(multiPortNo));
_unicastAddr.setAddress(ip, htons(uniPortNo));
_ttl = ttl;
/*------ Create unicast socket --------*/ /*------ Create unicast socket --------*/
_sockfdUnicast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sock = socket(AF_INET, SOCK_DGRAM, 0);
if (_sockfdUnicast < 0) if (sock < 0)
{ {
D_NWSTACK("error can't create unicast socket in UDPPort::open\n"); D_NWSTACK("error can't create unicast socket in UDPPort::open\n");
return -1; return -1;
} }
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
sockaddr_in addru; sockaddr_in addru;
addru.sin_family = AF_INET; addru.sin_family = AF_INET;
addru.sin_port = htons(uniPortNo); addru.sin_port = htons(uniPortNo);
addru.sin_addr.s_addr = INADDR_ANY; addru.sin_addr.s_addr = INADDR_ANY;
if (::bind(_sockfdUnicast, (sockaddr*) &addru, sizeof(addru)) < 0) if (::bind(sock, (sockaddr*) &addru, sizeof(addru)) < 0)
{ {
D_NWSTACK("error can't bind unicast socket in UDPPort::open\n"); D_NWSTACK("error can't bind unicast socket in UDPPort::open\n");
return -1; return -1;
} }
if (setsockopt(_sockfdUnicast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
{ _pollFds[0].fd = sock;
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n"); _pollFds[0].events = POLLIN;
close();
return -1;
}
/*------ Create Multicast socket --------*/ /*------ Create Multicast socket --------*/
_sockfdMulticast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sock = socket(AF_INET, SOCK_DGRAM, 0);
if (_sockfdMulticast < 0) if (sock < 0)
{ {
D_NWSTACK("error can't create multicast socket in UDPPort::open\n"); D_NWSTACK("error can't create multicast socket in UDPPort::open\n");
close(); close();
return -1; return -1;
} }
setsockopt(_sockfdMulticast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); optval = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
sockaddr_in addrm; sockaddr_in addrm;
addrm.sin_family = AF_INET; addrm.sin_family = AF_INET;
addrm.sin_port = _multicastAddr.getPortNo(); addrm.sin_port = htons(multiPortNo);
addrm.sin_addr.s_addr = INADDR_ANY; addrm.sin_addr.s_addr = INADDR_ANY;
if (::bind(_sockfdMulticast, (sockaddr*) &addrm, sizeof(addrm)) < 0) if (::bind(sock, (sockaddr*) &addrm, sizeof(addrm)) < 0)
{ {
D_NWSTACK("error can't bind multicast socket in UDPPort::open\n"); D_NWSTACK("error can't bind multicast socket in UDPPort::open\n");
return -1; return -1;
} }
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_interface.s_addr = INADDR_ANY;
mreq.imr_multiaddr.s_addr = inet_addr(multicastIP);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
D_NWSTACK("error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
close();
return -1;
}
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
{
D_NWSTACK("error Multicast IP_MULTICAST_TTL in UDPPort::open\n");
close();
return -1;
}
#ifdef DEBUG_NW
optval = 1;
#else
optval = 0;
#endif
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
{ {
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n"); D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
close(); close();
return -1; return -1;
} }
ip_mreq mreq; _multicastAddr.setAddress(inet_addr(multicastIP), htons(multiPortNo));
mreq.imr_interface.s_addr = INADDR_ANY; _pollFds[1].fd = sock;
mreq.imr_multiaddr.s_addr = _multicastAddr.getIpAddress(); _pollFds[1].events = POLLIN;
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
D_NWSTACK("error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
close();
return -1;
}
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,sizeof(ttl)) < 0)
{
D_NWSTACK("error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
close();
return -1;
}
if (setsockopt(_sockfdUnicast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
D_NWSTACK("error Unicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
close();
return -1;
}
return 0; return 0;
} }
@@ -376,11 +372,12 @@ int UDPPort::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr
dest.sin_port = addr->getPortNo(); dest.sin_port = addr->getPortNo();
dest.sin_addr.s_addr = addr->getIpAddress(); dest.sin_addr.s_addr = addr->getIpAddress();
int status = ::sendto(_sockfdUnicast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest)); int status = ::sendto(_pollFds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
if (status < 0) if (status < 0)
{ {
D_NWSTACK("errno == %d in UDPPort::sendto\n", errno); D_NWSTACK("errno == %d in UDPPort::sendto\n", errno);
} }
D_NWSTACK("sendto %s:%u length = %d\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), status); D_NWSTACK("sendto %s:%u length = %d\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), status);
return status; return status;
} }
@@ -392,36 +389,16 @@ int UDPPort::broadcast(const uint8_t* buf, uint32_t length)
int UDPPort::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr) int UDPPort::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr)
{ {
struct timeval timeout;
fd_set recvfds;
int maxSock = 0;
timeout.tv_sec = 1;
timeout.tv_usec = 0; // 1 sec
FD_ZERO(&recvfds);
FD_SET(_sockfdUnicast, &recvfds);
FD_SET(_sockfdMulticast, &recvfds);
if (_sockfdMulticast > _sockfdUnicast)
{
maxSock = _sockfdMulticast;
}
else
{
maxSock = _sockfdUnicast;
}
int rc = 0; int rc = 0;
if ( select(maxSock + 1, &recvfds, 0, 0, &timeout) > 0 ) poll(_pollFds, 2, 2000); // Timeout 2 seconds
if (_pollFds[0].revents == POLLIN)
{ {
if (FD_ISSET(_sockfdUnicast, &recvfds)) rc = recvfrom(_pollFds[0].fd, buf, len, 0, addr);
{
rc = recvfrom(_sockfdUnicast, buf, len, 0, addr);
} }
else if (FD_ISSET(_sockfdMulticast, &recvfds)) else if (_pollFds[1].revents == POLLIN)
{ {
rc = recvfrom(_sockfdMulticast, buf, len, 0, &_multicastAddr); rc = recvfrom(_pollFds[1].fd, buf, len, 0, addr);
}
} }
return rc; return rc;
} }

View File

@@ -19,18 +19,13 @@
#include "MQTTSNGWDefines.h" #include "MQTTSNGWDefines.h"
#include <string> #include <string>
#include <poll.h>
using namespace std; using namespace std;
namespace MQTTSNGW namespace MQTTSNGW
{ {
#ifdef DEBUG_NWSTACK
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
/*=========================================== /*===========================================
Class SensorNetAddreess Class SensorNetAddreess
============================================*/ ============================================*/
@@ -70,13 +65,9 @@ private:
void setNonBlocking(const bool); void setNonBlocking(const bool);
int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr); int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr);
int _sockfdUnicast; pollfd _pollFds[2];
int _sockfdMulticast;
SensorNetAddress _multicastAddr;
SensorNetAddress _unicastAddr;
bool _disconReq; bool _disconReq;
unsigned int _ttl; SensorNetAddress _multicastAddr;
}; };
/*=========================================== /*===========================================

View File

@@ -1,6 +1,6 @@
/************************************************************************************** /**************************************************************************************
* Copyright (c) 2017, Benjamin Aigner * Copyright (c) 2017, Benjamin Aigner
* Copyright (c) 2016, Tomoaki Yamaguchi (original UDPv4 implementation) * Copyright (c) 2021, Tomoaki Yamaguchi
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@@ -20,8 +20,10 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <net/if.h> #include <net/if.h>
#include <ifaddrs.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <string.h> #include <string.h>
@@ -40,7 +42,6 @@ using namespace MQTTSNGW;
============================================*/ ============================================*/
SensorNetAddress::SensorNetAddress() SensorNetAddress::SensorNetAddress()
{ {
_portNo = 0;
memset((void*) &_IpAddr, 0, sizeof(_IpAddr)); memset((void*) &_IpAddr, 0, sizeof(_IpAddr));
} }
@@ -48,31 +49,29 @@ SensorNetAddress::~SensorNetAddress()
{ {
} }
struct sockaddr_in6 *SensorNetAddress::getIpAddress(void) sockaddr_in6* SensorNetAddress::getIpAddress(void)
{ {
return &_IpAddr; return &_IpAddr;
} }
uint16_t SensorNetAddress::getPortNo(void) uint16_t SensorNetAddress::getPortNo(void)
{ {
return _portNo; return _IpAddr.sin6_port;
} }
void SensorNetAddress::setAddress(struct sockaddr_in6 *IpAddr, uint16_t port) void SensorNetAddress::setAddress(struct sockaddr_in6 *IpAddr)
{ {
memcpy((void*) &_IpAddr, IpAddr, sizeof(_IpAddr)); memcpy((void*) &_IpAddr, IpAddr, sizeof(_IpAddr));
_portNo = port;
} }
/** /**
* convert Text data to SensorNetAddress * convert Text data to SensorNetAddress
* @param data is a IPV6_Address:PortNo format string * @param data is a string [IPV6_Address]:PortNo
* @return success = 0, Invalid format = -1 * @return success = 0, Invalid format = -1
*/ */
int SensorNetAddress::setAddress(string* data) int SensorNetAddress::setAddress(string* data)
{ {
size_t pos = data->find_last_of("]:");
size_t pos = data->find_last_of(":");
if (pos != string::npos) if (pos != string::npos)
{ {
@@ -81,9 +80,9 @@ int SensorNetAddress::setAddress(string* data)
if ((portNo = atoi(port.c_str())) > 0) if ((portNo = atoi(port.c_str())) > 0)
{ {
_portNo = htons(portNo); _IpAddr.sin6_port = htons(portNo);
_IpAddr.sin6_family = AF_INET6;
string ip = data->substr(1,pos - 1); string ip = data->substr(1, pos - 2);
const char *cstr = ip.c_str(); const char *cstr = ip.c_str();
if (inet_pton(AF_INET6, cstr, &(_IpAddr.sin6_addr)) == 1) if (inet_pton(AF_INET6, cstr, &(_IpAddr.sin6_addr)) == 1)
@@ -92,7 +91,6 @@ int SensorNetAddress::setAddress(string* data)
} }
} }
} }
_portNo = 0;
memset((void*) &_IpAddr, 0, sizeof(_IpAddr)); memset((void*) &_IpAddr, 0, sizeof(_IpAddr));
return -1; return -1;
} }
@@ -106,6 +104,7 @@ int SensorNetAddress::setAddress(const char* data)
{ {
if (inet_pton(AF_INET6, data, &(_IpAddr.sin6_addr)) == 1) if (inet_pton(AF_INET6, data, &(_IpAddr.sin6_addr)) == 1)
{ {
_IpAddr.sin6_family = AF_INET6;
return 0; return 0;
} }
else else
@@ -122,24 +121,22 @@ char* SensorNetAddress::getAddress(void)
bool SensorNetAddress::isMatch(SensorNetAddress* addr) bool SensorNetAddress::isMatch(SensorNetAddress* addr)
{ {
return (this->_portNo == addr->_portNo) && \ return (this->_IpAddr.sin6_port == addr->_IpAddr.sin6_port)
(memcmp(this->_IpAddr.sin6_addr.s6_addr, addr->_IpAddr.sin6_addr.s6_addr, sizeof(this->_IpAddr.sin6_addr.s6_addr)) == 0); && (memcmp(this->_IpAddr.sin6_addr.s6_addr, addr->_IpAddr.sin6_addr.s6_addr,
sizeof(this->_IpAddr.sin6_addr.s6_addr)) == 0);
} }
SensorNetAddress& SensorNetAddress::operator =(SensorNetAddress& addr) SensorNetAddress& SensorNetAddress::operator =(SensorNetAddress& addr)
{ {
this->_portNo = addr._portNo; memcpy(&this->_IpAddr, &addr._IpAddr, sizeof(this->_IpAddr));
memcpy(&this->_IpAddr.sin6_addr, &addr._IpAddr.sin6_addr, sizeof(this->_IpAddr.sin6_addr));
return *this; return *this;
} }
char* SensorNetAddress::sprint(char* buf) char* SensorNetAddress::sprint(char* buf)
{ {
char ip[INET6_ADDRSTRLEN]; sprintf(buf, "[%s]:", getAddress());
inet_ntop(AF_INET6, &(_IpAddr.sin6_addr), ip, INET6_ADDRSTRLEN); sprintf(buf + strlen(buf), "%d", ntohs(_IpAddr.sin6_port));
sprintf( buf, "%s:", ip);
sprintf( buf + strlen(buf), "%d", ntohs(_portNo));
return buf; return buf;
} }
@@ -173,45 +170,44 @@ void SensorNetwork::initialize(void)
{ {
char param[MQTTSNGW_PARAM_MAX]; char param[MQTTSNGW_PARAM_MAX];
uint16_t unicastPortNo = 0; uint16_t unicastPortNo = 0;
uint16_t multicastPortNo = 0;
string ip; string ip;
string broadcast; string multicast;
string interface; string interface;
unsigned int hops = 1; uint32_t hops = 1;
if (theProcess->getParam("GatewayUDP6Bind", param) == 0) if (theProcess->getParam("MulticastIPv6", param) == 0)
{ {
ip = param; multicast = param;
_description = "GatewayUDP6Bind: "; _description += "Multicast Address: [";
_description += param; _description += param;
} }
if (theProcess->getParam("GatewayUDP6Port", param) == 0) if (theProcess->getParam("MulticastIPv6PortNo", param) == 0)
{
multicastPortNo = atoi(param);
_description += "]:";
_description += param;
}
if (theProcess->getParam("GatewayIPv6PortNo", param) == 0)
{ {
unicastPortNo = atoi(param); unicastPortNo = atoi(param);
_description += " Gateway Port: "; _description += ", Gateway Port:";
_description += param; _description += param;
} }
if (theProcess->getParam("GatewayUDP6Broadcast", param) == 0) if (theProcess->getParam("MulticastIPv6If", param) == 0)
{
broadcast = param;
_description += " Broadcast Address: ";
_description += param;
}
if (theProcess->getParam("GatewayUDP6If", param) == 0)
{ {
interface = param; interface = param;
_description += " Interface: "; _description += ", Interface: ";
_description += param; _description += param;
} }
if (theProcess->getParam("GatewayUDP6Hops", param) == 0) if (theProcess->getParam("MulticastHops", param) == 0)
{ {
hops = atoi(param); hops = atoi(param);
_description += " Hops: "; _description += ", Hops:";
_description += param; _description += param;
} }
errno = 0; if (UDPPort6::open(unicastPortNo, multicastPortNo, multicast.c_str(), interface.c_str(), hops) < 0)
if ( UDPPort6::open(ip.c_str(), unicastPortNo, broadcast.c_str(), interface.c_str(), hops) < 0 )
{ {
throw EXCEPTION("Can't open a UDP6", errno); throw EXCEPTION("Can't open a UDP6", errno);
} }
@@ -234,8 +230,7 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void)
UDPPort6::UDPPort6() UDPPort6::UDPPort6()
{ {
_disconReq = false; _disconReq = false;
_sockfdUnicast = -1; _hops = 0;
_sockfdMulticast = -1;
} }
UDPPort6::~UDPPort6() UDPPort6::~UDPPort6()
@@ -245,225 +240,187 @@ UDPPort6::~UDPPort6()
void UDPPort6::close(void) void UDPPort6::close(void)
{ {
if (_sockfdUnicast > 0) for (int i = 0; i < 2; i++)
{ {
::close(_sockfdUnicast); if (_pollfds[i].fd > 0)
_sockfdUnicast = -1; {
::close(_pollfds[i].fd);
_pollfds[i].fd = 0;
} }
if (_sockfdMulticast > 0)
{
::close(_sockfdMulticast);
_sockfdMulticast = -1;
} }
} }
int UDPPort6::open(const char* ipAddress, uint16_t uniPortNo, const char* broadcastAddr, const char* interfaceName, unsigned int hops) int UDPPort6::open(uint16_t uniPortNo, uint16_t multiPortNo, const char *multicastAddr, const char *interfaceName,
uint32_t hops)
{ {
struct addrinfo hints, *res; int optval = 0;
int errnu; int sock = 0;
const int reuse = 1; sockaddr_in6 addr6;
uint32_t ifindex = 0;
if (uniPortNo == 0) errno = 0;
if (uniPortNo == 0 || multiPortNo == 0)
{ {
WRITELOG("error portNo undefined in UDPPort::open\n"); D_NWSTACK("error portNo undefined in UDPPort6::open\n");
return -1; return -1;
} }
// Create a unicast socket
memset(&hints, 0, sizeof hints); sock = socket(AF_INET6, SOCK_DGRAM, 0);
hints.ai_family = AF_INET6; // use IPv6 if (sock < 0)
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; //use local IF address
getaddrinfo(NULL, std::to_string(uniPortNo).c_str(), &hints, &res);
_sockfdMulticast = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(_sockfdMulticast <0)
{ {
WRITELOG("UDP6::open - multicast: %s",strerror(_sockfdMulticast)); D_NWSTACK("UDP6::open - unicast socket: %s", strerror(errno));
return errno; return -1;
} }
//select the interface _pollfds[0].fd = sock;
unsigned int ifindex; _pollfds[0].events = POLLIN;
ifindex = if_nametoindex(interfaceName);
errnu = setsockopt(_sockfdMulticast, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex,sizeof(ifindex)); optval = 1;
if(errnu <0) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &optval, sizeof(optval));
{
WRITELOG("UDP6::open - limit IF: %s",strerror(errnu)); optval = 1;
return errnu; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*) &optval, sizeof(optval)) < 0)
} {
D_NWSTACK("\033[0m\033[0;31m unicast socket error %s IPV6_V6ONLY\033[0m\033[0;37m\n", strerror(errno));
strcpy(_interfaceName,interfaceName); close();
return -1;
//restrict the socket to IPv6 only }
int on = 1;
errnu = setsockopt(_sockfdMulticast, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)); if (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops)) < 0)
if(errnu <0) {
{ D_NWSTACK("\033[0m\033[0;31m error %s IPV6_UNICAST_HOPS\033[0m\033[0;37m\n", strerror(errno));
WRITELOG("UDP6::open - limit IPv6: %s",strerror(errnu)); close();
return errnu;
}
errnu = setsockopt(_sockfdMulticast, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,sizeof(hops));
if(errnu <0)
{
WRITELOG("UDP6::open - limit HOPS: %s",strerror(errnu));
return errnu;
}
_uniPortNo = uniPortNo;
_hops = hops;
freeaddrinfo(res);
//init the structs for getaddrinfo
//according to: https://beej.us/guide/bgnet/output/html/multipage/
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET6; // use IPv6, whichever
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
//no specific address, bind to available ones...
getaddrinfo(NULL, std::to_string(uniPortNo).c_str(), &hints, &res);
//create the socket
_sockfdUnicast = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (_sockfdUnicast < 0)
{
WRITELOG("UDP6::open - unicast socket: %s",strerror(_sockfdUnicast));
return -1; return -1;
} }
//if given, set a given device name to bind to
if (strlen(interfaceName) > 0) if (strlen(interfaceName) > 0)
{ {
ifindex = if_nametoindex(interfaceName);
#ifdef __APPLE__ #ifdef __APPLE__
int idx = if_nametoindex(interfaceName); setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
setsockopt(_sockfdUnicast, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx));
#else #else
//socket option: bind to a given interface name setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interfaceName, strlen(interfaceName));
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_BINDTODEVICE, interfaceName, strlen(interfaceName));
#endif #endif
} }
//socket option: reuse address memset(&addr6, 0, sizeof(addr6));
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(uniPortNo);
addr6.sin6_addr = in6addr_any;
//finally: bind... if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
errnu = ::bind(_sockfdUnicast, res->ai_addr, res->ai_addrlen);
if (errnu < 0)
{ {
WRITELOG("error can't bind unicast socket in UDPPort::open: %s\n",strerror(errnu)); D_NWSTACK("error can't bind unicast socket in UDPPort6::open: %s\n", strerror(errno));
close();
return -1; return -1;
} }
//if given, set a broadcast address; otherwise it will be ::
if(strlen(broadcastAddr) > 0) // create a MULTICAST socket
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
{ {
_grpAddr.setAddress(broadcastAddr); D_NWSTACK("UDP6::open - multicast: %s", strerror(errno));
} else { close();
_grpAddr.setAddress("::"); return -1;
} }
//everything went fine... _pollfds[1].fd = sock;
freeaddrinfo(res); _pollfds[1].events = POLLIN;
optval = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &optval, sizeof(optval)) < 0)
{
D_NWSTACK("\033[0m\033[0;31m multicast socket error %s SO_REUSEADDR\033[0m\033[0;37m\n", strerror(errno));
close();
return -1;
}
optval = 1;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*) &optval, sizeof(optval)) < 0)
{
D_NWSTACK("\033[0m\033[0;31m multicast socket error %s IPV6_V6ONLY\033[0m\033[0;37m\n", strerror(errno));
close();
return -1;
}
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(multiPortNo);
addr6.sin6_addr = in6addr_any;
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
{
close();
D_NWSTACK("error can't bind multicast socket in UDPPort6::open: %s\n", strerror(errno));
return -1;
}
ipv6_mreq addrm;
addrm.ipv6mr_interface = ifindex;
inet_pton(AF_INET6, multicastAddr, &addrm.ipv6mr_multiaddr);
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
{
D_NWSTACK("\033[0m\033[0;31m error %d IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", errno);
close();
return false;
}
#ifdef DEBUG_NW
optval = 1;
#else
optval = 0;
#endif
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char*) &optval, sizeof(optval)) < 0)
{
D_NWSTACK("\033[0m\033[0;31m error %s IPV6_MULTICAST_LOOP\033[0m\033[0;37m\n", strerror(errno));
close();
return false;
}
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0)
{
D_NWSTACK("\033[0m\033[0;31m error %s IPV6_MULTICAST_HOPS\033[0m\033[0;37m\n", strerror(errno));
close();
return -1;
}
memcpy(&addr6.sin6_addr, &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
_grpAddr.setAddress(&addr6);
return 0; return 0;
} }
int UDPPort6::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr) int UDPPort6::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr)
{ {
char destStr[INET6_ADDRSTRLEN+10]; sockaddr_in6 dest;
struct addrinfo hints, *res; memset(&dest, 0, sizeof(dest));
memset(&hints, 0, sizeof hints); dest.sin6_family = AF_INET6;
hints.ai_family = AF_INET6; // use IPv6 dest.sin6_port = addr->getPortNo();
hints.ai_socktype = SOCK_DGRAM; memcpy(dest.sin6_addr.s6_addr, (const void*) &addr->getIpAddress()->sin6_addr, sizeof(in6_addr));
int err = 0; #ifdef DEBUG_NW
int port = 0; char addrBuf[INET6_ADDRSTRLEN];
string portStr; addr->sprint(addrBuf);
if(addr->getPortNo() != 0) D_NWSTACK("sendto %s\n", addrBuf);
{ #endif
port = htons(addr->getPortNo());
portStr = to_string(port);
} else {
port = _uniPortNo;
portStr = to_string(port);
}
errno = 0; int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
if(strlen(_interfaceName) != 0)
{
strcpy(destStr, addr->getAddress());
strcat(destStr,"%");
strcat(destStr,_interfaceName);
if(IN6_IS_ADDR_LINKLOCAL(&addr->getIpAddress()->sin6_addr))
{
err = getaddrinfo(destStr, portStr.c_str(), &hints, &res);
}
else
{
err = getaddrinfo(addr->getAddress(), portStr.c_str(), &hints, &res);
}
} else {
strcpy(destStr, addr->getAddress());
err = getaddrinfo(addr->getAddress(), portStr.c_str(), &hints, &res);
}
if ( err != 0)
{
WRITELOG("UDP6::broadcast - getaddrinfo: %s",strerror(errno));
return err;
}
int status = ::sendto(_sockfdUnicast, buf, length, 0, res->ai_addr, res->ai_addrlen);
if (status < 0) if (status < 0)
{ {
WRITELOG("errno in UDPPort::unicast(sendto): %d, %s\n",status,strerror(errno)); D_NWSTACK("%s in UDPPor6t::sendto\n", strerror(errno));
} }
return status; return status;
} }
int UDPPort6::broadcast(const uint8_t* buf, uint32_t length) int UDPPort6::broadcast(const uint8_t* buf, uint32_t length)
{ {
struct addrinfo hint,*info; int err = unicast(buf, length, &_grpAddr);
int err;
memset( &hint, 0, sizeof( hint ) );
hint.ai_family = AF_INET6; if (err < 0)
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = 0;
errno = 0;
if(strlen(_interfaceName) != 0)
{ {
char destStr[80]; D_NWSTACK("UDP6::broadcast - sendto: %s", strerror(errno));
strcpy(destStr, _grpAddr.getAddress());
strcat(destStr,"%");
strcat(destStr,_interfaceName);
if(IN6_IS_ADDR_MC_NODELOCAL(&_grpAddr.getIpAddress()->sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&_grpAddr.getIpAddress()->sin6_addr))
{
err = getaddrinfo(destStr, std::to_string(_uniPortNo).c_str(), &hint, &info );
}
else
{
err = getaddrinfo(_grpAddr.getAddress(), std::to_string(_uniPortNo).c_str(), &hint, &info );
}
} else {
err = getaddrinfo(_grpAddr.getAddress(), std::to_string(_uniPortNo).c_str(), &hint, &info );
}
if( err != 0 ) {
WRITELOG("UDP6::broadcast - getaddrinfo: %s",strerror(errno));
return err;
}
err = sendto(_sockfdMulticast, buf, length, 0, info->ai_addr, info->ai_addrlen );
if(err < 0 ) {
WRITELOG("UDP6::broadcast - sendto: %s",strerror(errno));
return err; return err;
} }
@@ -472,25 +429,22 @@ int UDPPort6::broadcast(const uint8_t* buf, uint32_t length)
int UDPPort6::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr) int UDPPort6::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr)
{ {
struct timeval timeout; int rc = poll(_pollfds, 2, 2000); // Timeout 2secs
fd_set recvfds; if (rc == 0)
timeout.tv_sec = 1;
timeout.tv_usec = 0; // 1 sec
FD_ZERO(&recvfds);
FD_SET(_sockfdUnicast, &recvfds);
int rc = 0;
if ( select(_sockfdUnicast + 1, &recvfds, 0, 0, &timeout) > 0 )
{ {
if (FD_ISSET(_sockfdUnicast, &recvfds))
{
rc = recvfrom(_sockfdUnicast, buf, len, 0, addr);
}
}
return rc; return rc;
} }
for (int i = 0; i < 2; i++)
{
if (_pollfds[i].revents & POLLIN)
{
return recvfrom(_pollfds[i].fd, buf, len, 0, addr);
}
}
return 0;
}
int UDPPort6::recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr) int UDPPort6::recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr)
{ {
sockaddr_in6 sender; sockaddr_in6 sender;
@@ -501,10 +455,15 @@ int UDPPort6::recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, Se
if (status < 0 && errno != EAGAIN) if (status < 0 && errno != EAGAIN)
{ {
WRITELOG("errno == %d in UDPPort::recvfrom: %s\n",errno,strerror(errno)); D_NWSTACK("errno in UDPPort6::recvfrom: %s\n", strerror(errno));
return -1; return -1;
} }
addr->setAddress(&sender, (uint16_t)sender.sin6_port); addr->setAddress(&sender);
//D_NWSTACK("recved from %s:%d length = %d\n", inet_ntoa(sender.sin_addr),ntohs(sender.sin_port), status);
#ifdef DEBUG_NW
char addrBuf[INET6_ADDRSTRLEN];
addr->sprint(addrBuf);
D_NWSTACK("sendto %s length = %d\n", addrBuf, status);
#endif
return status; return status;
} }

View File

@@ -22,18 +22,13 @@
#include "MQTTSNGWDefines.h" #include "MQTTSNGWDefines.h"
#include <arpa/inet.h> #include <arpa/inet.h>
#include <string> #include <string>
#include <poll.h>
using namespace std; using namespace std;
namespace MQTTSNGW namespace MQTTSNGW
{ {
#ifdef DEBUG_NWSTACK
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
/*=========================================== /*===========================================
Class SensorNetAddreess Class SensorNetAddreess
============================================*/ ============================================*/
@@ -42,23 +37,22 @@ class SensorNetAddress
public: public:
SensorNetAddress(); SensorNetAddress();
~SensorNetAddress(); ~SensorNetAddress();
void setAddress(struct sockaddr_in6 *IpAddr, uint16_t port); void setAddress(sockaddr_in6 *IpAddr);
int setAddress(string* data); int setAddress(string* data);
int setAddress(const char* data); int setAddress(const char* data);
uint16_t getPortNo(void); uint16_t getPortNo(void);
struct sockaddr_in6 *getIpAddress(void); sockaddr_in6* getIpAddress(void);
char* getAddress(void); char* getAddress(void);
bool isMatch(SensorNetAddress* addr); bool isMatch(SensorNetAddress* addr);
SensorNetAddress& operator =(SensorNetAddress& addr); SensorNetAddress& operator =(SensorNetAddress& addr);
char* sprint(char* buf); char* sprint(char* buf);
private: private:
uint16_t _portNo;
char _addrString[INET6_ADDRSTRLEN + 1]; char _addrString[INET6_ADDRSTRLEN + 1];
struct sockaddr_in6 _IpAddr; sockaddr_in6 _IpAddr;
}; };
/*======================================== /*========================================
Class UpdPort Class UpdPort6
=======================================*/ =======================================*/
class UDPPort6 class UDPPort6
{ {
@@ -66,7 +60,7 @@ public:
UDPPort6(); UDPPort6();
virtual ~UDPPort6(); virtual ~UDPPort6();
int open(const char* ipAddress, uint16_t uniPortNo, const char* broadcastAddr, const char* interfaceName, unsigned int hops); int open(uint16_t uniPortNo, uint16_t multiPortNo, const char *broadcastAddr, const char *interfaceName, uint32_t hops);
void close(void); void close(void);
int unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* sendToAddr); int unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* sendToAddr);
int broadcast(const uint8_t* buf, uint32_t length); int broadcast(const uint8_t* buf, uint32_t length);
@@ -76,15 +70,11 @@ private:
void setNonBlocking(const bool); void setNonBlocking(const bool);
int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr); int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr);
int _sockfdUnicast; pollfd _pollfds[2];
int _sockfdMulticast;
char _interfaceName[10];
SensorNetAddress _grpAddr; SensorNetAddress _grpAddr;
SensorNetAddress _clientAddr; SensorNetAddress _clientAddr;
uint16_t _uniPortNo;
bool _disconReq; bool _disconReq;
unsigned int _hops; uint32_t _hops;
}; };
/*=========================================== /*===========================================

View File

@@ -25,13 +25,6 @@ using namespace std;
namespace MQTTSNGW namespace MQTTSNGW
{ {
//#define DEBUG_NWSTACK
#ifdef DEBUG_NWSTACK
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
#define API_XMITREQUEST 0x10 #define API_XMITREQUEST 0x10
#define API_RESPONSE 0x90 #define API_RESPONSE 0x90

View File

@@ -21,7 +21,6 @@
#include "MQTTSNGWPacketHandleTask.h" #include "MQTTSNGWPacketHandleTask.h"
using namespace MQTTSNGW; using namespace MQTTSNGW;
/* /*
* Gateway Application * Gateway Application
*/ */

View File

@@ -15,10 +15,15 @@ cmake .. -DSENSORNET=xbee
make MQTT-SNGateway make MQTT-SNGateway
cmake .. -DSENSORNET=udp6 cmake .. -DSENSORNET=udp6
make MQTT-SNGateway make MQTT-SNGateway
cmake .. -DSENSORNET=dtls
make MQTT-SNGateway
cmake .. -DSENSORNET=udp cmake .. -DSENSORNET=udp
make MQTT-SNGateway make MQTT-SNGateway
cd ../MQTTSNGateway/GatewayTester cd ../MQTTSNGateway/GatewayTester
make make SENSORNET=UDP6
make SENSORNET=DTLS
make SENSORNET=DTLS6
make SENSORNET=RFCOMM
make SENSORNET=UDP