mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2025-12-12 15:16:50 +01:00
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:
541
.cproject
541
.cproject
@@ -1,354 +1,191 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.602829827" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNClient/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value="pthread"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="ssl"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="crypto"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="bluetooth"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.170974409" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
|
||||
</option>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="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"/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.216116103" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1094525037" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.162341902" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.456127079" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1623573602" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.68366124" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1879517971" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
|
||||
</option>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="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/rfcomm|linux/ble" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
|
||||
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug"/>
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.602829827" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.default" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNClient/src}""/>
|
||||
</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"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.798283837" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="OPENSSL_API_COMPAT=30000"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1870583388" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="ssl"/>
|
||||
<listOptionValue builtIn="false" value="crypto"/>
|
||||
<listOptionValue builtIn="false" value="pthread"/>
|
||||
<listOptionValue builtIn="false" value="bluetooth"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.170974409" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
</option>
|
||||
<option id="gnu.cpp.link.option.shared.1648098307" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="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="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
</option>
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.216116103" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1094525037" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.162341902" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.456127079" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1623573602" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.68366124" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1879517971" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="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 flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Debug"/>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
@@ -1,48 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-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 "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-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 "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
</project>
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176156747064280842" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
</extension>
|
||||
</configuration>
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176157551606184930" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
@@ -20,7 +20,10 @@ CPPSRCS := \
|
||||
$(SUBDIR)/LGwProxy.cpp \
|
||||
$(SUBDIR)/LMqttsnClient.cpp \
|
||||
$(SUBDIR)/LNetworkUdp.cpp \
|
||||
$(SUBDIR)/LNetworkUdp6.cpp \
|
||||
$(SUBDIR)/LNetworkRfcomm.cpp \
|
||||
$(SUBDIR)/LNetworkDtls.cpp \
|
||||
$(SUBDIR)/LNetworkDtls6.cpp \
|
||||
$(SUBDIR)/LPublishManager.cpp \
|
||||
$(SUBDIR)/LRegisterManager.cpp \
|
||||
$(SUBDIR)/LSubscribeManager.cpp \
|
||||
@@ -38,11 +41,13 @@ CXX := g++
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDES += -I$(SUBDIR)
|
||||
DEFS :=
|
||||
LIBS +=
|
||||
DEF1 :=
|
||||
DEF2 :=
|
||||
DEFS := -D$(SN) $(DEF1) $(DEF2)
|
||||
LIBS += -L/usr/local/lib -L/usr/local/opt/openssl
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD := -lbluetooth
|
||||
LDADD := -lbluetooth -lssl -lcrypto
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGTEST)
|
||||
@@ -76,23 +81,23 @@ $(PROGQOS): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/$(QOSAPPL).o
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
@@ -2,27 +2,6 @@
|
||||
**sample/mainTest.cpp** is a Test sample coading.
|
||||
Each test is described as one function. test1(), test2()...
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*
|
||||
* you can use 4 commands in Test functions
|
||||
*
|
||||
* 1) PUBLISH(const char* topicName,
|
||||
* uint8_t* payload,
|
||||
* uint16_t len,
|
||||
* uint8_t qos,
|
||||
* bool retain = false);
|
||||
*
|
||||
* 2) SUBSCRIBE(const char* topicName,
|
||||
* TopicCallback onPublish,
|
||||
* uint8_t qos);
|
||||
*
|
||||
* 3) UNSUBSCRIBE(const char* topicName);
|
||||
*
|
||||
* 4) DISCONNECT(uint16_t sleepInSecs);
|
||||
*
|
||||
*------------------------------------------------------*/
|
||||
|
||||
void test1(void)
|
||||
{
|
||||
char payload[300];
|
||||
@@ -36,8 +15,34 @@ void test2(void)
|
||||
uint8_t qos = 1;
|
||||
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
|
||||
@@ -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.
|
||||
Uncomment a line \#define UDP or RFCOMM in LMqttsnClientApp.h file.
|
||||
**UDP**, **DTLS**, **UDP6**, **DTLS6** or **Bluetooth** is available as a sensor network.
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* UDP, DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6, DTLS6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||
"ff12::feed:caca:dead", // Multicast group IP
|
||||
"wlp4s0",
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
```
|
||||
|
||||
/*======================================
|
||||
* 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
|
||||
$ make
|
||||
$ make install
|
||||
$ make clean
|
||||
$ ./build.sh [udp | udp6 | dtls | dtls6 | rfcomm]
|
||||
```
|
||||
MQTT-SNGatewayTester program is copied into ../../../ directory.
|
||||
|
||||
|
||||
## **step3. Execute Gateway Tester.**
|
||||
|
||||
## Execute Gateway Tester
|
||||
```
|
||||
$ cd ../../..
|
||||
$ ./MQTT-SNGatewayTester
|
||||
$ ./Build/MQTT-SNGatewayTester
|
||||
|
||||
***************************************************************************
|
||||
* MQTT-SN Gateway Tester
|
||||
* MQTT-SN Gateway Tester DTLS
|
||||
* Part of Project Paho in Eclipse
|
||||
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
|
||||
*
|
||||
* Author : Tomoaki YAMAGUCHI
|
||||
* Version: 0.0.0
|
||||
* Version: 2.0.0
|
||||
***************************************************************************
|
||||
|
||||
Attempting to Connect the Broker.....
|
||||
|
||||
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 ) :
|
||||
Execute "Step0:Connect" ? ( y/n ) :
|
||||
|
||||
```
|
||||
|
||||
22
MQTTSNGateway/GatewayTester/build.sh
Executable file
22
MQTTSNGateway/GatewayTester/build.sh
Executable 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
|
||||
|
||||
|
||||
@@ -51,17 +51,26 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"ClientPUB", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20010, // Local PortNo
|
||||
};
|
||||
UDPCONF = { "ClientPUB", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20010, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "ClientPUB", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
RFCOMMCONF = { "ClientPUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
@@ -51,17 +51,26 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"QoS-1_Client01", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20001, // Local PortNo
|
||||
};
|
||||
UDPCONF = { "QoS-1_Client01", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20001, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "QoS-1_Client01", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
RFCOMMCONF = { "QoS-1_Client01", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
@@ -51,17 +51,26 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"ClientSUB", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20011, // Local PortNo
|
||||
};
|
||||
UDPCONF = { "ClientSUB", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20011, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "ClientSUB", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
RFCOMMCONF = { "ClientSUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
*
|
||||
* void PUBLISH ( uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void SUBSCRIBE ( const char* topicName, TopicCallback onPublish, uint8_t qos );
|
||||
* void SUBSCRIBE ( const char* topicName, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos );
|
||||
* void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void UNSUBSCRIBE ( const char* topicName );
|
||||
* void UNSUBSCRIBE ( const char* topicName );
|
||||
*
|
||||
* void UNSUBSCRIBE ( uint16_t topicId );
|
||||
* void UNSUBSCRIBE ( uint16_t topicId );
|
||||
*
|
||||
* void DISCONNECT ( uint16_t sleepInSecs );
|
||||
*
|
||||
@@ -49,7 +49,7 @@ extern LMqttsnClient* theClient;
|
||||
extern LScreen* theScreen;
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
* UDP,DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
@@ -57,6 +57,16 @@ UDPCONF = { "GatewayTestClient", // ClientId
|
||||
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)
|
||||
*------------------------------------------------------*/
|
||||
|
||||
@@ -200,6 +200,15 @@ int LGwProxy::getConnectResponce(void)
|
||||
{
|
||||
_network.setGwAddress();
|
||||
_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;
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LRegisterManager.h"
|
||||
#include "LTimer.h"
|
||||
#include "LTopicTable.h"
|
||||
@@ -43,6 +46,7 @@ using namespace std;
|
||||
#define GW_SLEEPING 10
|
||||
#define GW_DISCONNECTED 11
|
||||
#define GW_SLEPT 12
|
||||
#define SSL_CONNECTING 13
|
||||
|
||||
#define GW_WAIT_PINGRESP 1
|
||||
|
||||
|
||||
@@ -53,8 +53,14 @@ int main(int argc, char** argv)
|
||||
printf("\n%s", PAHO_COPYRIGHT0);
|
||||
#if defined(UDP)
|
||||
printf(" UDP\n");
|
||||
#elif defined(UDP6)
|
||||
printf(" UDP6\n");
|
||||
#elif defined(RFCOMM)
|
||||
printf(" RFCOMM\n");
|
||||
#elif defined(DTLS)
|
||||
printf(" DTLS\n");
|
||||
#elif defined(DTLS6)
|
||||
printf(" DTLS6\n");
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
#ifndef MQTTSNCLIENTAPP_H_
|
||||
#define MQTTSNCLIENTAPP_H_
|
||||
|
||||
/*======================================
|
||||
* Debug Flag
|
||||
======================================*/
|
||||
//#define DEBUG_NW
|
||||
//#define DEBUG_MQTTSN
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
#define UDP
|
||||
//#define RFCOMM
|
||||
/*======================================
|
||||
* Debug Flag
|
||||
======================================*/
|
||||
#define DEBUG_NW
|
||||
//#define DEBUG_MQTTSN
|
||||
|
||||
/****************************************
|
||||
MQTT-SN Parameters
|
||||
@@ -75,6 +74,15 @@ struct LUdpConfig
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LUdp6Config
|
||||
{
|
||||
const char* clientId;
|
||||
const char* ipAddress;
|
||||
const char *interface;
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LRfcommConfig
|
||||
{
|
||||
const char* clientId;
|
||||
@@ -97,20 +105,40 @@ typedef enum
|
||||
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
#ifdef UDP
|
||||
#define NETWORK_CONFIG UdpConfig theNetworkConfig
|
||||
#if defined(UDP)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define RFCOMMCONF LRfcommConfig theConf
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
#else
|
||||
#ifdef RFCOMM
|
||||
#define NETWORK_CONFIG BleConfig theNetworkConfig
|
||||
|
||||
#elif defined(UDP6)
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
|
||||
#elif defined(RFCOMM)
|
||||
#define RFCOMMCONF LRfcommConfig theNetcon
|
||||
#define UDPCONF LUdpConfig theConf
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define SENSORNET_CONFIG_t LRfcommConfig
|
||||
|
||||
#elif defined(DTLS)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(DTLS6)
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
#else
|
||||
#error "UDP, UDP6, DTLS, DTLS6 or RFCOMM is not defined in LMqttsnClientApp.h"
|
||||
#endif
|
||||
#error "UDP and RFCOMM are not defined in LMqttsnClientApp.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
|
||||
#define PUBLISH(...) theClient->publish(__VA_ARGS__)
|
||||
|
||||
537
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
537
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal 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
|
||||
|
||||
117
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
117
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal 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_ */
|
||||
533
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
533
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal 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
|
||||
|
||||
121
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
121
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal 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_ */
|
||||
@@ -13,7 +13,6 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#include "LMqttsnClientApp.h"
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -29,6 +28,7 @@
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/rfcomm.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#ifndef NETWORKRFCOMM_H_
|
||||
#define NETWORKRFCOMM_H_
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#include "LMqttsnClientApp.h"
|
||||
#ifdef UDP
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -27,89 +26,105 @@
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.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 uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork(){
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork(){
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen){
|
||||
return LUdpPort::multicast(xmitData, (uint32_t)dataLen);
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdpPort::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen){
|
||||
return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int* len){
|
||||
*len = 0;
|
||||
if (checkRecvBuf()){
|
||||
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if(_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(recvLen < 0){
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}else{
|
||||
if(_rxDataBuf[0] == 0x01){
|
||||
*len = getUint16(_rxDataBuf + 1 );
|
||||
}else{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
//if(recvLen != *len){
|
||||
// *len = 0;
|
||||
// return 0;
|
||||
//}else{
|
||||
return _rxDataBuf;
|
||||
//}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
//if(recvLen != *len){
|
||||
// *len = 0;
|
||||
// return 0;
|
||||
//}else{
|
||||
return _rxDataBuf;
|
||||
//}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void){
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
}
|
||||
|
||||
void LNetwork::setFixedGwAddress(void){
|
||||
void LNetwork::setFixedGwAddress(void)
|
||||
{
|
||||
_gwPortNo = LUdpPort::_gPortNo;
|
||||
_gwIpAddress = LUdpPort::_gIpAddr;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void){
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
|
||||
bool LNetwork::initialize(LUdpConfig* config){
|
||||
return LUdpPort::open(config);
|
||||
bool LNetwork::initialize(LUdpConfig *config)
|
||||
{
|
||||
return LUdpPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep(){
|
||||
_sleepflg = true;
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
@@ -117,7 +132,7 @@ bool LNetwork::isBroadcastable()
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udpStack
|
||||
Class udpStack
|
||||
=========================================*/
|
||||
LUdpPort::LUdpPort()
|
||||
{
|
||||
@@ -132,267 +147,302 @@ LUdpPort::~LUdpPort()
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LUdpPort::close(){
|
||||
if(_sockfdMcast > 0)
|
||||
{
|
||||
::close( _sockfdMcast);
|
||||
_sockfdMcast = -1;
|
||||
if(_sockfdUcast > 0)
|
||||
{
|
||||
::close( _sockfdUcast);
|
||||
_sockfdUcast = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdpPort::open(LUdpConfig* config)
|
||||
void LUdpPort::close()
|
||||
{
|
||||
const int reuse = 1;
|
||||
char loopch = 1;
|
||||
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*)config->ipAddress);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdUcast < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if( ::bind ( _sockfdUcast, (struct sockaddr*)&addr, sizeof(addr)) <0){
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMcast < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
return true;
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = -1;
|
||||
if (_sockfdUcast > 0)
|
||||
{
|
||||
::close(_sockfdUcast);
|
||||
_sockfdUcast = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdpPort::isUnicast(){
|
||||
return ( _castStat == STAT_UNICAST);
|
||||
bool LUdpPort::open(LUdpConfig *config)
|
||||
{
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdUcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (::bind(_sockfdUcast, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 UdpPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
optval= 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port ){
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = port;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
|
||||
int status = ::sendto( _sockfdUcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );
|
||||
if( status < 0){
|
||||
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");
|
||||
|
||||
if ( !theClientMode )
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf,"\033[0;34msendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20 ) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
bool LUdpPort::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
int LUdpPort::unicast(const uint8_t *buf, uint32_t length, uint32_t ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = port;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
|
||||
int LUdpPort::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(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("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");
|
||||
|
||||
int status = ::sendto( _sockfdMcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );
|
||||
if( status < 0){
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}else{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
DISPLAY(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
int LUdpPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
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;
|
||||
}
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
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));
|
||||
} 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 LUdpPort::checkRecvBuf(){
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
bool LUdpPort::checkRecvBuf()
|
||||
{
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(_sockfdUcast, &recvfds);
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(_sockfdUcast, &recvfds);
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
|
||||
if(_sockfdMcast > _sockfdUcast){
|
||||
maxSock = _sockfdMcast;
|
||||
}else{
|
||||
maxSock = _sockfdUcast;
|
||||
}
|
||||
if (_sockfdMcast > _sockfdUcast)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdUcast;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if(FD_ISSET(_sockfdUcast, &recvfds)){
|
||||
if( ::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
||||
_castStat = STAT_UNICAST;
|
||||
return true;
|
||||
}
|
||||
}else if(FD_ISSET(_sockfdMcast, &recvfds)){
|
||||
if( ::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = 0;
|
||||
return false;
|
||||
if (FD_ISSET(_sockfdUcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_UNICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LUdpPort::recv(uint8_t* buf, uint16_t len, bool flg, uint32_t* ipAddressPtr, uint16_t* portPtr){
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom (buf, len, flags, ipAddressPtr, portPtr );
|
||||
int LUdpPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){
|
||||
struct sockaddr_in sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
int LUdpPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
if(isUnicast()){
|
||||
status = ::recvfrom( _sockfdUcast, buf, length, flags, (struct sockaddr*)&sender, &addrlen );
|
||||
}else if(_castStat == STAT_MULTICAST){
|
||||
status = ::recvfrom( _sockfdMcast, buf, length, flags, (struct sockaddr*)&sender, &addrlen );
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
if (isUnicast())
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN) {
|
||||
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){
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
D_NWLOG("\nrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
for(uint16_t i = 0; i < status ; i++){
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
D_NWLOG("recved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if ( !theClientMode )
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < status ; i++){
|
||||
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;
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#ifndef NETWORKUDP_H_
|
||||
#define NETWORKUDP_H_
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#ifdef UDP
|
||||
|
||||
#include <sys/time.h>
|
||||
@@ -30,7 +29,6 @@
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
|
||||
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdp6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int diffAddr = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && diffAddr && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
memcpy(_gwIpAddress.s6_addr, _ipAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = _portNo;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(_gwIpAddress.s6_addr, 0, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LUdp6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udp6Stack
|
||||
=========================================*/
|
||||
LUdp6Port::LUdp6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
memset(_pollfds, 0, sizeof(_pollfds));
|
||||
_sock = 0;
|
||||
_interface = NULL;
|
||||
_gIpAddrStr = NULL;
|
||||
}
|
||||
|
||||
LUdp6Port::~LUdp6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
if (_interface)
|
||||
{
|
||||
free(_interface);
|
||||
}
|
||||
}
|
||||
|
||||
void LUdp6Port::close()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].fd > 0)
|
||||
{
|
||||
::close(_pollfds[i].fd);
|
||||
_pollfds[i].fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
int sock = 0;
|
||||
uint32_t ifindex = 0;
|
||||
sockaddr_in6 addr6;
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create a unicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
ifindex = if_nametoindex(config->interface);
|
||||
#ifdef __APPLE__
|
||||
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
|
||||
#else
|
||||
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, config->interface, strlen(config->interface));
|
||||
#endif
|
||||
}
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _uPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
_pollfds[0].fd = sock;
|
||||
_pollfds[0].events = POLLIN;
|
||||
|
||||
/* create a multicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = ifindex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
optval = 1;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
_pollfds[1].fd = sock;
|
||||
_pollfds[1].events = POLLIN;
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
int LUdp6Port::unicast(const uint8_t *buf, uint32_t length, in6_addr ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = port;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("unicast to [%s]:%-6u", addrBuf, htons(port));
|
||||
|
||||
int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG(" errno = %d %s in Udp6Port::unicast\n", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34municast to [%s[:%-6u", addrBuf, htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LUdp6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gPortNo));
|
||||
|
||||
int status = ::sendto(_pollfds[1].fd, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s ", _gIpAddrStr, portStr);
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d %s in Udp6Port::multicast\033[0m\033[0;37m\n", errno, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
int cnt = poll(_pollfds, 2, 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 */
|
||||
|
||||
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKUDP6_H_
|
||||
#define NETWORKUDP6_H_
|
||||
|
||||
#ifdef UDP6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LUpd6Port
|
||||
=======================================*/
|
||||
class LUdp6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LUdp6Port();
|
||||
virtual ~LUdp6Port();
|
||||
|
||||
bool open(LUdp6Config *config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length, in6_addr ipaddress, uint16_t port);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t *buf, uint16_t len, bool nonblock, in6_addr *ipaddress, uint16_t *port);
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
int recvfrom(uint8_t *buf, uint16_t len, int flags, in6_addr *ipaddress, uint16_t *port);
|
||||
|
||||
pollfd _pollfds[2];
|
||||
uint16_t _gPortNo;
|
||||
uint16_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
char* _interface;
|
||||
int _sock;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LUdp6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config *config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
uint16_t _gwPortNo;
|
||||
uint16_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP6 */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
@@ -1,164 +0,0 @@
|
||||
PROGNAME := MQTT-SNGateway
|
||||
APPL := mainGateway
|
||||
|
||||
LPROGNAME := MQTT-SNLogmonitor
|
||||
LAPPL := mainLogmonitor
|
||||
|
||||
TESTPROGNAME := testPFW
|
||||
TESTAPPL := mainTestProcess
|
||||
|
||||
CONFIG := gateway.conf
|
||||
CLIENTS := clients.conf
|
||||
PREDEFTOPIC := predefinedTopic.conf
|
||||
|
||||
SRCDIR := src
|
||||
SUBDIR := ../MQTTSNPacket/src
|
||||
|
||||
OS := linux
|
||||
SENSORNET := udp
|
||||
TEST := tests
|
||||
|
||||
INSTALL_DIR=../../
|
||||
CONFIG_DIR=../../
|
||||
|
||||
CPPSRCS := \
|
||||
$(SRCDIR)/MQTTGWConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTGWPacket.cpp \
|
||||
$(SRCDIR)/MQTTGWPublishHandler.cpp \
|
||||
$(SRCDIR)/MQTTGWSubscribeHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGateway.cpp \
|
||||
$(SRCDIR)/MQTTSNGWBrokerRecvTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWBrokerSendTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClient.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientRecvTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientSendTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWLogmonitor.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPacket.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPacketHandleTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWProcess.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPublishHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWSubscribeHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWEncapsulatedPacket.cpp \
|
||||
$(SRCDIR)/MQTTSNGWForwarder.cpp \
|
||||
$(SRCDIR)/MQTTSNGWQoSm1Proxy.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAdapter.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAggregater.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientList.cpp \
|
||||
$(SRCDIR)/MQTTSNGWTopic.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAdapterManager.cpp \
|
||||
$(SRCDIR)/MQTTSNAggregateConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWMessageIdTable.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAggregateTopicTable.cpp \
|
||||
$(SRCDIR)/$(OS)/$(SENSORNET)/SensorNetwork.cpp \
|
||||
$(SRCDIR)/$(OS)/Timer.cpp \
|
||||
$(SRCDIR)/$(OS)/Network.cpp \
|
||||
$(SRCDIR)/$(OS)/Threading.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestProcess.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestQue.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTree23.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTopics.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTopicIdMap.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTask.cpp
|
||||
|
||||
|
||||
CSRCS := $(SUBDIR)/MQTTSNConnectClient.c \
|
||||
$(SUBDIR)/MQTTSNConnectServer.c \
|
||||
$(SUBDIR)/MQTTSNDeserializePublish.c \
|
||||
$(SUBDIR)/MQTTSNPacket.c \
|
||||
$(SUBDIR)/MQTTSNSearchClient.c \
|
||||
$(SUBDIR)/MQTTSNSearchServer.c \
|
||||
$(SUBDIR)/MQTTSNSerializePublish.c \
|
||||
$(SUBDIR)/MQTTSNSubscribeClient.c \
|
||||
$(SUBDIR)/MQTTSNSubscribeServer.c \
|
||||
$(SUBDIR)/MQTTSNUnsubscribeClient.c \
|
||||
$(SUBDIR)/MQTTSNUnsubscribeServer.c
|
||||
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDE :=
|
||||
INCLUDES += $(INCLUDE) -I$(SRCDIR) \
|
||||
-I$(SRCDIR)/$(OS) \
|
||||
-I$(SRCDIR)/$(OS)/$(SENSORNET) \
|
||||
-I$(SUBDIR) \
|
||||
-I$(SRCDIR)/$(TEST) \
|
||||
-I/usr/local/opt/openssl/include/
|
||||
|
||||
# preprocessor defines
|
||||
DEFS :=
|
||||
|
||||
CXX := g++
|
||||
|
||||
LIB :=
|
||||
LIBS += $(LIB) -L/usr/local/lib -L/usr/local/opt/openssl/lib/
|
||||
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD := -lpthread -lssl -lcrypto
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGNAME)
|
||||
LPROG := $(OUTDIR)/$(LPROGNAME)
|
||||
TPROG := $(OUTDIR)/$(TESTPROGNAME)
|
||||
|
||||
OBJS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.o)
|
||||
OBJS += $(CSRCS:%.c=$(OUTDIR)/%.o)
|
||||
DEPS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.d)
|
||||
DEPS += $(CSRCS:%.c=$(OUTDIR)/%.d)
|
||||
|
||||
.PHONY: install clean exectest
|
||||
|
||||
all: $(PROG) $(LPROG) $(TPROG)
|
||||
|
||||
monitor: $(LPROG)
|
||||
|
||||
test: $(TPROG) $(LPROG) exectest
|
||||
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
$(PROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(APPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
$(LPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(LAPPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
$(TPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(APPL).o:$(SRCDIR)/$(APPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o:$(SRCDIR)/$(TEST)/$(TESTAPPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(LAPPL).o:$(SRCDIR)/$(LAPPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.c
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
install:
|
||||
cp -pf $(PROG) $(INSTALL_DIR)
|
||||
cp -pf $(LPROG) $(INSTALL_DIR)
|
||||
cp -pf $(CONFIG) $(CONFIG_DIR)
|
||||
cp -pf $(CLIENTS) $(CONFIG_DIR)
|
||||
cp -pf $(PREDEFTOPIC) $(CONFIG_DIR)
|
||||
|
||||
|
||||
exectest:
|
||||
./$(OUTDIR)/$(TESTPROGNAME) -f ./gateway.conf
|
||||
|
||||
|
||||
@@ -1,142 +1,211 @@
|
||||
MQTT-SN Transparent / Aggregating Gateway
|
||||
|
||||
**MQTT-SN** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||
|
||||
### **step1. Build the gateway**
|
||||
````
|
||||
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||
# MQTT-SN Transparent / Aggregating Gateway
|
||||
MQTT-SN requires a MQTT-SN Gateway which acts as a protocol converter to convert MQTT-SN messages to MQTT messages.
|
||||
MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||
### step1. Build the gateway
|
||||
copy and expand source code then,
|
||||
```
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||
```
|
||||
In order to build a gateway, one sensor network argument is required.
|
||||
```
|
||||
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm]
|
||||
|
||||
````
|
||||
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.**
|
||||
```
|
||||
|
||||
````
|
||||
MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin directory.
|
||||
|
||||
### step2. Execute the Gateway.
|
||||
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNGateway
|
||||
````
|
||||
$ ./MQTT-SNGateway
|
||||
```
|
||||
If you get the error message as follows:
|
||||
````
|
||||
RingBuffer can't create a shared memory.
|
||||
ABORT Gateway!!!
|
||||
````
|
||||
|
||||
RingBuffer can't create a shared memory. ABORT Gateway!!!
|
||||
You have to start using sudo command only once for the first time.
|
||||
````
|
||||
$ sudo ./MQTT-SNGateway
|
||||
````
|
||||
```
|
||||
$ 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:
|
||||
|
||||
<pre><dev>
|
||||
```
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#***************************************************************************
|
||||
#
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
```
|
||||
**GatewayID** is a gateway ID which used by GWINFO message.
|
||||
**GatewayName** is a name of the gateway.
|
||||
**MaxNumberOfClients** is a maxmum number of clients. Clients are dynamically allocated.
|
||||
**KeepAlive** is KeepAlive time in seconds.
|
||||
**LoginID** is used by CONNECT message.
|
||||
**Password** is used by CONNECT message.
|
||||
**BrokerName**is a domain name or IP address of a broker.
|
||||
**BrokerPortNo** is a broker's port no.
|
||||
**BrokerSecurePortNo** is a broker's port no of TLS connection.
|
||||
```
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
```
|
||||
**RootCAfile** is a CA file name.
|
||||
**RootCApath** is a CA path. **SSL_CTX_load_verify_locations(ctx, CAfile, CApath)** function requires these parameters.
|
||||
**CertsKey** is a certificate pem file.
|
||||
**PrivateKey** is a private key pem file.
|
||||
Clients can connect to the broker via TLS by setting '**Secure Connection**' for each client in the client conf file.
|
||||
```
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
MaxNumberOfClients=30;
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
```
|
||||
The gateway runs as a aggregating gateway when **AggregatingGateway** is 'YES'.
|
||||
If **QoS-1** is 'YES, the gateway prepares a proxy for the QoS-1 client. QoS-1 client has a 'QoS-1' parameter in a clients.conf file. For QoS-1 clients, set the QoS-1 parameters in the clients.conf file.
|
||||
If **Forwarder** is 'YES', the gateway prepare a forwarder agent.
|
||||
If **ClientAuthentication** is 'YES', the client cannot connect unless it is registered in the clients.conf file.
|
||||
**ClientsList** defines clients and those address so on.
|
||||
**PredefinedTopicList** file defines Predefined Topic.
|
||||
|
||||
|
||||
# UDP
|
||||
```
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastTTL=1
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
```
|
||||
**GatewayPortNo** is a unicast port no of the gateway.
|
||||
**MulticastIP** and **MulticastPortNo** are for GWSEARCH messages. Clients can get the gateway address (Gateway IP address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
|
||||
Client needs to know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**MulticastTTL** is a multicast TTL.
|
||||
```
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::feed:caca:dead
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
```
|
||||
**GatewayIPv6PortNo** is a unicast port no of the gateway.
|
||||
**MulticastIPv6PortNo** and **MulticastIPv6** are for GWSEARCH messages. Set the Global scope Multicast address so that the Global address is used for sending GWINFO.
|
||||
Clients can get the gateway address (Gateway IPv6 address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
|
||||
**MulticastIPv6If** is a multicast interface name.
|
||||
**MulticastHops** is a multicast hops.
|
||||
```
|
||||
#
|
||||
# DTLS | DTLS6 DTLS CertsKey
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
```
|
||||
**DtlsCertsKey** is a certs Key pem file for DTLS connection.
|
||||
**DtlsPrivKey** is a private key pem file for DTLS connection.
|
||||
```
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
```
|
||||
**Baudrate** is a baudrate of xbee.
|
||||
```
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
#LoRaLink
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/ttyLoRaLinkRx
|
||||
DeviceTxLoRaLink=/dev/ttyLoRaLinkTx
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
```
|
||||
https://github.com/ty4tw/MQTT-SN-LoRa
|
||||
|
||||
```
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
|
||||
```
|
||||
**RFCOMMAddress** is a bluetooth mac address and channel. channel should be * for the gateway.
|
||||
```
|
||||
#
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
|
||||
</dev></pre>
|
||||
ShearedMemory=NO
|
||||
```
|
||||
|
||||
**BrokerName** to specify a domain name of the Broker, and **BrokerPortNo** is a port No of the Broker. **BrokerSecurePortNo** is for TLS connection.
|
||||
**MulticastIP** and **MulticastPortNo** is a multicast address for GWSEARCH messages. Gateway is waiting GWSEARCH and when receiving it send GWINFO message via MulticastIP address. Clients can get the gateway address (Gateway IP address and **GatewayPortNo**) from GWINFO message by means of std::recvfrom().
|
||||
Client should know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**GatewayId** is used by GWINFO message.
|
||||
**KeepAlive** is a duration of ADVERTISE message in seconds.
|
||||
when **AggregatingGateway** or **ClientAuthentication** is **YES**, All clients which connect to the gateway must be declared by a **ClientsList** file.
|
||||
Format of the file is ClientId and SensorNetwork Address. e.g. IP address and Port No etc, in CSV. more detail see clients.conf.
|
||||
When **QoS-1** is **YES**, QoS-1 PUBLISH is available. All clients which send QoS-1 PUBLISH must be specified by Client.conf file.
|
||||
When **PredefinedTopic** is **YES**, **Pre-definedTopicId**s specified by **PredefinedTopicList** are effective. This file defines Pre-definedTopics of the clients. In this file, ClientID,TopicName and TopicID are declared in CSV format.
|
||||
When **Forwarder** is **YES**, Forwarder Encapsulation Message is available. Connectable Forwarders must be declared by a **ClientsList** file.
|
||||
**MaxNumberOfClients** Maximum number of clients allocated.
|
||||
|
||||
### ** How to monitor the gateway from remote. **
|
||||
### How to monitor the gateway from a remote terminal.
|
||||
Change gateway.conf as follows:
|
||||
```
|
||||
# LOG
|
||||
ShearedMemory=YES;
|
||||
````
|
||||
|
||||
Restart the gateway with sudo only once to create shared memories.
|
||||
|
||||
```
|
||||
Restart the gateway with sudo only once to create shared memories.
|
||||
open ssh terminal and execute LogMonitor.
|
||||
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNLogmonitor
|
||||
```
|
||||
|
||||
```
|
||||
Now you can get the Log on your terminal.
|
||||
|
||||
|
||||
## ** Tips **
|
||||
Uncomment the line 62, 63 in MQTTSNDefines.h then you can get more precise logs.
|
||||
##### Tips
|
||||
Use compiler definitions then you can get more precise logs.
|
||||
**-DDEBUG_NW** is a flag for debug logs of Sensor network.
|
||||
**-DDEBUG_MQTTSN** is a flag for debug logs of MQTT-SN message haandling.
|
||||
One or both flags can be specified.
|
||||
|
||||
```
|
||||
./build.sh udp -DDEBUG -DDEBUG_NW
|
||||
```
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
```
|
||||
@@ -1,19 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: build.sh [ udp | udp6 | xbee | loralink | rfcomm ]"
|
||||
else
|
||||
echo "Start building MQTT-SN Gateway"
|
||||
build () {
|
||||
echo "Start building MQTT-SN Gateway $1"
|
||||
|
||||
SCRIPT_DIR=$(cd $(dirname $0); pwd)
|
||||
cd $SCRIPT_DIR/..
|
||||
rm -rf build.gateway
|
||||
mkdir build.gateway
|
||||
cd build.gateway
|
||||
cmake .. -DSENSORNET=$1
|
||||
BDIR='build.gateway'
|
||||
if [ ! -d ./$BDIR ]; then
|
||||
mkdir $BDIR
|
||||
fi
|
||||
cd $BDIR
|
||||
cmake .. -DSENSORNET=$1 -DDEFS="${2} ${3}"
|
||||
make MQTTSNPacket
|
||||
make MQTT-SNGateway
|
||||
make MQTT-SNLogmonitor
|
||||
cd ../MQTTSNGateway
|
||||
cp *.conf ./bin/
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2019, Tomoaki Yamaguchi
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
@@ -14,64 +14,96 @@
|
||||
# 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
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
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
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
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
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::1
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
|
||||
#
|
||||
# DTLS | DTLS6
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
DtlsSSLPortNo=10001
|
||||
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
|
||||
#
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
|
||||
ShearedMemory=NO
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ IF(NOT DEFINED SENSORNET)
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "SENSORNET: " ${SENSORNET})
|
||||
|
||||
ADD_DEFINITIONS(${DEFS})
|
||||
MESSAGE(STATUS "Definitions: " ${DEFS})
|
||||
|
||||
ADD_LIBRARY(mqtt-sngateway_common
|
||||
MQTTGWConnectionHandler.cpp
|
||||
MQTTGWPacket.cpp
|
||||
@@ -74,8 +77,11 @@ ADD_LIBRARY(mqtt-sngateway_common
|
||||
${OS}/Threading.h
|
||||
)
|
||||
|
||||
# linux
|
||||
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
|
||||
@@ -84,7 +90,7 @@ TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
|
||||
${OS}
|
||||
${OS}/${SENSORNET}
|
||||
../../MQTTSNPacket/src
|
||||
/usr/local/opt/openssl/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
IF(SENSORNET MATCHES "rfcomm")
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "MQTTSNGWBrokerRecvTask.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTSNGWClientList.h"
|
||||
#include "MQTTSNGateway.h"
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -58,6 +58,7 @@ ClientList::~ClientList()
|
||||
|
||||
void ClientList::initialize(bool aggregate)
|
||||
{
|
||||
_maxClients = _gateway->getGWParams()->maxClients;
|
||||
_clientsPool->allocate(_gateway->getGWParams()->maxClients);
|
||||
|
||||
if (_gateway->getGWParams()->clientAuthentication)
|
||||
@@ -380,6 +381,7 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
{
|
||||
client->setQoSm1();
|
||||
}
|
||||
client->getNetwork()->setSecure(secure);
|
||||
|
||||
_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 *client = nullptr;
|
||||
|
||||
if (topicId == 0)
|
||||
{
|
||||
WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
|
||||
return nullptr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (strcmp(clientId->cstring, common_topic) == 0)
|
||||
{
|
||||
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
return nullptr;
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -419,47 +423,19 @@ Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicNa
|
||||
|
||||
if (_authorize && client == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* anonimous clients */
|
||||
if (_clientCnt > MAX_CLIENTS)
|
||||
client = createClient(NULL, clientId, aggregate);
|
||||
if (client)
|
||||
{
|
||||
return nullptr; // full of clients
|
||||
// create Topic & Add it
|
||||
client->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
client->_hasPredefTopic = true;
|
||||
}
|
||||
|
||||
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
|
||||
client->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
client->_hasPredefTopic = true;
|
||||
return client;
|
||||
}
|
||||
exit:
|
||||
return client;
|
||||
}
|
||||
|
||||
uint16_t ClientList::getClientCount()
|
||||
@@ -517,15 +493,17 @@ void ClientsPool::allocate(int maxClients)
|
||||
|
||||
Client* ClientsPool::getClient(void)
|
||||
{
|
||||
Client *cl = nullptr;
|
||||
|
||||
while (_firstClient != nullptr)
|
||||
{
|
||||
Client* cl = _firstClient;
|
||||
cl = _firstClient;
|
||||
_firstClient = cl->_nextClient;
|
||||
cl->_nextClient = nullptr;
|
||||
_clientCnt--;
|
||||
return cl;
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
return cl;
|
||||
}
|
||||
|
||||
void ClientsPool::setClient(Client* client)
|
||||
|
||||
@@ -83,6 +83,7 @@ private:
|
||||
Client* _endClient;
|
||||
Mutex _mutex;
|
||||
uint16_t _clientCnt;
|
||||
uint16_t _maxClients;
|
||||
bool _authorize { false };
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace MQTTSNGW
|
||||
/*=================================
|
||||
* MQTT-SN Parametrs
|
||||
==================================*/
|
||||
#define MAX_CLIENTS (100) // Number of Clients can be handled.
|
||||
#define MAX_CLIENTS (100) // Default number of Clients can be handled.
|
||||
#define MAX_CLIENTID_LENGTH (64) // Max length of clientID
|
||||
#define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages
|
||||
#define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size
|
||||
@@ -60,13 +60,19 @@ typedef unsigned int uint32_t;
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
#ifdef DEBUG
|
||||
//#define DEBUG_MQTTSN // print out log for debug
|
||||
//#define DEBUG_NW // print out SensorNetwork log
|
||||
#ifdef DEBUG_MQTTSN
|
||||
#define DEBUGLOG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUGLOG(...)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWDEFINES_H_ */
|
||||
|
||||
@@ -100,10 +100,6 @@ int MQTTSNPacket::recv(SensorNetwork* network)
|
||||
{
|
||||
len = desirialize(buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
}
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class SensorNetwork;
|
||||
|
||||
class MQTTSNPacket
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
|
||||
char* currentDateTime(void);
|
||||
|
||||
/*=====================================
|
||||
Class PacketHandleTask
|
||||
=====================================*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <Timer.h>
|
||||
@@ -156,6 +157,8 @@ int Process::getParam(const char* parameter, char* value)
|
||||
{
|
||||
char str[MQTTSNGW_PARAM_MAX];
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
memset(str, 0, sizeof(str));
|
||||
memset(param, 0, sizeof(param));
|
||||
FILE *fp;
|
||||
|
||||
int i = 0, j = 0;
|
||||
@@ -166,40 +169,55 @@ int Process::getParam(const char* parameter, char* value)
|
||||
throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
|
||||
}
|
||||
|
||||
int paramlen = strlen(parameter);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int pos = 0;
|
||||
int len = 0;
|
||||
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (!strncmp(str, parameter, strlen(parameter)))
|
||||
if (str[0] == '#' || str[0] == '\n')
|
||||
{
|
||||
while (str[i++] != '=')
|
||||
{
|
||||
;
|
||||
}
|
||||
while (str[i] != '\n')
|
||||
{
|
||||
param[j++] = str[i++];
|
||||
}
|
||||
param[j] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||
;
|
||||
param[i + 1] = '\0';
|
||||
for (i = 0; isspace(param[i]); i++)
|
||||
;
|
||||
if (i > 0)
|
||||
len = strlen(str);
|
||||
for (pos = 0; i < len; pos++)
|
||||
{
|
||||
if (str[pos] == '=')
|
||||
{
|
||||
j = 0;
|
||||
while (param[i])
|
||||
param[j++] = param[i++];
|
||||
param[j] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == paramlen)
|
||||
{
|
||||
if (strncmp(str, parameter, paramlen) == 0)
|
||||
{
|
||||
strcpy(param, str + pos + 1);
|
||||
param[len - pos - 2] = '\0';
|
||||
|
||||
|
||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||
;
|
||||
param[i + 1] = '\0';
|
||||
for (i = 0; isspace(param[i]); i++)
|
||||
;
|
||||
if (i > 0)
|
||||
{
|
||||
j = 0;
|
||||
while (param[i])
|
||||
param[j++] = param[i++];
|
||||
param[j] = '\0';
|
||||
}
|
||||
strcpy(value, param);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
strcpy(value, param);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
@@ -32,9 +32,9 @@ MQTTSNGW::Gateway* theGateway = nullptr;
|
||||
|
||||
Gateway::Gateway(void)
|
||||
{
|
||||
theGateway = this;
|
||||
theMultiTaskProcess = this;
|
||||
theProcess = this;
|
||||
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
|
||||
_clientList = new ClientList(this);
|
||||
_adapterManager = new AdapterManager(this);
|
||||
_topics = new Topics();
|
||||
@@ -95,15 +95,21 @@ Gateway::~Gateway()
|
||||
{
|
||||
free(_params.configName);
|
||||
}
|
||||
|
||||
if (_params.qosMinusClientListName)
|
||||
{
|
||||
free(_params.qosMinusClientListName);
|
||||
}
|
||||
|
||||
if (_params.bleAddress)
|
||||
if (_params.rfcommAddr)
|
||||
{
|
||||
free(_params.bleAddress);
|
||||
free(_params.rfcommAddr);
|
||||
}
|
||||
if (_params.gwCertskey)
|
||||
{
|
||||
free(_params.gwCertskey);
|
||||
}
|
||||
if (_params.gwPrivatekey)
|
||||
{
|
||||
free(_params.gwPrivatekey);
|
||||
}
|
||||
|
||||
if (_adapterManager)
|
||||
@@ -114,7 +120,6 @@ Gateway::~Gateway()
|
||||
{
|
||||
delete _clientList;
|
||||
}
|
||||
|
||||
if (_topics)
|
||||
{
|
||||
delete _topics;
|
||||
@@ -178,6 +183,14 @@ void Gateway::initialize(int argc, char** argv)
|
||||
{
|
||||
_params.rootCAfile = strdup(param);
|
||||
}
|
||||
if (getParam("DtlsCertsKey", param) == 0)
|
||||
{
|
||||
_params.gwCertskey = strdup(param);
|
||||
}
|
||||
if (getParam("DtlsPrivKey", param) == 0)
|
||||
{
|
||||
_params.gwPrivatekey = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("GatewayID", param) == 0)
|
||||
{
|
||||
@@ -282,11 +295,14 @@ void Gateway::initialize(int argc, char** argv)
|
||||
_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 */
|
||||
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||
|
||||
@@ -308,26 +324,30 @@ void Gateway::run(void)
|
||||
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT4);
|
||||
WRITELOG("\n%s %s has been started.\n\n", currentDateTime(), _params.gatewayName);
|
||||
WRITELOG(" ConfigFile: %s\n", _params.configName);
|
||||
WRITELOG(" ConfigFile : %s\n", _params.configName);
|
||||
|
||||
if (_params.clientListName)
|
||||
{
|
||||
WRITELOG(" ClientList: %s\n", _params.clientListName);
|
||||
WRITELOG(" ClientList : %s\n", _params.clientListName);
|
||||
}
|
||||
|
||||
if (_params.predefinedTopicFileName)
|
||||
{
|
||||
WRITELOG(" PreDefFile: %s\n", _params.predefinedTopicFileName);
|
||||
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
|
||||
}
|
||||
|
||||
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
|
||||
WRITELOG(" Broker: %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" Max number of Clients: %d\n", _params.maxClients);
|
||||
WRITELOG(" RootCApath: %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile: %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey: %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey);
|
||||
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" RootCApath : %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey : %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey : %s\n", _params.privateKey);
|
||||
WRITELOG(" SensorN/W : %s\n", _sensorNetwork.getDescription());
|
||||
#ifdef DTLS
|
||||
WRITELOG(" DtlsCertsKey: %s\n", _params.gwCertskey);
|
||||
WRITELOG(" DtlsPrivKey : %s\n", _params.gwPrivatekey);
|
||||
#endif
|
||||
WRITELOG(" Max Clients : %d\n\n", _params.maxClients);
|
||||
WRITELOG("%s %s starts running.\n\n", currentDateTime(), _params.gatewayName);
|
||||
|
||||
_stopFlg = false;
|
||||
|
||||
@@ -408,12 +428,12 @@ bool Gateway::hasSecureConnection(void)
|
||||
{
|
||||
return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class EventQue
|
||||
=====================================*/
|
||||
EventQue::EventQue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EventQue::~EventQue()
|
||||
|
||||
@@ -168,7 +168,9 @@ public:
|
||||
bool qosMinus1 { false };
|
||||
bool forwarder { false };
|
||||
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);
|
||||
char* getClientListFileName(void);
|
||||
char* getPredefinedTopicFileName(void);
|
||||
|
||||
bool hasSecureConnection(void);
|
||||
Topics* getTopics(void);
|
||||
bool IsStopping(void);
|
||||
void requestSensorNetSubTask(void);
|
||||
|
||||
private:
|
||||
GatewayParams _params;
|
||||
@@ -214,7 +216,6 @@ private:
|
||||
Topics* _topics;
|
||||
bool _stopFlg;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGATEWAY_H_ */
|
||||
|
||||
@@ -656,3 +656,7 @@ bool Network::isSecure()
|
||||
return _secureFlg;
|
||||
}
|
||||
|
||||
void Network::setSecure(bool secureFlg)
|
||||
{
|
||||
_secureFlg = secureFlg;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
bool isValid(void);
|
||||
bool isSecure(void);
|
||||
int getSock(void);
|
||||
void setSecure(bool secureFlg);
|
||||
|
||||
private:
|
||||
static SSL_CTX* _ctx;
|
||||
|
||||
1437
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
1437
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
File diff suppressed because it is too large
Load Diff
163
MQTTSNGateway/src/linux/dtls/SensorNetwork.h
Normal file
163
MQTTSNGateway/src/linux/dtls/SensorNetwork.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef SENSORNETWORK_H_
|
||||
#define SENSORNETWORK_H_
|
||||
|
||||
#include "MQTTSNGWDefines.h"
|
||||
#include "Threading.h"
|
||||
#include <netinet/ip.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <string>
|
||||
#include <poll.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
/*===========================================
|
||||
Class SensorNetAddreess
|
||||
============================================*/
|
||||
typedef struct
|
||||
{
|
||||
int af;
|
||||
union
|
||||
{
|
||||
struct in_addr ad4;
|
||||
struct in6_addr ad6;
|
||||
} addr;
|
||||
} ipAddr_t;
|
||||
|
||||
class SensorNetAddress
|
||||
{
|
||||
public:
|
||||
SensorNetAddress();
|
||||
~SensorNetAddress();
|
||||
void setAddress(ipAddr_t *Address, uint16_t port);
|
||||
int setAddress(string *ipAddrPort);
|
||||
int setIpAddress(string *IpAddress);
|
||||
void setFamily(int type);
|
||||
int getFamily(void);
|
||||
void setPort(in_port_t port);
|
||||
void setSockaddr4(sockaddr_in *sockaddr);
|
||||
void setSockaddr6(sockaddr_in6 *sockaddr);
|
||||
void cpyAddr4(sockaddr_in *sockaddr);
|
||||
void cpyAddr6(sockaddr_in6 *sockaddr);
|
||||
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_ */
|
||||
@@ -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)
|
||||
{
|
||||
D_NWSTACK("\r\n===> Send: ");
|
||||
D_LRSTACK("\r\n===> Send: ");
|
||||
uint8_t buf[2] = { 0 };
|
||||
uint8_t chks = 0;
|
||||
uint16_t len = pLen + 3; // 3 = DestAddr[1] + PayloadType[1] + Crc[1]
|
||||
@@ -404,7 +404,7 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
|
||||
send(type);
|
||||
chks += type;
|
||||
|
||||
D_NWSTACK("\r\n Payload: ");
|
||||
D_LRSTACK("\r\n Payload: ");
|
||||
|
||||
for ( uint8_t i = 0; i < pLen; i++ ){
|
||||
send(payload[i]); // Payload
|
||||
@@ -412,21 +412,21 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
|
||||
}
|
||||
|
||||
chks = 0xff - chks;
|
||||
D_NWSTACK(" checksum ");
|
||||
D_LRSTACK(" checksum ");
|
||||
send(chks);
|
||||
D_NWSTACK("\r\n");
|
||||
D_LRSTACK("\r\n");
|
||||
|
||||
/* wait ACK */
|
||||
_sem.timedwait(LORALINK_TIMEOUT_ACK);
|
||||
|
||||
if ( _respCd == LORALINK_NO_FREE_CH )
|
||||
{
|
||||
D_NWSTACK(" Channel isn't free\r\n");
|
||||
D_LRSTACK(" Channel isn't free\r\n");
|
||||
return -1;
|
||||
}
|
||||
else if ( _respCd != LORALINK_ACK )
|
||||
{
|
||||
D_NWSTACK(" Not Acknowleged\r\n");
|
||||
D_LRSTACK(" Not Acknowleged\r\n");
|
||||
return -1;
|
||||
}
|
||||
return (int)pLen;
|
||||
@@ -479,7 +479,7 @@ int LoRaLink::recv(uint8_t* buf)
|
||||
/*
|
||||
if ( *buf == ESCAPE )
|
||||
{
|
||||
D_NWSTACK( " %02x",buf[0] );
|
||||
D_LRSTACK( " %02x",buf[0] );
|
||||
if ( read(fd, buf, 1) == 1 )
|
||||
{
|
||||
*buf = PAD ^ *buf;
|
||||
@@ -491,7 +491,7 @@ int LoRaLink::recv(uint8_t* buf)
|
||||
|
||||
}
|
||||
*/
|
||||
D_NWSTACK( " %02x",buf[0] );
|
||||
D_LRSTACK(" %02x", buf[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -552,7 +552,7 @@ bool SerialPort::send(unsigned char b)
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWSTACK( " %02x", b);
|
||||
D_LRSTACK(" %02x", b);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation
|
||||
* Tomoaki Yamaguchi - initial API and implementation
|
||||
**************************************************************************************/
|
||||
#ifndef SENSORNETWORKX_H_
|
||||
#define SENSORNETWORKX_H_
|
||||
@@ -25,12 +25,11 @@ using namespace std;
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
//#define DEBUG_NWSTACK
|
||||
|
||||
#ifdef DEBUG_NWSTACK
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__); fflush(stdout)
|
||||
#ifdef DEBUG_NW
|
||||
#define D_LRSTACK(...) printf(__VA_ARGS__); fflush(stdout)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#define D_LRSTACK(...)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -26,12 +26,6 @@ using namespace std;
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
|
||||
#ifdef DEBUG_NWSTACK
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
#define MAX_RFCOMM_CH 30
|
||||
|
||||
/*===========================================
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <poll.h>
|
||||
#include "SensorNetwork.h"
|
||||
#include "MQTTSNGWProcess.h"
|
||||
|
||||
@@ -196,33 +199,33 @@ void SensorNetwork::initialize(void)
|
||||
* MulticastIP=225.1.1.1
|
||||
* MulticastPortNo=1883
|
||||
*
|
||||
*/
|
||||
if (theProcess->getParam("MulticastIP", param) == 0)
|
||||
{
|
||||
ip = param;
|
||||
_description = "UDP Multicast ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastPortNo", param) == 0)
|
||||
{
|
||||
multicastPortNo = atoi(param);
|
||||
_description += ":";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayPortNo", param) == 0)
|
||||
{
|
||||
unicastPortNo = atoi(param);
|
||||
_description += " Gateway Port ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastTTL", param) == 0)
|
||||
{
|
||||
ttl = atoi(param);
|
||||
_description += " TTL: ";
|
||||
_description += param;
|
||||
}
|
||||
*/
|
||||
if (theProcess->getParam("MulticastIP", param) == 0)
|
||||
{
|
||||
ip = param;
|
||||
_description = "UDP Multicast ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastPortNo", param) == 0)
|
||||
{
|
||||
multicastPortNo = atoi(param);
|
||||
_description += ":";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayPortNo", param) == 0)
|
||||
{
|
||||
unicastPortNo = atoi(param);
|
||||
_description += ", Gateway Port:";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastTTL", param) == 0)
|
||||
{
|
||||
ttl = atoi(param);
|
||||
_description += ", TTL:";
|
||||
_description += param;
|
||||
}
|
||||
|
||||
/* Prepare UDP sockets */
|
||||
/* setup UDP sockets */
|
||||
errno = 0;
|
||||
if ( UDPPort::open(ip.c_str(), multicastPortNo, unicastPortNo, ttl) < 0 )
|
||||
{
|
||||
@@ -247,9 +250,7 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||
UDPPort::UDPPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdUnicast = -1;
|
||||
_sockfdMulticast = -1;
|
||||
_ttl = 0;
|
||||
memset(_pollFds, 0, sizeof(_pollFds));
|
||||
}
|
||||
|
||||
UDPPort::~UDPPort()
|
||||
@@ -259,130 +260,126 @@ UDPPort::~UDPPort()
|
||||
|
||||
void UDPPort::close(void)
|
||||
{
|
||||
if (_sockfdUnicast > 0)
|
||||
{
|
||||
::close(_sockfdUnicast);
|
||||
_sockfdUnicast = -1;
|
||||
}
|
||||
if (_sockfdMulticast > 0)
|
||||
{
|
||||
::close(_sockfdMulticast);
|
||||
_sockfdMulticast = -1;
|
||||
}
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollFds[i].fd > 0)
|
||||
{
|
||||
::close(_pollFds[i].fd);
|
||||
_pollFds[i].fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UDPPort::open(const char* ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, unsigned int ttl)
|
||||
int UDPPort::open(const char *multicastIP, uint16_t multiPortNo, uint16_t uniPortNo, unsigned int ttl)
|
||||
{
|
||||
char loopch = 0;
|
||||
const int reuse = 1;
|
||||
int optval = 0;
|
||||
int sock = 0;
|
||||
|
||||
if (uniPortNo == 0 || multiPortNo == 0)
|
||||
{
|
||||
D_NWSTACK("error portNo undefined in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
if (uniPortNo == 0 || multiPortNo == 0)
|
||||
{
|
||||
D_NWSTACK("error portNo undefined in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ip = inet_addr(ipAddress);
|
||||
_multicastAddr.setAddress(ip, htons(multiPortNo));
|
||||
_unicastAddr.setAddress(ip, htons(uniPortNo));
|
||||
_ttl = ttl;
|
||||
/*------ Create unicast socket --------*/
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
D_NWSTACK("error can't create unicast socket in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*------ Create unicast socket --------*/
|
||||
_sockfdUnicast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdUnicast < 0)
|
||||
{
|
||||
D_NWSTACK("error can't create unicast socket in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
sockaddr_in addru;
|
||||
addru.sin_family = AF_INET;
|
||||
addru.sin_port = htons(uniPortNo);
|
||||
addru.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
sockaddr_in addru;
|
||||
addru.sin_family = AF_INET;
|
||||
addru.sin_port = htons(uniPortNo);
|
||||
addru.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (::bind(_sockfdUnicast, (sockaddr*) &addru, sizeof(addru)) < 0)
|
||||
if (::bind(sock, (sockaddr*) &addru, sizeof(addru)) < 0)
|
||||
{
|
||||
D_NWSTACK("error can't bind unicast socket in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(_sockfdUnicast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
|
||||
{
|
||||
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*------ Create Multicast socket --------*/
|
||||
_sockfdMulticast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMulticast < 0)
|
||||
_pollFds[0].fd = sock;
|
||||
_pollFds[0].events = POLLIN;
|
||||
|
||||
/*------ Create Multicast socket --------*/
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
D_NWSTACK("error can't create multicast socket in UDPPort::open\n");
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
setsockopt(_sockfdMulticast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _multicastAddr.getPortNo();
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = htons(multiPortNo);
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (::bind(_sockfdMulticast, (sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWSTACK("error can't bind multicast socket in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
|
||||
{
|
||||
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
if (::bind(sock, (sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWSTACK("error can't bind multicast socket in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ip_mreq mreq;
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _multicastAddr.getIpAddress();
|
||||
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(_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(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(_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(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
|
||||
{
|
||||
D_NWSTACK("error Multicast IP_MULTICAST_TTL 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;
|
||||
#ifdef DEBUG_NW
|
||||
optval = 1;
|
||||
#else
|
||||
optval = 0;
|
||||
#endif
|
||||
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
_multicastAddr.setAddress(inet_addr(multicastIP), htons(multiPortNo));
|
||||
_pollFds[1].fd = sock;
|
||||
_pollFds[1].events = POLLIN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UDPPort::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr)
|
||||
{
|
||||
sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = addr->getPortNo();
|
||||
dest.sin_addr.s_addr = addr->getIpAddress();
|
||||
sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = addr->getPortNo();
|
||||
dest.sin_addr.s_addr = addr->getIpAddress();
|
||||
|
||||
int status = ::sendto(_sockfdUnicast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWSTACK("errno == %d in UDPPort::sendto\n", errno);
|
||||
}
|
||||
D_NWSTACK("sendto %s:%u length = %d\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), status);
|
||||
return status;
|
||||
int status = ::sendto(_pollFds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWSTACK("errno == %d in UDPPort::sendto\n", errno);
|
||||
}
|
||||
|
||||
D_NWSTACK("sendto %s:%u length = %d\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), status);
|
||||
return status;
|
||||
}
|
||||
|
||||
int UDPPort::broadcast(const uint8_t* buf, uint32_t length)
|
||||
@@ -392,55 +389,35 @@ int UDPPort::broadcast(const uint8_t* buf, uint32_t length)
|
||||
|
||||
int UDPPort::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
int rc = 0;
|
||||
poll(_pollFds, 2, 2000); // Timeout 2 seconds
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0; // 1 sec
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(_sockfdUnicast, &recvfds);
|
||||
FD_SET(_sockfdMulticast, &recvfds);
|
||||
|
||||
if (_sockfdMulticast > _sockfdUnicast)
|
||||
{
|
||||
maxSock = _sockfdMulticast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdUnicast;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
if ( select(maxSock + 1, &recvfds, 0, 0, &timeout) > 0 )
|
||||
{
|
||||
if (FD_ISSET(_sockfdUnicast, &recvfds))
|
||||
{
|
||||
rc = recvfrom(_sockfdUnicast, buf, len, 0, addr);
|
||||
}
|
||||
else if (FD_ISSET(_sockfdMulticast, &recvfds))
|
||||
{
|
||||
rc = recvfrom(_sockfdMulticast, buf, len, 0, &_multicastAddr);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
if (_pollFds[0].revents == POLLIN)
|
||||
{
|
||||
rc = recvfrom(_pollFds[0].fd, buf, len, 0, addr);
|
||||
}
|
||||
else if (_pollFds[1].revents == POLLIN)
|
||||
{
|
||||
rc = recvfrom(_pollFds[1].fd, buf, len, 0, addr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int UDPPort::recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr)
|
||||
{
|
||||
sockaddr_in sender;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
sockaddr_in sender;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
int status = ::recvfrom(sockfd, buf, len, flags, (sockaddr*) &sender, &addrlen);
|
||||
int status = ::recvfrom(sockfd, buf, len, flags, (sockaddr*) &sender, &addrlen);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWSTACK("errno == %d in UDPPort::recvfrom\n", errno);
|
||||
return -1;
|
||||
}
|
||||
addr->setAddress(sender.sin_addr.s_addr, sender.sin_port);
|
||||
D_NWSTACK("recved from %s:%d length = %d\n", inet_ntoa(sender.sin_addr),ntohs(sender.sin_port), status);
|
||||
return status;
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWSTACK("errno == %d in UDPPort::recvfrom\n", errno);
|
||||
return -1;
|
||||
}
|
||||
addr->setAddress(sender.sin_addr.s_addr, sender.sin_port);
|
||||
D_NWSTACK("recved from %s:%d length = %d\n", inet_ntoa(sender.sin_addr),ntohs(sender.sin_port), status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,18 +19,13 @@
|
||||
|
||||
#include "MQTTSNGWDefines.h"
|
||||
#include <string>
|
||||
#include <poll.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
|
||||
#ifdef DEBUG_NWSTACK
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
/*===========================================
|
||||
Class SensorNetAddreess
|
||||
============================================*/
|
||||
@@ -70,13 +65,9 @@ private:
|
||||
void setNonBlocking(const bool);
|
||||
int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr);
|
||||
|
||||
int _sockfdUnicast;
|
||||
int _sockfdMulticast;
|
||||
|
||||
SensorNetAddress _multicastAddr;
|
||||
SensorNetAddress _unicastAddr;
|
||||
pollfd _pollFds[2];
|
||||
bool _disconReq;
|
||||
unsigned int _ttl;
|
||||
SensorNetAddress _multicastAddr;
|
||||
};
|
||||
|
||||
/*===========================================
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**************************************************************************************
|
||||
* 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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
@@ -20,8 +20,10 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
@@ -40,61 +42,57 @@ using namespace MQTTSNGW;
|
||||
============================================*/
|
||||
SensorNetAddress::SensorNetAddress()
|
||||
{
|
||||
_portNo = 0;
|
||||
memset((void *)&_IpAddr,0,sizeof(_IpAddr));
|
||||
memset((void*) &_IpAddr, 0, sizeof(_IpAddr));
|
||||
}
|
||||
|
||||
SensorNetAddress::~SensorNetAddress()
|
||||
{
|
||||
}
|
||||
|
||||
struct sockaddr_in6 *SensorNetAddress::getIpAddress(void)
|
||||
sockaddr_in6* SensorNetAddress::getIpAddress(void)
|
||||
{
|
||||
return &_IpAddr;
|
||||
return &_IpAddr;
|
||||
}
|
||||
|
||||
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));
|
||||
_portNo = port;
|
||||
memcpy((void*) &_IpAddr, IpAddr, sizeof(_IpAddr));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
int SensorNetAddress::setAddress(string* data)
|
||||
{
|
||||
size_t pos = data->find_last_of("]:");
|
||||
|
||||
size_t pos = data->find_last_of(":");
|
||||
if (pos != string::npos)
|
||||
{
|
||||
int portNo = 0;
|
||||
string port = data->substr(pos + 1);
|
||||
|
||||
if ( pos != string::npos)
|
||||
{
|
||||
int portNo = 0;
|
||||
string port = data->substr(pos + 1);
|
||||
if ((portNo = atoi(port.c_str())) > 0)
|
||||
{
|
||||
_IpAddr.sin6_port = htons(portNo);
|
||||
_IpAddr.sin6_family = AF_INET6;
|
||||
string ip = data->substr(1, pos - 2);
|
||||
const char *cstr = ip.c_str();
|
||||
|
||||
if ( ( portNo = atoi(port.c_str()) ) > 0 )
|
||||
{
|
||||
_portNo = htons(portNo);
|
||||
|
||||
string ip = data->substr(1,pos - 1);
|
||||
const char *cstr = ip.c_str();
|
||||
|
||||
if (inet_pton(AF_INET6, cstr, &(_IpAddr.sin6_addr)) == 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
_portNo = 0;
|
||||
memset((void *)&_IpAddr,0,sizeof(_IpAddr));
|
||||
return -1;
|
||||
if (inet_pton(AF_INET6, cstr, &(_IpAddr.sin6_addr)) == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
memset((void*) &_IpAddr, 0, sizeof(_IpAddr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,43 +102,42 @@ int SensorNetAddress::setAddress(string* data)
|
||||
*/
|
||||
int SensorNetAddress::setAddress(const char* data)
|
||||
{
|
||||
if ( inet_pton(AF_INET6, data, &(_IpAddr.sin6_addr)) == 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (inet_pton(AF_INET6, data, &(_IpAddr.sin6_addr)) == 1)
|
||||
{
|
||||
_IpAddr.sin6_family = AF_INET6;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
char* SensorNetAddress::getAddress(void)
|
||||
{
|
||||
inet_ntop(AF_INET6, &(_IpAddr.sin6_addr), _addrString, INET6_ADDRSTRLEN);
|
||||
return _addrString;
|
||||
inet_ntop(AF_INET6, &(_IpAddr.sin6_addr), _addrString, INET6_ADDRSTRLEN);
|
||||
return _addrString;
|
||||
}
|
||||
|
||||
bool SensorNetAddress::isMatch(SensorNetAddress* addr)
|
||||
{
|
||||
return (this->_portNo == addr->_portNo) && \
|
||||
(memcmp(this->_IpAddr.sin6_addr.s6_addr, addr->_IpAddr.sin6_addr.s6_addr, sizeof(this->_IpAddr.sin6_addr.s6_addr)) == 0);
|
||||
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);
|
||||
}
|
||||
|
||||
SensorNetAddress& SensorNetAddress::operator =(SensorNetAddress& addr)
|
||||
{
|
||||
this->_portNo = addr._portNo;
|
||||
memcpy(&this->_IpAddr.sin6_addr, &addr._IpAddr.sin6_addr, sizeof(this->_IpAddr.sin6_addr));
|
||||
return *this;
|
||||
memcpy(&this->_IpAddr, &addr._IpAddr, sizeof(this->_IpAddr));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
char* SensorNetAddress::sprint(char* buf)
|
||||
{
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &(_IpAddr.sin6_addr), ip, INET6_ADDRSTRLEN);
|
||||
sprintf( buf, "%s:", ip);
|
||||
sprintf( buf + strlen(buf), "%d", ntohs(_portNo));
|
||||
return buf;
|
||||
sprintf(buf, "[%s]:", getAddress());
|
||||
sprintf(buf + strlen(buf), "%d", ntohs(_IpAddr.sin6_port));
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*===========================================
|
||||
@@ -156,75 +153,74 @@ SensorNetwork::~SensorNetwork()
|
||||
|
||||
int SensorNetwork::unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendToAddr)
|
||||
{
|
||||
return UDPPort6::unicast(payload, payloadLength, sendToAddr);
|
||||
return UDPPort6::unicast(payload, payloadLength, sendToAddr);
|
||||
}
|
||||
|
||||
int SensorNetwork::broadcast(const uint8_t* payload, uint16_t payloadLength)
|
||||
{
|
||||
return UDPPort6::broadcast(payload, payloadLength);
|
||||
return UDPPort6::broadcast(payload, payloadLength);
|
||||
}
|
||||
|
||||
int SensorNetwork::read(uint8_t* buf, uint16_t bufLen)
|
||||
{
|
||||
return UDPPort6::recv(buf, bufLen, &_clientAddr);
|
||||
return UDPPort6::recv(buf, bufLen, &_clientAddr);
|
||||
}
|
||||
|
||||
void SensorNetwork::initialize(void)
|
||||
{
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
uint16_t unicastPortNo = 0;
|
||||
string ip;
|
||||
string broadcast;
|
||||
string interface;
|
||||
unsigned int hops = 1;
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
uint16_t unicastPortNo = 0;
|
||||
uint16_t multicastPortNo = 0;
|
||||
string ip;
|
||||
string multicast;
|
||||
string interface;
|
||||
uint32_t hops = 1;
|
||||
|
||||
if (theProcess->getParam("GatewayUDP6Bind", param) == 0)
|
||||
{
|
||||
ip = param;
|
||||
_description = "GatewayUDP6Bind: ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayUDP6Port", param) == 0)
|
||||
{
|
||||
unicastPortNo = atoi(param);
|
||||
_description += " Gateway Port: ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayUDP6Broadcast", param) == 0)
|
||||
{
|
||||
broadcast = param;
|
||||
_description += " Broadcast Address: ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayUDP6If", param) == 0)
|
||||
{
|
||||
interface = param;
|
||||
_description += " Interface: ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayUDP6Hops", param) == 0)
|
||||
{
|
||||
hops = atoi(param);
|
||||
_description += " Hops: ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastIPv6", param) == 0)
|
||||
{
|
||||
multicast = param;
|
||||
_description += "Multicast Address: [";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastIPv6PortNo", param) == 0)
|
||||
{
|
||||
multicastPortNo = atoi(param);
|
||||
_description += "]:";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("GatewayIPv6PortNo", param) == 0)
|
||||
{
|
||||
unicastPortNo = atoi(param);
|
||||
_description += ", Gateway Port:";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastIPv6If", param) == 0)
|
||||
{
|
||||
interface = param;
|
||||
_description += ", Interface: ";
|
||||
_description += param;
|
||||
}
|
||||
if (theProcess->getParam("MulticastHops", param) == 0)
|
||||
{
|
||||
hops = atoi(param);
|
||||
_description += ", Hops:";
|
||||
_description += param;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
if ( UDPPort6::open(ip.c_str(), unicastPortNo, broadcast.c_str(), interface.c_str(), hops) < 0 )
|
||||
{
|
||||
throw EXCEPTION("Can't open a UDP6", errno);
|
||||
}
|
||||
if (UDPPort6::open(unicastPortNo, multicastPortNo, multicast.c_str(), interface.c_str(), hops) < 0)
|
||||
{
|
||||
throw EXCEPTION("Can't open a UDP6", errno);
|
||||
}
|
||||
}
|
||||
|
||||
const char* SensorNetwork::getDescription(void)
|
||||
{
|
||||
return _description.c_str();
|
||||
return _description.c_str();
|
||||
}
|
||||
|
||||
SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||
{
|
||||
return &_clientAddr;
|
||||
return &_clientAddr;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
@@ -233,278 +229,241 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||
|
||||
UDPPort6::UDPPort6()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdUnicast = -1;
|
||||
_sockfdMulticast = -1;
|
||||
_disconReq = false;
|
||||
_hops = 0;
|
||||
}
|
||||
|
||||
UDPPort6::~UDPPort6()
|
||||
{
|
||||
close();
|
||||
close();
|
||||
}
|
||||
|
||||
void UDPPort6::close(void)
|
||||
{
|
||||
if (_sockfdUnicast > 0)
|
||||
{
|
||||
::close(_sockfdUnicast);
|
||||
_sockfdUnicast = -1;
|
||||
}
|
||||
if (_sockfdMulticast > 0)
|
||||
{
|
||||
::close(_sockfdMulticast);
|
||||
_sockfdMulticast = -1;
|
||||
}
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].fd > 0)
|
||||
{
|
||||
::close(_pollfds[i].fd);
|
||||
_pollfds[i].fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 errnu;
|
||||
const int reuse = 1;
|
||||
int optval = 0;
|
||||
int sock = 0;
|
||||
sockaddr_in6 addr6;
|
||||
uint32_t ifindex = 0;
|
||||
|
||||
if (uniPortNo == 0)
|
||||
{
|
||||
WRITELOG("error portNo undefined in UDPPort::open\n");
|
||||
return -1;
|
||||
}
|
||||
errno = 0;
|
||||
|
||||
if (uniPortNo == 0 || multiPortNo == 0)
|
||||
{
|
||||
D_NWSTACK("error portNo undefined in UDPPort6::open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_INET6; // use IPv6
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE; //use local IF address
|
||||
// Create a unicast socket
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
D_NWSTACK("UDP6::open - unicast socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
getaddrinfo(NULL, std::to_string(uniPortNo).c_str(), &hints, &res);
|
||||
_pollfds[0].fd = sock;
|
||||
_pollfds[0].events = POLLIN;
|
||||
|
||||
_sockfdMulticast = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if(_sockfdMulticast <0)
|
||||
{
|
||||
WRITELOG("UDP6::open - multicast: %s",strerror(_sockfdMulticast));
|
||||
return errno;
|
||||
}
|
||||
optval = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &optval, sizeof(optval));
|
||||
|
||||
//select the interface
|
||||
unsigned int ifindex;
|
||||
ifindex = if_nametoindex(interfaceName);
|
||||
errnu = setsockopt(_sockfdMulticast, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex,sizeof(ifindex));
|
||||
if(errnu <0)
|
||||
{
|
||||
WRITELOG("UDP6::open - limit IF: %s",strerror(errnu));
|
||||
return errnu;
|
||||
}
|
||||
optval = 1;
|
||||
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));
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(_interfaceName,interfaceName);
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops)) < 0)
|
||||
{
|
||||
D_NWSTACK("\033[0m\033[0;31m error %s IPV6_UNICAST_HOPS\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//restrict the socket to IPv6 only
|
||||
int on = 1;
|
||||
errnu = setsockopt(_sockfdMulticast, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on));
|
||||
if(errnu <0)
|
||||
{
|
||||
WRITELOG("UDP6::open - limit IPv6: %s",strerror(errnu));
|
||||
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;
|
||||
}
|
||||
|
||||
//if given, set a given device name to bind to
|
||||
if(strlen(interfaceName) > 0)
|
||||
{
|
||||
if (strlen(interfaceName) > 0)
|
||||
{
|
||||
ifindex = if_nametoindex(interfaceName);
|
||||
#ifdef __APPLE__
|
||||
int idx = if_nametoindex(interfaceName);
|
||||
setsockopt(_sockfdUnicast, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx));
|
||||
#else
|
||||
//socket option: bind to a given interface name
|
||||
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_BINDTODEVICE, interfaceName, strlen(interfaceName));
|
||||
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
|
||||
#else
|
||||
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interfaceName, strlen(interfaceName));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//socket option: reuse address
|
||||
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = htons(uniPortNo);
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
//finally: bind...
|
||||
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));
|
||||
return -1;
|
||||
}
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWSTACK("error can't bind unicast socket in UDPPort6::open: %s\n", strerror(errno));
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//if given, set a broadcast address; otherwise it will be ::
|
||||
if(strlen(broadcastAddr) > 0)
|
||||
{
|
||||
_grpAddr.setAddress(broadcastAddr);
|
||||
} else {
|
||||
_grpAddr.setAddress("::");
|
||||
}
|
||||
//everything went fine...
|
||||
freeaddrinfo(res);
|
||||
return 0;
|
||||
|
||||
// create a MULTICAST socket
|
||||
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
D_NWSTACK("UDP6::open - multicast: %s", strerror(errno));
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
_pollfds[1].fd = sock;
|
||||
_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;
|
||||
}
|
||||
|
||||
int UDPPort6::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr)
|
||||
{
|
||||
char destStr[INET6_ADDRSTRLEN+10];
|
||||
struct addrinfo hints, *res;
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_INET6; // use IPv6
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
sockaddr_in6 dest;
|
||||
memset(&dest, 0, sizeof(dest));
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = addr->getPortNo();
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) &addr->getIpAddress()->sin6_addr, sizeof(in6_addr));
|
||||
|
||||
int err = 0;
|
||||
int port = 0;
|
||||
string portStr;
|
||||
if(addr->getPortNo() != 0)
|
||||
{
|
||||
port = htons(addr->getPortNo());
|
||||
portStr = to_string(port);
|
||||
} else {
|
||||
port = _uniPortNo;
|
||||
portStr = to_string(port);
|
||||
}
|
||||
#ifdef DEBUG_NW
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
addr->sprint(addrBuf);
|
||||
D_NWSTACK("sendto %s\n", addrBuf);
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
WRITELOG("errno in UDPPort::unicast(sendto): %d, %s\n",status,strerror(errno));
|
||||
}
|
||||
|
||||
return status;
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWSTACK("%s in UDPPor6t::sendto\n", strerror(errno));
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int UDPPort6::broadcast(const uint8_t* buf, uint32_t length)
|
||||
{
|
||||
struct addrinfo hint,*info;
|
||||
int err;
|
||||
memset( &hint, 0, sizeof( hint ) );
|
||||
int err = unicast(buf, length, &_grpAddr);
|
||||
|
||||
hint.ai_family = AF_INET6;
|
||||
hint.ai_socktype = SOCK_DGRAM;
|
||||
hint.ai_protocol = 0;
|
||||
if (err < 0)
|
||||
{
|
||||
D_NWSTACK("UDP6::broadcast - sendto: %s", strerror(errno));
|
||||
return err;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
if(strlen(_interfaceName) != 0)
|
||||
{
|
||||
char destStr[80];
|
||||
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 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UDPPort6::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set recvfds;
|
||||
int rc = poll(_pollfds, 2, 2000); // Timeout 2secs
|
||||
if (rc == 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
sockaddr_in6 sender;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
sockaddr_in6 sender;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
int status = ::recvfrom(sockfd, buf, len, flags, (sockaddr*) &sender, &addrlen);
|
||||
int status = ::recvfrom(sockfd, buf, len, flags, (sockaddr*) &sender, &addrlen);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
WRITELOG("errno == %d in UDPPort::recvfrom: %s\n",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
addr->setAddress(&sender, (uint16_t)sender.sin6_port);
|
||||
//D_NWSTACK("recved from %s:%d length = %d\n", inet_ntoa(sender.sin_addr),ntohs(sender.sin_port), status);
|
||||
return status;
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWSTACK("errno in UDPPort6::recvfrom: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
addr->setAddress(&sender);
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
addr->sprint(addrBuf);
|
||||
D_NWSTACK("sendto %s length = %d\n", addrBuf, status);
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Benjamin Aigner - port to UDPv6, used by RFC7668 (6lowpan over Bluetooth LE)
|
||||
* Benjamin Aigner - port to UDPv6, used by RFC7668 (6lowpan over Bluetooth LE)
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
@@ -22,69 +22,59 @@
|
||||
#include "MQTTSNGWDefines.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <string>
|
||||
#include <poll.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
|
||||
#ifdef DEBUG_NWSTACK
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
/*===========================================
|
||||
Class SensorNetAddreess
|
||||
============================================*/
|
||||
class SensorNetAddress
|
||||
{
|
||||
public:
|
||||
SensorNetAddress();
|
||||
~SensorNetAddress();
|
||||
void setAddress(struct sockaddr_in6 *IpAddr, uint16_t port);
|
||||
int setAddress(string* data);
|
||||
int setAddress(const char* data);
|
||||
uint16_t getPortNo(void);
|
||||
struct sockaddr_in6 *getIpAddress(void);
|
||||
char* getAddress(void);
|
||||
bool isMatch(SensorNetAddress* addr);
|
||||
SensorNetAddress& operator =(SensorNetAddress& addr);
|
||||
char* sprint(char* buf);
|
||||
SensorNetAddress();
|
||||
~SensorNetAddress();
|
||||
void setAddress(sockaddr_in6 *IpAddr);
|
||||
int setAddress(string* data);
|
||||
int setAddress(const char* data);
|
||||
uint16_t getPortNo(void);
|
||||
sockaddr_in6* getIpAddress(void);
|
||||
char* getAddress(void);
|
||||
bool isMatch(SensorNetAddress* addr);
|
||||
SensorNetAddress& operator =(SensorNetAddress& addr);
|
||||
char* sprint(char* buf);
|
||||
private:
|
||||
uint16_t _portNo;
|
||||
char _addrString[INET6_ADDRSTRLEN+1];
|
||||
struct sockaddr_in6 _IpAddr;
|
||||
char _addrString[INET6_ADDRSTRLEN + 1];
|
||||
sockaddr_in6 _IpAddr;
|
||||
};
|
||||
|
||||
/*========================================
|
||||
Class UpdPort
|
||||
Class UpdPort6
|
||||
=======================================*/
|
||||
class UDPPort6
|
||||
{
|
||||
public:
|
||||
UDPPort6();
|
||||
virtual ~UDPPort6();
|
||||
UDPPort6();
|
||||
virtual ~UDPPort6();
|
||||
|
||||
int open(const char* ipAddress, uint16_t uniPortNo, const char* broadcastAddr, const char* interfaceName, unsigned int hops);
|
||||
void close(void);
|
||||
int unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* sendToAddr);
|
||||
int broadcast(const uint8_t* buf, uint32_t length);
|
||||
int recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr);
|
||||
int open(uint16_t uniPortNo, uint16_t multiPortNo, const char *broadcastAddr, const char *interfaceName, uint32_t hops);
|
||||
void close(void);
|
||||
int unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* sendToAddr);
|
||||
int broadcast(const uint8_t* buf, uint32_t length);
|
||||
int recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr);
|
||||
|
||||
private:
|
||||
void setNonBlocking(const bool);
|
||||
int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr);
|
||||
void setNonBlocking(const bool);
|
||||
int recvfrom(int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, SensorNetAddress* addr);
|
||||
|
||||
int _sockfdUnicast;
|
||||
int _sockfdMulticast;
|
||||
char _interfaceName[10];
|
||||
|
||||
SensorNetAddress _grpAddr;
|
||||
SensorNetAddress _clientAddr;
|
||||
uint16_t _uniPortNo;
|
||||
bool _disconReq;
|
||||
unsigned int _hops;
|
||||
pollfd _pollfds[2];
|
||||
SensorNetAddress _grpAddr;
|
||||
SensorNetAddress _clientAddr;
|
||||
bool _disconReq;
|
||||
uint32_t _hops;
|
||||
};
|
||||
|
||||
/*===========================================
|
||||
@@ -93,19 +83,19 @@ private:
|
||||
class SensorNetwork: public UDPPort6
|
||||
{
|
||||
public:
|
||||
SensorNetwork();
|
||||
~SensorNetwork();
|
||||
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);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendto);
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLength);
|
||||
int read(uint8_t* buf, uint16_t bufLen);
|
||||
void initialize(void);
|
||||
const char* getDescription(void);
|
||||
SensorNetAddress* getSenderAddress(void);
|
||||
|
||||
private:
|
||||
SensorNetAddress _clientAddr; // Sender's address. not gateway's one.
|
||||
string _description;
|
||||
SensorNetAddress _clientAddr; // Sender's address. not gateway's one.
|
||||
string _description;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,13 +25,6 @@ using namespace std;
|
||||
|
||||
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_RESPONSE 0x90
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "MQTTSNGWPacketHandleTask.h"
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
/*
|
||||
* Gateway Application
|
||||
*/
|
||||
|
||||
@@ -15,10 +15,15 @@ cmake .. -DSENSORNET=xbee
|
||||
make MQTT-SNGateway
|
||||
cmake .. -DSENSORNET=udp6
|
||||
make MQTT-SNGateway
|
||||
cmake .. -DSENSORNET=dtls
|
||||
make MQTT-SNGateway
|
||||
cmake .. -DSENSORNET=udp
|
||||
make MQTT-SNGateway
|
||||
cd ../MQTTSNGateway/GatewayTester
|
||||
make
|
||||
|
||||
make SENSORNET=UDP6
|
||||
make SENSORNET=DTLS
|
||||
make SENSORNET=DTLS6
|
||||
make SENSORNET=RFCOMM
|
||||
make SENSORNET=UDP
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user