mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2026-02-03 12:03:44 +01:00
540
.cproject
540
.cproject
@@ -1,352 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
|
||||
<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" 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.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="MQTTSNGateway/src/linux/loralink|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNGateway/src/linux/udp6|MQTTSNClient|MQTTSNGateway/src/MQTTSNGWProxy.cpp|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/src/linux/xbee|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src/tests|MQTTSNGateway/src/tests/mainTestProcessFramework.cpp|ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
|
||||
</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="MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNPacket/src|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNClient|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
|
||||
<entry excluding="udp6|xbee|loralink" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src/linux"/>
|
||||
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
<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"/>
|
||||
</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="GatewayTester|src/linux/udp6|src/linux/udp|src/linux/dtls/SensorNetSubTask.cpp|GatewayTester/samples/ClientSub|GatewayTester/samples/ClientPubQoS-1|GatewayTester/samples/ClientPub|src/linux/rfcomm|src/tests|src/linux/xbee|src/mainLogmonitor.cpp|src/linux/loralink" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway"/>
|
||||
<entry excluding="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||
<entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" 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="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Debug"/>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
</configuration>
|
||||
</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>
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -5,8 +5,15 @@
|
||||
*.pyc
|
||||
/doc/MQTTSNClient/
|
||||
/doc/MQTTSNPacket/
|
||||
/rbmutex.key
|
||||
/ringbuffer.key
|
||||
rbmutex.key
|
||||
ringbuffer.key
|
||||
/Release/
|
||||
/Debug/
|
||||
/core
|
||||
Build/
|
||||
*.a
|
||||
CMakeFiles/
|
||||
*.cmake
|
||||
CMakeCache.txt
|
||||
bin/
|
||||
/build.gateway/
|
||||
@@ -1,48 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<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>
|
||||
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
@@ -0,0 +1,77 @@
|
||||
eclipse.preferences.version=1
|
||||
fr.ac6.mcu.ide.source.checker.libnano.problem=Error
|
||||
fr.ac6.mcu.ide.source.checker.libnano.problem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Float formatting support\\")"}
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
|
||||
org.eclipse.cdt.qt.core.qtproblem=Warning
|
||||
org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>null}
|
||||
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_settings_version=1
|
||||
12
.travis.yml
12
.travis.yml
@@ -13,19 +13,11 @@ addons:
|
||||
- g++-4.8
|
||||
- cmake
|
||||
- cmake-data
|
||||
- bluez
|
||||
- libbluetooth-dev
|
||||
|
||||
script:
|
||||
- ./travis-build.sh
|
||||
|
||||
- cd MQTTSNGateway
|
||||
- make SENSORNET="xbee"
|
||||
- make SENSORNET="udp"
|
||||
- make SENSORNET="udp6"
|
||||
|
||||
- make test
|
||||
|
||||
- cd GatewayTester
|
||||
- make
|
||||
|
||||
notifications:
|
||||
emails:
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# Ian Craggs - initial version
|
||||
#*******************************************************************************/
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
|
||||
PROJECT("paho-mqttsn" CXX)
|
||||
MESSAGE(STATUS "CMake version: " ${CMAKE_VERSION})
|
||||
MESSAGE(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME})
|
||||
@@ -39,3 +39,4 @@ INCLUDE(CPack)
|
||||
ENABLE_TESTING()
|
||||
|
||||
ADD_SUBDIRECTORY(MQTTSNPacket)
|
||||
ADD_SUBDIRECTORY(MQTTSNGateway)
|
||||
16
MQTTSNGateway/CMakeLists.txt
Normal file
16
MQTTSNGateway/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2022 a1lu
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# Contributors:
|
||||
# a1lu - initial version
|
||||
#*******************************************************************************/
|
||||
ADD_SUBDIRECTORY(src)
|
||||
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
Binary file not shown.
@@ -20,6 +20,10 @@ CPPSRCS := \
|
||||
$(SUBDIR)/LGwProxy.cpp \
|
||||
$(SUBDIR)/LMqttsnClient.cpp \
|
||||
$(SUBDIR)/LNetworkUdp.cpp \
|
||||
$(SUBDIR)/LNetworkUdp6.cpp \
|
||||
$(SUBDIR)/LNetworkRfcomm.cpp \
|
||||
$(SUBDIR)/LNetworkDtls.cpp \
|
||||
$(SUBDIR)/LNetworkDtls6.cpp \
|
||||
$(SUBDIR)/LPublishManager.cpp \
|
||||
$(SUBDIR)/LRegisterManager.cpp \
|
||||
$(SUBDIR)/LSubscribeManager.cpp \
|
||||
@@ -36,12 +40,14 @@ $(SUBDIR)/Util.cpp \
|
||||
CXX := g++
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDES += -I$(SUBDIR)
|
||||
DEFS :=
|
||||
LIBS +=
|
||||
INCLUDES += -I$(SUBDIR) -I/usr/local/opt/openssl/include
|
||||
DEF1 :=
|
||||
DEF2 :=
|
||||
DEFS := -D$(SN) $(DEF1) $(DEF2)
|
||||
LIBS += -L/usr/local/lib -L/usr/local/opt/openssl/lib
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD :=
|
||||
LDADD := -lssl -lcrypto $(LDADDBLT)
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGTEST)
|
||||
@@ -75,23 +81,23 @@ $(PROGQOS): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/$(QOSAPPL).o
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
@@ -1,119 +1,117 @@
|
||||
###Gateway Test Program.
|
||||
# Gateway Test Program.
|
||||
**sample/mainTest.cpp** is a Test sample coading.
|
||||
Each test is described as one function. test1(), test2()...
|
||||
````
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*
|
||||
* you can use 4 commands in Test functions
|
||||
*
|
||||
* 1) PUBLISH(const char* topicName,
|
||||
* uint8_t* payload,
|
||||
* uint16_t len,
|
||||
* uint8_t qos,
|
||||
* bool retain = false);
|
||||
*
|
||||
* 2) SUBSCRIBE(const char* topicName,
|
||||
* TopicCallback onPublish,
|
||||
* uint8_t qos);
|
||||
*
|
||||
* 3) UNSUBSCRIBE(const char* topicName);
|
||||
*
|
||||
* 4) DISCONNECT(uint16_t sleepInSecs);
|
||||
*
|
||||
*------------------------------------------------------*/
|
||||
|
||||
```
|
||||
void test1(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "ESP8266-08b133 ");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), qos);
|
||||
char payload[300];
|
||||
sprintf(payload, "ESP8266-08b133 ");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), qos);
|
||||
}
|
||||
|
||||
void test2(void)
|
||||
{
|
||||
uint8_t qos = 1;
|
||||
SUBSCRIBE(topic2, on_publish02, qos);
|
||||
uint8_t qos = 1;
|
||||
SUBSCRIBE(topic2, on_publish02, qos);
|
||||
}
|
||||
````
|
||||
**TEST_LIST** is a test senario. Test functions are executed one by one.
|
||||
````
|
||||
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* MQTT-SN GATEWAY TEST CLIENT
|
||||
*
|
||||
* Supported functions.
|
||||
*
|
||||
* void PUBLISH ( const char* topicName, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void PUBLISH ( uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void SUBSCRIBE ( const char* topicName, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void UNSUBSCRIBE ( const char* topicName );
|
||||
*
|
||||
* void UNSUBSCRIBE ( uint16_t topicId );
|
||||
*
|
||||
* void DISCONNECT ( uint16_t sleepInSecs );
|
||||
*
|
||||
* void CONNECT ( void );
|
||||
*
|
||||
* void DISPLAY( format, .....); <== instead of printf()
|
||||
*--------------------------------------------------------------------------
|
||||
|
||||
```
|
||||
**TEST_LIST** is a test senario. Test functions are executed interactively.
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* A List of Test Tasks
|
||||
*------------------------------------------------------*/
|
||||
|
||||
TEST_LIST = {// e.g. TEST( Label, Test),
|
||||
TEST("Publish topic1", test1),
|
||||
TEST("Subscribe topic2", test2),
|
||||
TEST("Publish topic2", test3),
|
||||
TEST("Unsubscribe topic2", test4),
|
||||
TEST("Publish topic2", test3),
|
||||
TEST("Disconnect", test5),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
````
|
||||
TEST("Publish topic1", test1),
|
||||
TEST("Subscribe topic2", test2),
|
||||
TEST("Publish topic2", test3),
|
||||
TEST("Unsubscribe topic2", test4),
|
||||
TEST("Publish topic2", test3),
|
||||
TEST("Disconnect", test5),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### **step1. Build **
|
||||
````
|
||||
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
**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
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## How to Build
|
||||
```
|
||||
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.
|
||||
|
||||
|
||||
### **step2. Execute Gateway Tester.**
|
||||
|
||||
````
|
||||
$ cd ../../..
|
||||
$ ./MQTT-SNGatewayTester
|
||||
## Execute Gateway Tester
|
||||
```
|
||||
$ ./Build/MQTT-SNGatewayTester
|
||||
|
||||
***************************************************************************
|
||||
* MQTT-SN Gateway Tester
|
||||
* MQTT-SN Gateway Tester DTLS
|
||||
* Part of Project Paho in Eclipse
|
||||
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
|
||||
*
|
||||
* Author : Tomoaki YAMAGUCHI
|
||||
* Version: 0.0.0
|
||||
* Version: 2.0.0
|
||||
***************************************************************************
|
||||
|
||||
Attempting to Connect the Broker.....
|
||||
Execute "Step0:Connect" ? ( y/n ) :
|
||||
|
||||
sendto 225.1.1.1 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.5 :1883 03 01 00
|
||||
sendto 225.1.1.1 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.5 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.17 :10000 03 02 01
|
||||
sendto 192.168.11.17 :10000 13 04 0c 01 03 84 47 61 74 65 77 61 79 54 65 73 74 65 72
|
||||
|
||||
recved 192.168.11.17 :10000 02 06
|
||||
sendto 192.168.11.17 :10000 0c 07 00 77 69 6c 6c 54 6f 70 69 63
|
||||
|
||||
recved 192.168.11.17 :10000 02 08
|
||||
sendto 192.168.11.17 :10000 0d 09 77 69 6c 6c 4d 65 73 73 61 67 65
|
||||
|
||||
recved 192.168.11.17 :10000 03 05 00
|
||||
|
||||
|
||||
Connected to the Broker
|
||||
|
||||
Attempting OnConnect.....
|
||||
sendto 192.168.11.17 :10000 13 12 20 00 01 74 79 34 74 77 2f 63 6c 69 65 6e 74 49 64
|
||||
|
||||
recved 192.168.11.17 :10000 08 13 20 00 01 00 01 00
|
||||
|
||||
|
||||
SUBSCRIBE complete. ty4tw/clientId
|
||||
|
||||
OnConnect complete
|
||||
Test Ready.
|
||||
|
||||
Execute Publish topic1 Test ? ( Y/N ) :
|
||||
|
||||
````
|
||||
```
|
||||
|
||||
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEF1="DEF1=${2}"
|
||||
DEF2="DEF2=${3}"
|
||||
|
||||
if [ $1 == "udp" ] ; then
|
||||
make SN=UDP $DEF1 $DEF2
|
||||
elif [ $1 == "udp6" ] ; then
|
||||
make SN=UDP6 $DEF1 $DEF2
|
||||
elif [ $1 == "rfcomm" ] ; then
|
||||
export LDADDBLT=-lbluetooth
|
||||
make SN=RFCOMM $DEF1 $DEF2
|
||||
elif [ $1 == "dtls" ] ; then
|
||||
make SN=DTLS $DEF1 $DEF2
|
||||
elif [ $1 == "dtls6" ] ; then
|
||||
make SN=DTLS6 $DEF1 $DEF2
|
||||
elif [ $1 == "clean" ] ; then
|
||||
make clean
|
||||
else
|
||||
echo "Usage: build.sh [ udp | udp6 | rfcomm | dtls | dtls6 | clean]"
|
||||
fi
|
||||
|
||||
|
||||
@@ -51,12 +51,29 @@ 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 = { "ClientPUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
@@ -117,7 +134,7 @@ void publishTopic57(void)
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic57\" \n");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos);
|
||||
PUBLISH(topic57, (uint8_t* )payload, strlen(payload), qos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,12 +51,29 @@ 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 = { "QoS-1_Client01", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
|
||||
@@ -51,12 +51,29 @@ 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 = { "ClientSUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
|
||||
@@ -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,27 +49,43 @@ extern LMqttsnClient* theClient;
|
||||
extern LScreen* theScreen;
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
* UDP,DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"GatewayTestClient", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6, DTLS6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
*------------------------------------------------------*/
|
||||
MQTTSNCONF = {
|
||||
60, //KeepAlive [seconds]
|
||||
true, //Clean session
|
||||
300, //Sleep duration [seconds]
|
||||
"", //WillTopic
|
||||
"", //WillMessage
|
||||
0, //WillQos
|
||||
false //WillRetain
|
||||
};
|
||||
MQTTSNCONF = { 60, //KeepAlive [seconds]
|
||||
true, //Clean session
|
||||
300, //Sleep duration [seconds]
|
||||
"", //WillTopic
|
||||
"", //WillMessage
|
||||
0, //WillQos
|
||||
false //WillRetain
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Define Topics
|
||||
@@ -78,37 +94,45 @@ const char* topic1 = "ty4tw/topic1";
|
||||
const char* topic2 = "ty4tw/topic2";
|
||||
const char* topic3 = "ty4tw/topic3";
|
||||
const char* topic4 = "ty4tw/topic4";
|
||||
const char* topic40 = "ty4tw/#";
|
||||
const char* topic51 = "ty4tw/topic5/1";
|
||||
const char* topic52 = "ty4tw/topic5/2";
|
||||
const char* topic53 = "ty4tw/topic5/3";
|
||||
const char* topic50 = "ty4tw/topic5/+";
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Callback routines for Subscribed Topics
|
||||
*------------------------------------------------------*/
|
||||
int on_Topic01(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nTopic1 recv.\n");
|
||||
char c = pload[ploadlen-1];
|
||||
pload[ploadlen-1]= 0; // set null terminator
|
||||
DISPLAY("Payload -->%s%c<--\n\n",pload, c);
|
||||
char c = pload[ploadlen - 1];
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s%c<--\n\n", pload, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_Topic02(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nTopic2 recv.\n");
|
||||
pload[ploadlen-1]= 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n",pload);
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n", pload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_Topic03(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nNew callback recv Topic3\n");
|
||||
pload[ploadlen-1]= 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n",pload);
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n", pload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_TopicWildcard(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nNew callback recv TopicWildcard\n");
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n", pload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -116,40 +140,51 @@ int on_Topic03(uint8_t* pload, uint16_t ploadlen)
|
||||
* A Link list of Callback routines and Topics
|
||||
*------------------------------------------------------*/
|
||||
|
||||
SUBSCRIBE_LIST = {// e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
|
||||
END_OF_SUBSCRIBE_LIST
|
||||
};
|
||||
|
||||
SUBSCRIBE_LIST =
|
||||
{ // e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
|
||||
END_OF_SUBSCRIBE_LIST
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*------------------------------------------------------*/
|
||||
void subscribePredefTopic1(void)
|
||||
{
|
||||
SUBSCRIBE(1, on_Topic03, QoS1);
|
||||
SUBSCRIBE_PREDEF(1, on_Topic03, QoS1);
|
||||
}
|
||||
|
||||
void publishTopic1(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/Topic1\" \n");
|
||||
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), QoS0);
|
||||
}
|
||||
|
||||
void subscribeTopic10(void)
|
||||
{
|
||||
SUBSCRIBE(10, on_Topic02, QoS1);
|
||||
sprintf(payload, "publish \"ty4tw/topic1\" \n");
|
||||
PUBLISH(topic1, (uint8_t* )payload, strlen(payload), QoS0);
|
||||
}
|
||||
|
||||
void publishTopic2(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic2\" \n");
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), QoS1);
|
||||
PUBLISH(topic2, (uint8_t* )payload, strlen(payload), QoS1);
|
||||
}
|
||||
|
||||
void publishTopic4(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic40\" \n");
|
||||
PUBLISH(topic4, (uint8_t* )payload, strlen(payload), QoS1);
|
||||
}
|
||||
|
||||
void subscribeTopic10(void)
|
||||
{
|
||||
SUBSCRIBE_PREDEF(10, on_Topic02, QoS1);
|
||||
}
|
||||
|
||||
void subscribeWildcardTopic(void)
|
||||
{
|
||||
SUBSCRIBE(topic50, on_TopicWildcard, QoS1);
|
||||
}
|
||||
|
||||
|
||||
void unsubscribe(void)
|
||||
@@ -167,7 +202,7 @@ void test3(void)
|
||||
char payload[300];
|
||||
sprintf(payload, "TEST3 ");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos);
|
||||
PUBLISH(topic2, (uint8_t* )payload, strlen(payload), qos);
|
||||
}
|
||||
|
||||
void disconnect(void)
|
||||
@@ -180,48 +215,76 @@ void asleep(void)
|
||||
DISCONNECT(theMqcon.sleepDuration);
|
||||
}
|
||||
|
||||
void onconnect(void)
|
||||
{
|
||||
ONCONNECT();
|
||||
}
|
||||
|
||||
void connect(void)
|
||||
{
|
||||
CONNECT();
|
||||
}
|
||||
|
||||
void DisableAutoPingreq(void)
|
||||
{
|
||||
SetAutoPingReqMode(false);
|
||||
}
|
||||
|
||||
void CleanSessionOff(void)
|
||||
{
|
||||
SetCleanSession(false);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------
|
||||
* A List of Test functions is valid in case of
|
||||
* line 23 of LMqttsnClientApp.h is commented out.
|
||||
* //#define CLIENT_MODE
|
||||
*------------------------------------------------------*/
|
||||
|
||||
TEST_LIST = {// e.g. TEST( Label, Test),
|
||||
TEST("Step0:Subscribe predef topic1", subscribePredefTopic1),
|
||||
TEST("Step1:Publish topic1", publishTopic1),
|
||||
TEST("Step2:Publish topic2", publishTopic2),
|
||||
TEST("Step3:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||
TEST("Step4:Publish topic2", publishTopic2),
|
||||
TEST("Step5:Unsubscribe topic2", unsubscribe),
|
||||
TEST("Step6:Publish topic2", publishTopic2),
|
||||
TEST("Step7:subscribe again", subscribechangeCallback),
|
||||
TEST("Step8:Publish topic2", publishTopic2),
|
||||
TEST("Step9:Sleep ", asleep),
|
||||
TEST("Step10:Publish topic1", publishTopic1),
|
||||
TEST("Step11:Disconnect", disconnect),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
TEST_LIST =
|
||||
{ // e.g. TEST( Label, Test),
|
||||
TEST("Step0:Connect", connect),
|
||||
TEST("Step1:Subscribe list", onconnect),
|
||||
TEST("Step2:Subscribe predef topic1", subscribePredefTopic1),
|
||||
TEST("Step3:Publish topic1", publishTopic1),
|
||||
TEST("Step4:Publish topic2", publishTopic2),
|
||||
TEST("Step5:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||
TEST("Step6:Publish topic2", publishTopic2),
|
||||
TEST("Step7:Unsubscribe topic2", unsubscribe),
|
||||
TEST("Step8:Publish topic2", publishTopic2),
|
||||
TEST("Step9:subscribe again", subscribechangeCallback),
|
||||
TEST("Step10:Publish topic2", publishTopic2),
|
||||
|
||||
TEST("Step11:Sleep ", asleep),
|
||||
TEST("Step12:Publish topic1", publishTopic1),
|
||||
TEST("Step13:Disconnect", disconnect),
|
||||
TEST("Step14:Publish topic2", publishTopic1),
|
||||
TEST("Step15:Connect", connect),
|
||||
TEST("Step16:Publish topic2", publishTopic2),
|
||||
TEST("Step17:Auto Pingreq mode off", DisableAutoPingreq),
|
||||
TEST("Step18:Publish topic2", publishTopic1),
|
||||
TEST("Step19:Disconnect", disconnect),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* List of tasks is valid in case of line23 of
|
||||
* LMqttsnClientApp.h is uncommented.
|
||||
* #define CLIENT_MODE
|
||||
*------------------------------------------------------*/
|
||||
TASK_LIST = {// e.g. TASK( task, executing duration in second),
|
||||
TASK(publishTopic1, 4), // publishTopic1() is executed every 4 seconds
|
||||
TASK(publishTopic2, 7), // publishTopic2() is executed every 7 seconds
|
||||
END_OF_TASK_LIST
|
||||
};
|
||||
|
||||
TASK_LIST =
|
||||
{ // e.g. TASK( task, executing duration in second),
|
||||
TASK(publishTopic1, 4),// publishTopic1() is executed every 4 seconds
|
||||
TASK(publishTopic2, 7),// publishTopic2() is executed every 7 seconds
|
||||
END_OF_TASK_LIST
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Initialize function
|
||||
*------------------------------------------------------*/
|
||||
void setup(void)
|
||||
{
|
||||
SetForwarderMode(false);
|
||||
SetForwarderMode(false);
|
||||
}
|
||||
|
||||
|
||||
/***************** END OF PROGRAM ********************/
|
||||
|
||||
@@ -57,6 +57,8 @@ LGwProxy::LGwProxy()
|
||||
_initialized = 0;
|
||||
_isForwarderMode = false;
|
||||
_isQoSMinus1Mode = false;
|
||||
_isPingReqMode = true;
|
||||
_isAutoConnectMode = true;
|
||||
}
|
||||
|
||||
LGwProxy::~LGwProxy()
|
||||
@@ -64,16 +66,20 @@ LGwProxy::~LGwProxy()
|
||||
_topicTbl.clearTopic();
|
||||
}
|
||||
|
||||
void LGwProxy::initialize(LUdpConfig netconf, LMqttsnConfig mqconf)
|
||||
void LGwProxy::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
|
||||
{
|
||||
_network.initialize(netconf);
|
||||
_clientId = netconf.clientId;
|
||||
_willTopic = mqconf.willTopic;
|
||||
_willMsg = mqconf.willMsg;
|
||||
_qosWill = mqconf.willQos;
|
||||
_retainWill = mqconf.willRetain;
|
||||
_cleanSession = mqconf.cleanSession;
|
||||
_tkeepAlive = mqconf.keepAlive;
|
||||
if (_network.initialize(netconf) == false)
|
||||
{
|
||||
DISPLAY("Can't open SensorNetwork\n");
|
||||
exit(-1);
|
||||
}
|
||||
_clientId = netconf->clientId;
|
||||
_willTopic = mqconf->willTopic;
|
||||
_willMsg = mqconf->willMsg;
|
||||
_qosWill = mqconf->willQos;
|
||||
_retainWill = mqconf->willRetain;
|
||||
_cleanSession = mqconf->cleanSession;
|
||||
_tkeepAlive = mqconf->keepAlive;
|
||||
_initialized = 1;
|
||||
}
|
||||
|
||||
@@ -85,6 +91,12 @@ void LGwProxy::connect()
|
||||
{
|
||||
pos = _msg;
|
||||
|
||||
if (!_network.isBroadcastable() && _status == GW_LOST)
|
||||
{
|
||||
_status = GW_CONNECTING;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_status == GW_LOST)
|
||||
{
|
||||
|
||||
@@ -188,7 +200,24 @@ int LGwProxy::getConnectResponce(void)
|
||||
{
|
||||
_network.setGwAddress();
|
||||
_gwId = _mqttsnMsg[1];
|
||||
|
||||
#if defined(DTLS) || defined(DTLS6)
|
||||
for (int i = 0; i < MQTTSN_RETRY_COUNT; i++)
|
||||
{
|
||||
if (_network.sslConnect() > 0)
|
||||
{
|
||||
_status = GW_CONNECTING;
|
||||
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection established.\033[0m\033[0;37m\n\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection failed.\033[0m\033[0;37m\n\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
_status = GW_CONNECTING;
|
||||
#endif
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
|
||||
{
|
||||
@@ -231,9 +260,12 @@ int LGwProxy::getConnectResponce(void)
|
||||
|
||||
void LGwProxy::reconnect(void)
|
||||
{
|
||||
D_MQTTLOG("...Gateway reconnect\r\n");
|
||||
_status = GW_DISCONNECTED;
|
||||
connect();
|
||||
if (_isAutoConnectMode)
|
||||
{
|
||||
D_MQTTLOG("...Gateway reconnect\r\n");
|
||||
_status = GW_DISCONNECTED;
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
void LGwProxy::disconnect(uint16_t secs)
|
||||
@@ -395,7 +427,7 @@ int LGwProxy::getMessage(void)
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_DISCONNECT)
|
||||
{
|
||||
_status = GW_LOST;
|
||||
_status = GW_DISCONNECTED;
|
||||
_gwAliveTimer.stop();
|
||||
_keepAliveTimer.stop();
|
||||
}
|
||||
@@ -586,7 +618,7 @@ uint16_t LGwProxy::getNextMsgId(void)
|
||||
|
||||
void LGwProxy::checkPingReq(void)
|
||||
{
|
||||
if ( _isQoSMinus1Mode )
|
||||
if (_isQoSMinus1Mode || _isPingReqMode == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -671,3 +703,23 @@ void LGwProxy::setQoSMinus1Mode(bool valid)
|
||||
{
|
||||
_isQoSMinus1Mode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setPingReqMode(bool valid)
|
||||
{
|
||||
_isPingReqMode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setAutoConnectMode(bool valid)
|
||||
{
|
||||
_isAutoConnectMode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setSessionMode(bool valid)
|
||||
{
|
||||
_cleanSession = valid;
|
||||
}
|
||||
|
||||
uint8_t LGwProxy::getStatus(void)
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LRegisterManager.h"
|
||||
#include "LTimer.h"
|
||||
#include "LTopicTable.h"
|
||||
@@ -42,6 +46,7 @@ using namespace std;
|
||||
#define GW_SLEEPING 10
|
||||
#define GW_DISCONNECTED 11
|
||||
#define GW_SLEPT 12
|
||||
#define SSL_CONNECTING 13
|
||||
|
||||
#define GW_WAIT_PINGRESP 1
|
||||
|
||||
@@ -54,7 +59,7 @@ public:
|
||||
LGwProxy();
|
||||
~LGwProxy();
|
||||
|
||||
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf);
|
||||
void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
|
||||
void connect(void);
|
||||
void disconnect(uint16_t sec = 0);
|
||||
int getMessage(void);
|
||||
@@ -67,6 +72,9 @@ public:
|
||||
void setAdvertiseDuration(uint16_t duration);
|
||||
void setForwarderMode(bool valid);
|
||||
void setQoSMinus1Mode(bool valid);
|
||||
void setPingReqMode(bool valid);
|
||||
void setAutoConnectMode(bool valid);
|
||||
void setSessionMode(bool valid);
|
||||
void reconnect(void);
|
||||
int writeMsg(const uint8_t* msg);
|
||||
void setPingReqTimer(void);
|
||||
@@ -74,6 +82,7 @@ public:
|
||||
LTopicTable* getTopicTable(void);
|
||||
LRegisterManager* getRegisterManager(void);
|
||||
const char* getClientId(void);
|
||||
uint8_t getStatus(void);
|
||||
private:
|
||||
int readMsg(void);
|
||||
void writeGwMsg(void);
|
||||
@@ -109,8 +118,10 @@ private:
|
||||
LTimer _keepAliveTimer;
|
||||
uint16_t _tSleep;
|
||||
uint16_t _tWake;
|
||||
bool _isForwarderMode;
|
||||
bool _isQoSMinus1Mode;
|
||||
bool _isForwarderMode;
|
||||
bool _isQoSMinus1Mode;
|
||||
bool _isPingReqMode;
|
||||
bool _isAutoConnectMode;
|
||||
char _msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ extern TaskList theTaskList[];
|
||||
extern TestList theTestList[];
|
||||
extern OnPublishList theOnPublishList[];
|
||||
extern MQTTSNCONF;
|
||||
extern UDPCONF;
|
||||
extern SENSORNET_CONFIG_t theNetcon;
|
||||
extern void setup(void);
|
||||
|
||||
/*=====================================
|
||||
@@ -50,7 +50,20 @@ int main(int argc, char** argv)
|
||||
#ifndef CLIENT_MODE
|
||||
char c = 0;
|
||||
printf("\n%s", PAHO_COPYRIGHT4);
|
||||
printf("\n%s\n", PAHO_COPYRIGHT0);
|
||||
printf("\n%s", PAHO_COPYRIGHT0);
|
||||
#if defined(UDP)
|
||||
printf("UDP ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(UDP6)
|
||||
printf("UDP6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(DTLS)
|
||||
printf("DTLS ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(DTLS6)
|
||||
printf("DTLS6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(RFCOMM)
|
||||
printf("RFCOMM ClientId:%s channel:%d\n", theNetcon.clientId, theNetcon.channel);
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
printf("%s\n", PAHO_COPYRIGHT1);
|
||||
printf("%s\n", PAHO_COPYRIGHT2);
|
||||
printf(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
@@ -77,11 +90,13 @@ int main(int argc, char** argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
theClient->setAutoConnectMode(false);
|
||||
theClient->getPublishManager()->setAutoConnectMode(false);
|
||||
#endif
|
||||
|
||||
setup();
|
||||
theClient->addTask(theClientMode);
|
||||
theClient->initialize( theNetcon, theMqcon);
|
||||
theClient->initialize( &theNetcon, &theMqcon);
|
||||
do
|
||||
{
|
||||
theClient->run();
|
||||
@@ -98,7 +113,7 @@ int main(int argc, char** argv)
|
||||
======================================*/
|
||||
LMqttsnClient::LMqttsnClient()
|
||||
{
|
||||
|
||||
_isAutoConnect = true;
|
||||
}
|
||||
|
||||
LMqttsnClient::~LMqttsnClient()
|
||||
@@ -106,10 +121,10 @@ LMqttsnClient::~LMqttsnClient()
|
||||
|
||||
}
|
||||
|
||||
void LMqttsnClient::initialize(LUdpConfig netconf, LMqttsnConfig mqconf)
|
||||
void LMqttsnClient::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
|
||||
{
|
||||
_gwProxy.initialize(netconf, mqconf);
|
||||
setSleepDuration(mqconf.sleepDuration);
|
||||
setSleepDuration(mqconf->sleepDuration);
|
||||
}
|
||||
|
||||
void LMqttsnClient::addTask(bool clientMode)
|
||||
@@ -183,9 +198,10 @@ void LMqttsnClient::subscribe(const char* topicName, TopicCallback onPublish, ui
|
||||
_subMgr.subscribe(topicName, onPublish, qos);
|
||||
}
|
||||
|
||||
void LMqttsnClient::subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
void LMqttsnClient::subscribePredefinedId(uint16_t topicId, TopicCallback onPublish,
|
||||
uint8_t qos)
|
||||
{
|
||||
_subMgr.subscribe(topicId, onPublish, qos);
|
||||
_subMgr.subscribePredefinedId(topicId, onPublish, qos);
|
||||
}
|
||||
|
||||
void LMqttsnClient::unsubscribe(const char* topicName)
|
||||
@@ -205,10 +221,20 @@ void LMqttsnClient::disconnect(uint16_t sleepInSecs)
|
||||
|
||||
void LMqttsnClient::run()
|
||||
{
|
||||
_gwProxy.connect();
|
||||
if (_isAutoConnect)
|
||||
{
|
||||
_gwProxy.connect();
|
||||
}
|
||||
_taskMgr.run();
|
||||
}
|
||||
|
||||
void LMqttsnClient::setAutoConnectMode(uint8_t flg)
|
||||
{
|
||||
_isAutoConnect = flg;
|
||||
_pubMgr.setAutoConnectMode(flg);
|
||||
_gwProxy.setAutoConnectMode(flg);
|
||||
}
|
||||
|
||||
void LMqttsnClient::setSleepMode(uint32_t duration)
|
||||
{
|
||||
// ToDo: set WDT and sleep mode
|
||||
@@ -227,7 +253,10 @@ void LMqttsnClient::setSleepDuration(uint32_t duration)
|
||||
|
||||
void LMqttsnClient::onConnect(void)
|
||||
{
|
||||
if (_isAutoConnect)
|
||||
{
|
||||
_subMgr.onConnect();
|
||||
}
|
||||
}
|
||||
|
||||
const char* LMqttsnClient::getClientId(void)
|
||||
|
||||
@@ -54,15 +54,16 @@ public:
|
||||
void publish(uint16_t topicId, Payload* payload, uint8_t qos, bool retain = false);
|
||||
void publish(uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false);
|
||||
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void unsubscribe(const char* topicName);
|
||||
void unsubscribe(const uint16_t topicId);
|
||||
void disconnect(uint16_t sleepInSecs);
|
||||
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf);
|
||||
void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
|
||||
void run(void);
|
||||
void addTask(bool test);
|
||||
void setSleepDuration(uint32_t duration);
|
||||
void setSleepMode(uint32_t duration);
|
||||
void setAutoConnectMode(uint8_t flg);
|
||||
void sleep(void);
|
||||
const char* getClientId(void);
|
||||
uint16_t getTopicId(const char* topicName);
|
||||
@@ -78,6 +79,7 @@ private:
|
||||
LSubscribeManager _subMgr;
|
||||
LGwProxy _gwProxy;
|
||||
uint32_t _sleepDuration;
|
||||
uint8_t _isAutoConnect;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
#ifndef MQTTSNCLIENTAPP_H_
|
||||
#define MQTTSNCLIENTAPP_H_
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
|
||||
/*======================================
|
||||
* Debug Flag
|
||||
======================================*/
|
||||
//#define DEBUG_NW
|
||||
//#define DEBUG_MQTTSN
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
|
||||
/****************************************
|
||||
MQTT-SN Parameters
|
||||
*****************************************/
|
||||
@@ -55,7 +55,8 @@ typedef signed int int32_t;
|
||||
Application config structures
|
||||
*****************************************/
|
||||
|
||||
struct LMqttsnConfig{
|
||||
struct LMqttsnConfig
|
||||
{
|
||||
uint16_t keepAlive;
|
||||
bool cleanSession;
|
||||
uint32_t sleepDuration;
|
||||
@@ -65,13 +66,30 @@ struct LMqttsnConfig{
|
||||
bool willRetain;
|
||||
};
|
||||
|
||||
struct LUdpConfig{
|
||||
struct LUdpConfig
|
||||
{
|
||||
const char* clientId;
|
||||
uint8_t ipAddress[4];
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LUdp6Config
|
||||
{
|
||||
const char* clientId;
|
||||
const char* ipAddress;
|
||||
const char *interface;
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LRfcommConfig
|
||||
{
|
||||
const char* clientId;
|
||||
const char* gwAddress;
|
||||
uint8_t channel;
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -85,13 +103,50 @@ typedef enum
|
||||
MACROs for Application
|
||||
=======================================*/
|
||||
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig
|
||||
#define NETWORK_CONFIG UdpConfig theNetworkConfig
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
#if defined(UDP)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(UDP6)
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
|
||||
#elif defined(RFCOMM)
|
||||
#define RFCOMMCONF LRfcommConfig theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define SENSORNET_CONFIG_t LRfcommConfig
|
||||
|
||||
#elif defined(DTLS)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(DTLS6)
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
#else
|
||||
#error "UDP, UDP6, DTLS, DTLS6 or RFCOMM is not defined in LMqttsnClientApp.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
|
||||
#define PUBLISH(...) theClient->publish(__VA_ARGS__)
|
||||
#define SUBSCRIBE(...) theClient->subscribe(__VA_ARGS__)
|
||||
#define SUBSCRIBE_PREDEF(...) theClient->subscribePredefinedId(__VA_ARGS__)
|
||||
#define UNSUBSCRIBE(...) theClient->unsubscribe(__VA_ARGS__)
|
||||
#define DISCONNECT(...) theClient->disconnect(__VA_ARGS__)
|
||||
#define ONCONNECT() theClient->getSubscribeManager()->onConnect()
|
||||
|
||||
#define TASK_LIST TaskList theTaskList[]
|
||||
#define TASK(...) {__VA_ARGS__, 0, 0}
|
||||
@@ -102,11 +157,13 @@ typedef enum
|
||||
#define SUBSCRIBE_LIST OnPublishList theOnPublishList[]
|
||||
#define SUB(...) {__VA_ARGS__}
|
||||
#define END_OF_SUBSCRIBE_LIST {MQTTSN_TOPIC_TYPE_NORMAL,0,0,0, 0}
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
|
||||
#define SetForwarderMode(...) theClient->getGwProxy()->setForwarderMode(__VA_ARGS__)
|
||||
#define SetQoSMinus1Mode(...) theClient->getGwProxy()->setQoSMinus1Mode(__VA_ARGS__)
|
||||
|
||||
#define SetAutoConnectMode(...) theClient->setAutoConnectMode(__VA_ARGS__)
|
||||
#define SetAutoPingReqMode(...) theClient->getGwProxy()->setPingReqMode(__VA_ARGS__)
|
||||
#define SetCleanSession(...) theClient->getGwProxy()->setSessionMode(__VA_ARGS__)
|
||||
#ifdef CLIENT_MODE
|
||||
#define DISPLAY(...)
|
||||
#define PROMPT(...)
|
||||
@@ -195,11 +252,11 @@ typedef enum
|
||||
/*=================================
|
||||
* Starting prompt
|
||||
==================================*/
|
||||
#define TESTER_VERSION " * Version: 2.0.0"
|
||||
#define TESTER_VERSION " * Version: 2.1.0"
|
||||
|
||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway Tester"
|
||||
#define PAHO_COPYRIGHT0 " * "
|
||||
#define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse"
|
||||
#define PAHO_COPYRIGHT2 " * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)"
|
||||
#define PAHO_COPYRIGHT2 " * (https://github.com/eclipse/paho.mqtt-sn.embedded-c.git)"
|
||||
#define PAHO_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI"
|
||||
#define PAHO_COPYRIGHT4 " ***************************************************************************"
|
||||
|
||||
|
||||
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef DTLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
|
||||
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtlsPort::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtlsPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
uint16_t recvLen = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
recvLen = LDtlsPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
|
||||
bool LNetwork::initialize(LUdpConfig *config)
|
||||
{
|
||||
return LDtlsPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int LNetwork::sslConnect(void)
|
||||
{
|
||||
return LDtlsPort::sslConnect(_gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class DtlsPort
|
||||
=========================================*/
|
||||
LDtlsPort::LDtlsPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdMcast = 0;
|
||||
_sockfdSsl = 0;
|
||||
_castStat = 0;
|
||||
}
|
||||
|
||||
LDtlsPort::~LDtlsPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LDtlsPort::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = 0;
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtlsPort::open(LUdpConfig *config)
|
||||
{
|
||||
char errmsg[256];
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Client certification and cookie are not required */
|
||||
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||
|
||||
/* setup Multicast socket */
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
ip_mreq mreq;
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LDtlsPort::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
|
||||
int LDtlsPort::unicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
int status = SSL_write(_ssl, buf, length);
|
||||
if (status <= 0)
|
||||
{
|
||||
int rc = 0;
|
||||
SSL_get_error(_ssl, rc);
|
||||
DISPLAY("errno == %d in LDtlsPort::unicast\n", rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto gateway via DTLS ");
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int LDtlsPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
DISPLAY(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool LDtlsPort::checkRecvBuf()
|
||||
{
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
if (_sockfdMcast)
|
||||
{
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
}
|
||||
if (_sockfdSsl)
|
||||
{
|
||||
FD_SET(_sockfdSsl, &recvfds);
|
||||
}
|
||||
|
||||
if (_sockfdMcast > _sockfdSsl)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdSsl;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_SSL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = STAT_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LDtlsPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LDtlsPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in sender;
|
||||
int status = 0;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
if (_castStat == STAT_SSL)
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
if (SSL_read(_ssl, buf, length) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
|
||||
D_NWLOG("recved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo)
|
||||
{
|
||||
int reuse = 1;
|
||||
if (_ssl != 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect SSL exists.\n");
|
||||
SSL_shutdown(_ssl);
|
||||
SSL_free(_ssl);
|
||||
_sockfdSsl = 0;
|
||||
_ssl = 0;
|
||||
}
|
||||
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect socket exists.\n");
|
||||
::close(_sockfdSsl);
|
||||
}
|
||||
|
||||
_sockfdSsl = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdSsl < 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't create a socket\n");
|
||||
return -1;
|
||||
}
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = portNo;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
int rc = 0;
|
||||
errno = 0;
|
||||
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||
connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in));
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest);
|
||||
_ssl = SSL_new(_ctx);
|
||||
SSL_set_bio(_ssl, cbio, cbio);
|
||||
|
||||
D_NWLOG("LDtlsPort::sslConnect connect to %-15s:%-6u\n", inet_ntoa(dest.sin_addr), htons(dest.sin_port));
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||
|
||||
int stat = SSL_connect(_ssl);
|
||||
if (stat != 1)
|
||||
{
|
||||
rc = -1;
|
||||
D_NWLOG("SSL fail to connect\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
D_NWLOG("SSL connected\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKDTLS_H_
|
||||
#define NETWORKDTLS_H_
|
||||
|
||||
#ifdef DTLS
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
#define STAT_NONE 0
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
#define STAT_SSL 3
|
||||
/*========================================
|
||||
Class LDtlsPort
|
||||
=======================================*/
|
||||
class LDtlsPort
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LDtlsPort();
|
||||
virtual ~LDtlsPort();
|
||||
|
||||
bool open(LUdpConfig* config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock, uint32_t* ipaddress, in_port_t* port );
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
SSL* getSSL(void);
|
||||
int sslConnect(uint32_t ipAddress, in_port_t port);
|
||||
private:
|
||||
void close();
|
||||
int recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipaddress, in_port_t* port );
|
||||
|
||||
int _sockfdMcast;
|
||||
int _sockfdSsl;
|
||||
SSL_CTX *_ctx;
|
||||
SSL *_ssl;
|
||||
in_port_t _gPortNo;
|
||||
in_port_t _uPortNo;
|
||||
uint32_t _gIpAddr;
|
||||
uint8_t _castStat;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LDtlsPort
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdpConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
int sslConnect(void);
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
uint32_t _gwIpAddress;
|
||||
uint32_t _ipAddress;
|
||||
in_port_t _gwPortNo;
|
||||
in_port_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* DTLS */
|
||||
#endif /* NETWORKDTLS_H_ */
|
||||
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef DTLS6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <termios.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <poll.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
|
||||
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtls6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtls6Port::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LDtls6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int addrFlg = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && addrFlg && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
memcpy(&_gwIpAddress.s6_addr, &_ipAddress.s6_addr, sizeof(_ipAddress.s6_addr));
|
||||
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(&_gwIpAddress, 0, sizeof(_gwIpAddress));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LDtls6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int LNetwork::sslConnect(void)
|
||||
{
|
||||
return LDtls6Port::sslConnect(_gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class Dtls6Port
|
||||
=========================================*/
|
||||
LDtls6Port::LDtls6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
_castStat = STAT_NONE;
|
||||
_ifIndex = 0;
|
||||
_gIpAddrStr = nullptr;
|
||||
_sockfdMcast = 0;
|
||||
_sockfdSsl = 0;
|
||||
_ctx = nullptr;
|
||||
_ssl = nullptr;
|
||||
_gPortNo = _uPortNo = 0;
|
||||
}
|
||||
|
||||
LDtls6Port::~LDtls6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
}
|
||||
|
||||
void LDtls6Port::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = 0;
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtls6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
sockaddr_in6 addr6;
|
||||
char errmsg[256];
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Client certification and cookie are not required */
|
||||
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
_ifIndex = if_nametoindex(config->interface);
|
||||
_interfaceName = config->interface;
|
||||
}
|
||||
|
||||
/* create a multicast socket */
|
||||
_sockfdMcast = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(_sockfdMcast, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = _ifIndex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LDtls6Port::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
int LDtls6Port::unicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
int status = SSL_write(_ssl, buf, length);
|
||||
if (status <= 0)
|
||||
{
|
||||
int rc = 0;
|
||||
SSL_get_error(_ssl, rc);
|
||||
DISPLAY("errno == %d in LDtls6Port::unicast\n", rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto gateway via DTLS6 ");
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtls6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gIpAddr.sin6_port));
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtls6Port::checkRecvBuf()
|
||||
{
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
if (_sockfdMcast)
|
||||
{
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
}
|
||||
if (_sockfdSsl)
|
||||
{
|
||||
FD_SET(_sockfdSsl, &recvfds);
|
||||
}
|
||||
|
||||
if (_sockfdMcast > _sockfdSsl)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdSsl;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_SSL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = STAT_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LDtls6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LDtls6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
sockaddr_in6 sender;
|
||||
int status = 0;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (_castStat == STAT_SSL)
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
if (SSL_read(_ssl, buf, length) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||
*portPtr = sender.sin6_port;
|
||||
|
||||
D_NWLOG("recved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtls6Port::sslConnect(in6_addr ipAddress, in_port_t portNo)
|
||||
{
|
||||
int optval = 1;
|
||||
|
||||
if (_ssl != 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect SSL exists.\n");
|
||||
SSL_shutdown(_ssl);
|
||||
SSL_free(_ssl);
|
||||
_sockfdSsl = 0;
|
||||
_ssl = 0;
|
||||
}
|
||||
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect socket exists.\n");
|
||||
::close(_sockfdSsl);
|
||||
}
|
||||
|
||||
_sockfdSsl = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (_sockfdSsl <= 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect Can't create a socket\n");
|
||||
return -1;
|
||||
}
|
||||
optval = 1;
|
||||
setsockopt(_sockfdSsl, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR || SO_REUSEPORT, &optval, sizeof(optval));
|
||||
|
||||
if (_ifIndex > 0)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
setsockopt(_sockfdSsl, IPPROTO_IP, IP_BOUND_IF, &_ifIndex, sizeof(_ifIndex));
|
||||
#else
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_BINDTODEVICE, _interfaceName.c_str(), _interfaceName.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
sockaddr_in6 addr;
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = _uPortNo;
|
||||
addr.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Destination is a gateway address and portNo
|
||||
int rc = 0;
|
||||
sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = portNo;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||
if (connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in6)) < 0)
|
||||
{
|
||||
D_NWLOG("socket can't connect %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest) <0)
|
||||
{
|
||||
D_NWLOG("BIO_ctrl %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
_ssl = SSL_new(_ctx);
|
||||
if (_ssl == nullptr)
|
||||
{
|
||||
D_NWLOG("SSL_new %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
SSL_set_bio(_ssl, cbio, cbio);
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("connect to %-15s:%-6u\n", addrBuf, ntohs(dest.sin6_port));
|
||||
#endif
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||
errno = 0;
|
||||
|
||||
int stat = SSL_connect(_ssl);
|
||||
if (stat != 1)
|
||||
{
|
||||
rc = -1;
|
||||
D_NWLOG("SSL fail to connect %s\n",strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
D_NWLOG("SSL connected\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKDTLS6_H_
|
||||
#define NETWORKDTLS6_H_
|
||||
|
||||
#ifdef DTLS6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <poll.h>
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_NONE 0
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
#define STAT_SSL 3
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LDtls6Port
|
||||
=======================================*/
|
||||
class LDtls6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LDtls6Port();
|
||||
virtual ~LDtls6Port();
|
||||
|
||||
bool open(LUdp6Config* config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock, in6_addr* ipaddress, in_port_t* port );
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
SSL* getSSL(void);
|
||||
int sslConnect(in6_addr ipAddress, uint16_t port);
|
||||
private:
|
||||
void close();
|
||||
int recvfrom ( uint8_t* buf, uint16_t len, int flags, in6_addr* ipaddress, in_port_t* port );
|
||||
|
||||
int _sockfdMcast;
|
||||
int _sockfdSsl;
|
||||
SSL_CTX *_ctx;
|
||||
SSL *_ssl;
|
||||
in_port_t _gPortNo;
|
||||
in_port_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
uint32_t _ifIndex;
|
||||
string _interfaceName;
|
||||
uint8_t _castStat;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LDtls6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
int sslConnect(void);
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
in_port_t _gwPortNo;
|
||||
in_port_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* DTLS6 */
|
||||
#endif /* NETWORKDTLS6_H_ */
|
||||
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/rfcomm.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
extern LRfcommConfig theNetcon;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
_returnCode = 0;
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LRfcommPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LRfcommPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int* len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LRfcommPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false);
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
}
|
||||
|
||||
void LNetwork::setFixedGwAddress(void)
|
||||
{
|
||||
_channel = LRfcommPort::_channel;
|
||||
str2ba( theNetcon.gwAddress, (bdaddr_t*)_gwAddress);
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LRfcommConfig* config)
|
||||
{
|
||||
return LRfcommPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class RFCOMM Stack
|
||||
=========================================*/
|
||||
LRfcommPort::LRfcommPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockRfcomm = 0;
|
||||
_channel = 0;
|
||||
}
|
||||
|
||||
LRfcommPort::~LRfcommPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void LRfcommPort::close()
|
||||
{
|
||||
if (_sockRfcomm > 0)
|
||||
{
|
||||
::close(_sockRfcomm);
|
||||
_sockRfcomm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool LRfcommPort::open(LRfcommConfig* config)
|
||||
{
|
||||
const int reuse = 1;
|
||||
str2ba(config->gwAddress, (bdaddr_t*)_gwAddress);
|
||||
_channel = config->channel;
|
||||
|
||||
if (_channel == 0 || _gwAddress == 0 )
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockRfcomm = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
|
||||
if (_sockRfcomm < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockRfcomm, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_rc addru = { 0 };
|
||||
addru.rc_family = AF_BLUETOOTH;
|
||||
addru.rc_channel = _channel;
|
||||
memcpy(&addru.rc_bdaddr, _gwAddress, 6);
|
||||
|
||||
char bufgw[30];
|
||||
ba2str(&addru.rc_bdaddr, bufgw);
|
||||
DISPLAY("GW MAC = %s RFCOMM CH = %d\n", bufgw, addru.rc_channel);
|
||||
|
||||
// connect to server
|
||||
errno = 0;
|
||||
int status = connect(_sockRfcomm, (struct sockaddr *) &addru, sizeof(addru));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror = %d Can't connect to GW in LRfcommPort::open\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merror = %d Can't connect to GW Ble socket in LRfcommPort::open\033[0m\033[0;37m\n",errno);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int LRfcommPort::unicast(const uint8_t* buf, uint32_t length)
|
||||
{
|
||||
int status = ::write(_sockRfcomm, buf, length);
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("errno == %d in LRfcommPort::unicast\n", errno);
|
||||
DISPLAY("errno == %d in LRfcommPort::unicast\n", errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-2d", _channel);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-2dch", _channel);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LRfcommPort::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
if (::recv(_sockRfcomm, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int LRfcommPort::recv(uint8_t* buf, uint16_t length, bool flg)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
int status = ::recv(_sockRfcomm, buf, length, flags);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
D_NWLOG("\nrecved ");
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKRFCOMM_H_
|
||||
#define NETWORKRFCOMM_H_
|
||||
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient
|
||||
{
|
||||
/*========================================
|
||||
Class LRfcommPort
|
||||
=======================================*/
|
||||
class LRfcommPort
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LRfcommPort();
|
||||
virtual ~LRfcommPort();
|
||||
bool open(LRfcommConfig* config);
|
||||
int unicast(const uint8_t* buf, uint32_t length);
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
|
||||
int _sockRfcomm;
|
||||
uint8_t _gwAddress[6];
|
||||
uint8_t _channel;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LRfcommPort
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
void setFixedGwAddress(void);
|
||||
bool initialize(LRfcommConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* RFCOMM */
|
||||
#endif /* NETWORKRFCOM_H_ */
|
||||
@@ -13,6 +13,7 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
@@ -25,365 +26,426 @@
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
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()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udpStack
|
||||
Class udpStack
|
||||
=========================================*/
|
||||
LUdpPort::LUdpPort(){
|
||||
LUdpPort::LUdpPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdUcast = -1;
|
||||
_sockfdMcast = -1;
|
||||
_castStat = 0;
|
||||
}
|
||||
|
||||
LUdpPort::~LUdpPort(){
|
||||
LUdpPort::~LUdpPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LUdpPort::close(){
|
||||
if(_sockfdMcast > 0){
|
||||
::close( _sockfdMcast);
|
||||
_sockfdMcast = -1;
|
||||
if(_sockfdUcast > 0){
|
||||
::close( _sockfdUcast);
|
||||
_sockfdUcast = -1;
|
||||
}
|
||||
}
|
||||
void LUdpPort::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = -1;
|
||||
if (_sockfdUcast > 0)
|
||||
{
|
||||
::close(_sockfdUcast);
|
||||
_sockfdUcast = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdpPort::open(LUdpConfig config){
|
||||
const int reuse = 1;
|
||||
char loopch = 1;
|
||||
bool LUdpPort::open(LUdpConfig *config)
|
||||
{
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config.ipAddress[3];
|
||||
config.ipAddress[3] = config.ipAddress[0];
|
||||
config.ipAddress[0] = sav;
|
||||
sav = config.ipAddress[2];
|
||||
config.ipAddress[2] = config.ipAddress[1];
|
||||
config.ipAddress[1] = sav;
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gPortNo = htons(config.gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*)config.ipAddress);
|
||||
_uPortNo = htons(config.uPortNo);
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){
|
||||
return false;
|
||||
}
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdUcast < 0){
|
||||
return false;
|
||||
}
|
||||
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdUcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
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;
|
||||
}
|
||||
if (::bind(_sockfdUcast, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMcast < 0){
|
||||
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);
|
||||
sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if( ::bind ( _sockfdMcast, (struct sockaddr*)&addrm, sizeof(addrm)) <0){
|
||||
return false;
|
||||
}
|
||||
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in UdpPort::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
optval= 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LUdpPort::isUnicast(){
|
||||
return ( _castStat == STAT_UNICAST);
|
||||
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::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);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
} D_NWLOG("\n");
|
||||
|
||||
int status = ::sendto( _sockfdUcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );
|
||||
if( 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;
|
||||
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;
|
||||
}
|
||||
|
||||
int LUdpPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
||||
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 UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
||||
|
||||
int status = ::sendto( _sockfdMcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );
|
||||
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));
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
} D_NWLOG("\n");
|
||||
|
||||
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;
|
||||
}
|
||||
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,6 +17,8 @@
|
||||
#ifndef NETWORKUDP_H_
|
||||
#define NETWORKUDP_H_
|
||||
|
||||
#ifdef UDP
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
@@ -27,8 +29,6 @@
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
LUdpPort();
|
||||
virtual ~LUdpPort();
|
||||
|
||||
bool open(LUdpConfig config);
|
||||
bool open(LUdpConfig* config);
|
||||
|
||||
int unicast(const uint8_t* buf, uint32_t length, uint32_t ipaddress, uint16_t port );
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
@@ -87,8 +87,9 @@ public:
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
void setFixedGwAddress(void);
|
||||
bool initialize(LUdpConfig config);
|
||||
bool initialize(LUdpConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
@@ -103,6 +104,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
|
||||
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdp6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int diffAddr = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && diffAddr && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
memcpy(_gwIpAddress.s6_addr, _ipAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = _portNo;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(_gwIpAddress.s6_addr, 0, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LUdp6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udp6Stack
|
||||
=========================================*/
|
||||
LUdp6Port::LUdp6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
memset(_pollfds, 0, sizeof(_pollfds));
|
||||
_sock = 0;
|
||||
_interface = NULL;
|
||||
_gIpAddrStr = NULL;
|
||||
}
|
||||
|
||||
LUdp6Port::~LUdp6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
if (_interface)
|
||||
{
|
||||
free(_interface);
|
||||
}
|
||||
}
|
||||
|
||||
void LUdp6Port::close()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].fd > 0)
|
||||
{
|
||||
::close(_pollfds[i].fd);
|
||||
_pollfds[i].fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
int sock = 0;
|
||||
uint32_t ifindex = 0;
|
||||
sockaddr_in6 addr6;
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create a unicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
ifindex = if_nametoindex(config->interface);
|
||||
#ifdef __APPLE__
|
||||
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
|
||||
#else
|
||||
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, config->interface, strlen(config->interface));
|
||||
#endif
|
||||
}
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _uPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
_pollfds[0].fd = sock;
|
||||
_pollfds[0].events = POLLIN;
|
||||
|
||||
/* create a multicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = ifindex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
optval = 1;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
_pollfds[1].fd = sock;
|
||||
_pollfds[1].events = POLLIN;
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
int LUdp6Port::unicast(const uint8_t *buf, uint32_t length, in6_addr ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = port;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("unicast to [%s]:%-6u", addrBuf, htons(port));
|
||||
|
||||
int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG(" errno = %d %s in Udp6Port::unicast\n", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34municast to [%s[:%-6u", addrBuf, htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LUdp6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gPortNo));
|
||||
|
||||
int status = ::sendto(_pollfds[1].fd, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s ", _gIpAddrStr, portStr);
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d %s in Udp6Port::multicast\033[0m\033[0;37m\n", errno, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
int cnt = poll(_pollfds, 2, 50); // Timeout 50m secs
|
||||
if (cnt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].revents & POLLIN)
|
||||
{
|
||||
if (::recv(_pollfds[i].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_sock = _pollfds[i].fd;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
int LUdp6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LUdp6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in6 sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
|
||||
status = ::recvfrom(_sock, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in Udp6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||
*portPtr = sender.sin6_port;
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecv from [%s]:%-6u", addrBuf, htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LUdp6Port::isUnicast(void)
|
||||
{
|
||||
return (_sock == _pollfds[0].fd && _sock > 0);
|
||||
}
|
||||
#endif /* UDP6 */
|
||||
|
||||
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKUDP6_H_
|
||||
#define NETWORKUDP6_H_
|
||||
|
||||
#ifdef UDP6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LUpd6Port
|
||||
=======================================*/
|
||||
class LUdp6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LUdp6Port();
|
||||
virtual ~LUdp6Port();
|
||||
|
||||
bool open(LUdp6Config *config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length, in6_addr ipaddress, uint16_t port);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t *buf, uint16_t len, bool nonblock, in6_addr *ipaddress, uint16_t *port);
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
int recvfrom(uint8_t *buf, uint16_t len, int flags, in6_addr *ipaddress, uint16_t *port);
|
||||
|
||||
pollfd _pollfds[2];
|
||||
uint16_t _gPortNo;
|
||||
uint16_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
char* _interface;
|
||||
int _sock;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LUdp6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config *config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
uint16_t _gwPortNo;
|
||||
uint16_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP6 */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
@@ -44,6 +44,7 @@ LPublishManager::LPublishManager()
|
||||
_last = 0;
|
||||
_elmCnt = 0;
|
||||
_publishedFlg = SAVE_TASK_INDEX;
|
||||
_autoConnectFlg = false;
|
||||
}
|
||||
|
||||
LPublishManager::~LPublishManager()
|
||||
@@ -115,7 +116,10 @@ void LPublishManager::sendPublish(PubElement* elm)
|
||||
return;
|
||||
}
|
||||
|
||||
theClient->getGwProxy()->connect();
|
||||
if (_autoConnectFlg)
|
||||
{
|
||||
theClient->getGwProxy()->connect();
|
||||
}
|
||||
|
||||
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
uint8_t org = 0;
|
||||
@@ -310,6 +314,11 @@ void LPublishManager::checkTimeout(void)
|
||||
}
|
||||
}
|
||||
|
||||
void LPublishManager::setAutoConnectMode(bool flg)
|
||||
{
|
||||
_autoConnectFlg = flg;
|
||||
}
|
||||
|
||||
PubElement* LPublishManager::getElement(uint16_t msgId)
|
||||
{
|
||||
PubElement* elm = _first;
|
||||
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
void sendSuspend(const char* topicName, uint16_t topicId, uint8_t topicType);
|
||||
bool isDone(void);
|
||||
bool isMaxFlight(void);
|
||||
void setAutoConnectMode(bool);
|
||||
private:
|
||||
PubElement* getElement(uint16_t msgId);
|
||||
PubElement* getElement(const char* topicName);
|
||||
@@ -84,7 +85,8 @@ private:
|
||||
PubElement* _last;
|
||||
uint8_t _elmCnt;
|
||||
uint8_t _publishedFlg;
|
||||
uint8_t _autoConnectFlg;
|
||||
};
|
||||
|
||||
|
||||
} /* tomyAsyncClient */
|
||||
#endif /* PUBLISHMANAGER_H_ */
|
||||
|
||||
@@ -67,7 +67,9 @@ void LSubscribeManager::onConnect(void)
|
||||
{
|
||||
if ( theOnPublishList[i].type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
subscribe(theOnPublishList[i].id, theOnPublishList[i].pubCallback, theOnPublishList[i].qos);
|
||||
subscribePredefinedId(theOnPublishList[i].id,
|
||||
theOnPublishList[i].pubCallback,
|
||||
theOnPublishList[i].qos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,6 +124,7 @@ void LSubscribeManager::send(SubElement* elm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
if (elm->topicType == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
@@ -169,7 +172,7 @@ void LSubscribeManager::subscribe(const char* topicName, TopicCallback onPublish
|
||||
send(elm);
|
||||
}
|
||||
|
||||
void LSubscribeManager::subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
void LSubscribeManager::subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
{
|
||||
SubElement* elm = add(MQTTSN_TYPE_SUBSCRIBE, 0, MQTTSN_TOPIC_TYPE_PREDEFINED, topicId, qos, onPublish);
|
||||
send(elm);
|
||||
@@ -262,7 +265,9 @@ void LSubscribeManager::responce(const uint8_t* msg)
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;31m UNSUBACK Invalid messageId. \033[0m\033[0;37m\n\n");
|
||||
DISPLAY(
|
||||
"\033[0m\033[0;31m UNSUBACK Invalid messageId=%04x. \033[0m\033[0;37m\n\n",
|
||||
msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
~LSubscribeManager();
|
||||
void onConnect(void);
|
||||
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void unsubscribe(const char* topicName);
|
||||
void unsubscribe(uint16_t topicId);
|
||||
void responce(const uint8_t* msg);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -32,148 +31,153 @@ extern LMqttsnClient* theClient;
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=====================================
|
||||
TaskManager
|
||||
TaskManager
|
||||
======================================*/
|
||||
LTaskManager::LTaskManager(void){
|
||||
_tasks = 0;
|
||||
_tests = 0;
|
||||
_index = 0;
|
||||
LTaskManager::LTaskManager(void)
|
||||
{
|
||||
_tasks = 0;
|
||||
_tests = 0;
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
LTaskManager::~LTaskManager(void){
|
||||
|
||||
LTaskManager::~LTaskManager(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LTaskManager::add(TaskList* task){
|
||||
void LTaskManager::add(TaskList* task)
|
||||
{
|
||||
_tasks = task;
|
||||
}
|
||||
|
||||
void LTaskManager::add(TestList* test){
|
||||
void LTaskManager::add(TestList* test)
|
||||
{
|
||||
_tests = test;
|
||||
}
|
||||
|
||||
void LTaskManager::run(void){
|
||||
int i = 0;
|
||||
char c = 0;
|
||||
bool cancelFlg = false;
|
||||
TestList test = {0};
|
||||
TaskList task = {0};
|
||||
void LTaskManager::run(void)
|
||||
{
|
||||
int i = 0;
|
||||
char c = 0;
|
||||
bool cancelFlg = false;
|
||||
TestList test = { 0 };
|
||||
TaskList task = { 0 };
|
||||
|
||||
if ( !theClientMode )
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
if (!theClientMode)
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
|
||||
for (i = 0; _tests[i].testTask > test.testTask; i++)
|
||||
{
|
||||
PROMPT("Execute \"%s\" ? ( y/n ) : ", _tests[i].testLabel);
|
||||
while (true)
|
||||
{
|
||||
if (CHECKKEYIN(&c))
|
||||
{
|
||||
if ( toupper(c) == 'N' )
|
||||
{
|
||||
for (i = 0; _tests[i].testTask > test.testTask; i++)
|
||||
{
|
||||
PROMPT("Execute \"%s\" ? ( y/n ) : ", _tests[i].testLabel);
|
||||
while (true)
|
||||
{
|
||||
if (CHECKKEYIN(&c))
|
||||
{
|
||||
if (toupper(c) == 'N')
|
||||
{
|
||||
|
||||
DISPLAY("\033[0m\033[0;32m\n**** %s is canceled ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
|
||||
theScreen->prompt("");
|
||||
cancelFlg = true;
|
||||
break;
|
||||
}
|
||||
else if ( toupper(c) == 'Y' )
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n\n**** %s start ****\033[0m\033[0;37m\n", _tests[i].testLabel);
|
||||
theScreen->prompt("");
|
||||
(_tests[i].testTask)();
|
||||
cancelFlg = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
}
|
||||
DISPLAY("\033[0m\033[0;32m\n**** %s is canceled ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
|
||||
theScreen->prompt("");
|
||||
cancelFlg = true;
|
||||
break;
|
||||
}
|
||||
else if (toupper(c) == 'Y')
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n\n**** %s start ****\033[0m\033[0;37m\n", _tests[i].testLabel);
|
||||
theScreen->prompt("");
|
||||
(_tests[i].testTask)();
|
||||
cancelFlg = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
while ( true )
|
||||
{
|
||||
do
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while(theClient->getPublishManager()->isMaxFlight() ||
|
||||
!theClient->getSubscribeManager()->isDone() ||
|
||||
!theClient->getRegisterManager()->isDone());
|
||||
while (true)
|
||||
{
|
||||
do
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
|
||||
|| !theClient->getRegisterManager()->isDone());
|
||||
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !cancelFlg )
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n**** %s complete ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
|
||||
}
|
||||
}
|
||||
DISPLAY("\033[0m\033[0;32m\n\n######### All tests complete! ###########\033[0m\033[0;37m\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
for (_index = 0; _tasks[_index].callback > task.callback; _index++)
|
||||
{
|
||||
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) &&
|
||||
_tasks[_index].count == 0)
|
||||
{
|
||||
_tasks[_index].prevTime = time(NULL);
|
||||
(_tasks[_index].callback)();
|
||||
}
|
||||
}
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cancelFlg)
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n**** %s complete ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
|
||||
}
|
||||
}
|
||||
DISPLAY("\033[0m\033[0;32m\n\n######### All tests complete! ###########\033[0m\033[0;37m\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
for (_index = 0; _tasks[_index].callback > task.callback; _index++)
|
||||
{
|
||||
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) && _tasks[_index].count == 0)
|
||||
{
|
||||
_tasks[_index].prevTime = time(NULL);
|
||||
(_tasks[_index].callback)();
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while(theClient->getPublishManager()->isMaxFlight() ||
|
||||
!theClient->getSubscribeManager()->isDone() ||
|
||||
!theClient->getRegisterManager()->isDone());
|
||||
do
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
|
||||
|| !theClient->getRegisterManager()->isDone());
|
||||
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LTaskManager::getIndex(void){
|
||||
return _index;
|
||||
uint8_t LTaskManager::getIndex(void)
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
|
||||
void LTaskManager::done(uint8_t index){
|
||||
if (_tasks )
|
||||
{
|
||||
if (_tasks[index].count > 0)
|
||||
{
|
||||
_tasks[index].count--;
|
||||
}
|
||||
}
|
||||
if (_tests )
|
||||
{
|
||||
if (_tests[index].count > 0)
|
||||
{
|
||||
_tests[index].count--;
|
||||
}
|
||||
}
|
||||
void LTaskManager::done(uint8_t index)
|
||||
{
|
||||
if (_tasks)
|
||||
{
|
||||
if (_tasks[index].count > 0)
|
||||
{
|
||||
_tasks[index].count--;
|
||||
}
|
||||
}
|
||||
if (_tests)
|
||||
{
|
||||
if (_tests[index].count > 0)
|
||||
{
|
||||
_tests[index].count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LTaskManager::suspend(uint8_t index){
|
||||
if ( _tasks )
|
||||
{
|
||||
_tasks[index].count++;
|
||||
}
|
||||
if ( _tests )
|
||||
{
|
||||
_tests[index].count++;
|
||||
}
|
||||
void LTaskManager::suspend(uint8_t index)
|
||||
{
|
||||
if (_tasks)
|
||||
{
|
||||
_tasks[index].count++;
|
||||
}
|
||||
if (_tests)
|
||||
{
|
||||
_tests[index].count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
PROGNAME := MQTT-SNGateway
|
||||
APPL := mainGateway
|
||||
|
||||
LPROGNAME := MQTT-SNLogmonitor
|
||||
LAPPL := mainLogmonitor
|
||||
|
||||
TESTPROGNAME := testPFW
|
||||
TESTAPPL := mainTestProcess
|
||||
|
||||
CONFIG := gateway.conf
|
||||
CLIENTS := clients.conf
|
||||
PREDEFTOPIC := predefinedTopic.conf
|
||||
|
||||
SRCDIR := src
|
||||
SUBDIR := ../MQTTSNPacket/src
|
||||
|
||||
OS := linux
|
||||
SENSORNET := udp
|
||||
TEST := tests
|
||||
|
||||
INSTALL_DIR=../../
|
||||
CONFIG_DIR=../../
|
||||
|
||||
CPPSRCS := \
|
||||
$(SRCDIR)/MQTTGWConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTGWPacket.cpp \
|
||||
$(SRCDIR)/MQTTGWPublishHandler.cpp \
|
||||
$(SRCDIR)/MQTTGWSubscribeHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGateway.cpp \
|
||||
$(SRCDIR)/MQTTSNGWBrokerRecvTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWBrokerSendTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClient.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientRecvTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientSendTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWLogmonitor.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPacket.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPacketHandleTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWProcess.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPublishHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWSubscribeHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWEncapsulatedPacket.cpp \
|
||||
$(SRCDIR)/MQTTSNGWForwarder.cpp \
|
||||
$(SRCDIR)/MQTTSNGWQoSm1Proxy.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAdapter.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAggregater.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientList.cpp \
|
||||
$(SRCDIR)/MQTTSNGWTopic.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAdapterManager.cpp \
|
||||
$(SRCDIR)/MQTTSNAggregateConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWMessageIdTable.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAggregateTopicTable.cpp \
|
||||
$(SRCDIR)/$(OS)/$(SENSORNET)/SensorNetwork.cpp \
|
||||
$(SRCDIR)/$(OS)/Timer.cpp \
|
||||
$(SRCDIR)/$(OS)/Network.cpp \
|
||||
$(SRCDIR)/$(OS)/Threading.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestProcess.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestQue.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTree23.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTopics.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTopicIdMap.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTask.cpp
|
||||
|
||||
|
||||
CSRCS := $(SUBDIR)/MQTTSNConnectClient.c \
|
||||
$(SUBDIR)/MQTTSNConnectServer.c \
|
||||
$(SUBDIR)/MQTTSNDeserializePublish.c \
|
||||
$(SUBDIR)/MQTTSNPacket.c \
|
||||
$(SUBDIR)/MQTTSNSearchClient.c \
|
||||
$(SUBDIR)/MQTTSNSearchServer.c \
|
||||
$(SUBDIR)/MQTTSNSerializePublish.c \
|
||||
$(SUBDIR)/MQTTSNSubscribeClient.c \
|
||||
$(SUBDIR)/MQTTSNSubscribeServer.c \
|
||||
$(SUBDIR)/MQTTSNUnsubscribeClient.c \
|
||||
$(SUBDIR)/MQTTSNUnsubscribeServer.c
|
||||
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDE :=
|
||||
INCLUDES += $(INCLUDE) -I$(SRCDIR) \
|
||||
-I$(SRCDIR)/$(OS) \
|
||||
-I$(SRCDIR)/$(OS)/$(SENSORNET) \
|
||||
-I$(SUBDIR) \
|
||||
-I$(SRCDIR)/$(TEST) \
|
||||
-I/usr/local/opt/openssl/include/
|
||||
|
||||
# preprocessor defines
|
||||
DEFS :=
|
||||
|
||||
CXX := g++
|
||||
|
||||
LIB :=
|
||||
LIBS += $(LIB) -L/usr/local/lib -L/usr/local/opt/openssl/lib/
|
||||
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD := -lpthread -lssl -lcrypto
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGNAME)
|
||||
LPROG := $(OUTDIR)/$(LPROGNAME)
|
||||
TPROG := $(OUTDIR)/$(TESTPROGNAME)
|
||||
|
||||
OBJS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.o)
|
||||
OBJS += $(CSRCS:%.c=$(OUTDIR)/%.o)
|
||||
DEPS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.d)
|
||||
DEPS += $(CSRCS:%.c=$(OUTDIR)/%.d)
|
||||
|
||||
.PHONY: install clean exectest
|
||||
|
||||
all: $(PROG) $(LPROG) $(TPROG)
|
||||
|
||||
monitor: $(LPROG)
|
||||
|
||||
test: $(TPROG) $(LPROG) exectest
|
||||
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
$(PROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(APPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
$(LPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(LAPPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
$(TPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(APPL).o:$(SRCDIR)/$(APPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o:$(SRCDIR)/$(TEST)/$(TESTAPPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(LAPPL).o:$(SRCDIR)/$(LAPPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.c
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
install:
|
||||
cp -pf $(PROG) $(INSTALL_DIR)
|
||||
cp -pf $(LPROG) $(INSTALL_DIR)
|
||||
cp -pf $(CONFIG) $(CONFIG_DIR)
|
||||
cp -pf $(CLIENTS) $(CONFIG_DIR)
|
||||
cp -pf $(PREDEFTOPIC) $(CONFIG_DIR)
|
||||
|
||||
|
||||
exectest:
|
||||
./$(OUTDIR)/$(TESTPROGNAME) -f ./gateway.conf
|
||||
|
||||
|
||||
@@ -1,145 +1,211 @@
|
||||
# MQTT-SN Transparent / Aggregating Gateway
|
||||
MQTT-SN requires a MQTT-SN Gateway which acts as a protocol converter to convert MQTT-SN messages to MQTT messages.
|
||||
MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||
### step1. Build the gateway
|
||||
copy and expand source code then,
|
||||
```
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||
```
|
||||
In order to build a gateway, one sensor network argument is required.
|
||||
```
|
||||
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm|dtls|dtls6]
|
||||
```
|
||||
|
||||
**MQTT-SN** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||
MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin directory.
|
||||
|
||||
### **step1. Build the gateway**
|
||||
````
|
||||
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||
$ make [SENSORNET={udp6|xbee|loralink}]
|
||||
$ make install
|
||||
$ make clean
|
||||
````
|
||||
By default, a gateway for UDP is built.
|
||||
In order to create a gateway for UDP6, XBee or LoRaLink, SENSORNET argument is required.
|
||||
|
||||
MQTT-SNGateway, MQTT-SNLogmonitor and *.conf files are copied into ../ directory.
|
||||
If you want to install the gateway into specific directories, enter a command line as follows:
|
||||
````
|
||||
$ make install INSTALL_DIR=/path/to/your_directory CONFIG_DIR=/path/to/your_directory
|
||||
````
|
||||
### step2. Execute the Gateway.
|
||||
|
||||
|
||||
### **step2. Execute the Gateway.**
|
||||
|
||||
````
|
||||
$ cd ../../
|
||||
$ ./MQTT-SNGateway [-f Config file name]
|
||||
````
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNGateway
|
||||
```
|
||||
If you get the error message as follows:
|
||||
````
|
||||
what(): RingBuffer can't create a shared memory.
|
||||
Aborted (core dumped)
|
||||
````
|
||||
|
||||
RingBuffer can't create a shared memory. ABORT Gateway!!!
|
||||
You have to start using sudo command only once for the first time.
|
||||
````
|
||||
$ sudo ./MQTT-SNGateway [-f Config file name]
|
||||
````
|
||||
|
||||
### **How to Change the configuration of the gateway**
|
||||
**../gateway.conf** Contents are follows:
|
||||
|
||||
<pre><dev>
|
||||
```
|
||||
$ sudo ./MQTT-SNGateway
|
||||
```
|
||||
## Contents of the gateway configuration file
|
||||
**gateway.conf** is in bin directory. It's contents are follows:
|
||||
|
||||
```
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#***************************************************************************
|
||||
#
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
BrokerName=mqtt.eclipse.org
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
```
|
||||
**GatewayID** is a gateway ID which used by GWINFO message.
|
||||
**GatewayName** is a name of the gateway.
|
||||
**MaxNumberOfClients** is a maxmum number of clients. Clients are dynamically allocated.
|
||||
**KeepAlive** is KeepAlive time in seconds.
|
||||
**LoginID** is used by CONNECT message.
|
||||
**Password** is used by CONNECT message.
|
||||
**BrokerName**is a domain name or IP address of a broker.
|
||||
**BrokerPortNo** is a broker's port no.
|
||||
**BrokerSecurePortNo** is a broker's port no of TLS connection.
|
||||
```
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
```
|
||||
**RootCAfile** is a CA file name.
|
||||
**RootCApath** is a CA path. **SSL_CTX_load_verify_locations(ctx, CAfile, CApath)** function requires these parameters.
|
||||
**CertsKey** is a certificate pem file.
|
||||
**PrivateKey** is a private key pem file.
|
||||
Clients can connect to the broker via TLS by setting '**Secure Connection**' for each client in the client conf file.
|
||||
```
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
```
|
||||
The gateway runs as a aggregating gateway when **AggregatingGateway** is 'YES'.
|
||||
If **QoS-1** is 'YES, the gateway prepares a proxy for the QoS-1 client. QoS-1 client has a 'QoS-1' parameter in a clients.conf file. For QoS-1 clients, set the QoS-1 parameters in the clients.conf file.
|
||||
If **Forwarder** is 'YES', the gateway prepare a forwarder agent.
|
||||
If **ClientAuthentication** is 'YES', the client cannot connect unless it is registered in the clients.conf file.
|
||||
**ClientsList** defines clients and those address so on.
|
||||
**PredefinedTopicList** file defines Predefined Topic.
|
||||
|
||||
|
||||
# UDP
|
||||
```
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
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.
|
||||
|
||||
### ** 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.
|
||||
|
||||
`$ ./MQTT-SNLogmonitor`
|
||||
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNLogmonitor
|
||||
```
|
||||
Now you can get the Log on your terminal.
|
||||
|
||||
|
||||
## ** Tips **
|
||||
Uncomment the line 62, 63 in MQTTSNDefines.h then you can get more precise logs.
|
||||
##### Tips
|
||||
Use compiler definitions then you can get more precise logs.
|
||||
**-DDEBUG_NW** is a flag for debug logs of Sensor network.
|
||||
**-DDEBUG_MQTTSN** is a flag for debug logs of MQTT-SN message haandling.
|
||||
One or both flags can be specified.
|
||||
|
||||
```
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
./build.sh udp -DDEBUG -DDEBUG_NW
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
42
MQTTSNGateway/build.sh
Executable file
42
MQTTSNGateway/build.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
build () {
|
||||
echo "Start building MQTT-SN Gateway $1"
|
||||
|
||||
cd $SCRIPT_DIR/..
|
||||
BDIR='build.gateway'
|
||||
if [ ! -d ./$BDIR ]; then
|
||||
mkdir $BDIR
|
||||
fi
|
||||
cd $BDIR
|
||||
cmake .. -DSENSORNET=$1 -DDEFS="${2} ${3}"
|
||||
make MQTTSNPacket
|
||||
make MQTT-SNGateway
|
||||
make MQTT-SNLogmonitor
|
||||
cd ../MQTTSNGateway
|
||||
cp *.conf ./bin/
|
||||
}
|
||||
|
||||
SCRIPT_DIR=$(cd $(dirname $0); pwd)
|
||||
|
||||
if [ $1 == "udp" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "udp6" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "xbee" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "loralink" ]; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "rfcomm" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "dtls" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "dtls6" ] ; then
|
||||
build dtls "${2} ${3} -DDTLS6"
|
||||
elif [ $1 == "clean" ] ; then
|
||||
rm -rf ../builg.gateway
|
||||
else
|
||||
echo "Usage: build.sh [ udp | udp6 | xbee | loralink | rfcomm | dtls | dtls6 | clean]"
|
||||
fi
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
# Lines bigning with # are comment line.
|
||||
# ClientId, SensorNetAddress, "unstableLine", "secureConnection"
|
||||
# in case of UDP, SensorNetAddress format is IPAddress: port no.
|
||||
# if the SensorNetwork is not stable, write "unstableLine".
|
||||
# if Broker's Connection is SSL, write "secureConnection".
|
||||
# if the client is a forwarder, "forwarder" is required.
|
||||
# if the client send PUBLISH QoS-1, "QoS-1" is required.
|
||||
# if the SensorNetwork is not stable, specify "unstableLine".
|
||||
# if Broker's Connection is TLS, specify "secureConnection".
|
||||
# if the client is a forwarder,specify "forwarder".
|
||||
# if the client send PUBLISH QoS-1, specify "QoS-1".
|
||||
#
|
||||
# Ex:
|
||||
# #Client List
|
||||
@@ -31,6 +31,17 @@
|
||||
#
|
||||
# SensorNetwork address format is defined by SensorNetAddress::setAddress(string* data) function.
|
||||
#
|
||||
# UDP6 (IPv6 UDP) [IPv6 address]:PortNo
|
||||
# RFCOMM Device_address.channel (1-30)
|
||||
# XBee FFFFFFFFFFFFFFFF 8bytes Hex
|
||||
# LoRaLink 1-254
|
||||
#
|
||||
#
|
||||
# This is a sample of UDP.
|
||||
#
|
||||
# REWRITE ALL ACCORDING TO YOUR CLIENTS.
|
||||
#
|
||||
|
||||
GatewayTester, 172.16.1.11:20020
|
||||
ClientPUB,172.16.1.11:2010
|
||||
Client01,172.16.1.11:12001
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2019, Tomoaki Yamaguchi
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
@@ -14,55 +14,95 @@
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
BrokerName=mqtt.eclipse.org
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
|
||||
|
||||
# UDP
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::1
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
|
||||
#
|
||||
# DTLS | DTLS6
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
|
||||
#
|
||||
# LOG
|
||||
#
|
||||
|
||||
ShearedMemory=NO
|
||||
|
||||
|
||||
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
@@ -0,0 +1,151 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2022 a1lu
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# Contributors:
|
||||
# a1lu - initial version
|
||||
# ty4tw - modify
|
||||
#*******************************************************************************/
|
||||
PROJECT(mqtt-sn-gateway CXX)
|
||||
|
||||
SET(GW_VERSION_MAJOR 1)
|
||||
SET(GW_VERSION_MINOR 5)
|
||||
SET(GW_VERSION_PATCH 1)
|
||||
|
||||
SET(GATEWAY_VERSION ${GW_VERSION_MAJOR}.${GW_VERSION_MINOR}.${GW_VERSION_PATCH})
|
||||
MESSAGE(STATUS "VERSION : ${GATEWAY_VERSION}")
|
||||
|
||||
configure_file( MQTTSNGWVersion.h.in ${CMAKE_CURRENT_SOURCE_DIR}/MQTTSNGWVersion.h )
|
||||
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../bin)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
SET(OS linux)
|
||||
|
||||
IF(NOT DEFINED SENSORNET)
|
||||
SET(SENSORNET udp)
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "SENSORNET: " ${SENSORNET})
|
||||
|
||||
ADD_DEFINITIONS(${DEFS})
|
||||
MESSAGE(STATUS "Definitions: " ${DEFS})
|
||||
|
||||
ADD_LIBRARY(mqtt-sngateway_common
|
||||
MQTTGWConnectionHandler.cpp
|
||||
MQTTGWPacket.cpp
|
||||
MQTTGWPublishHandler.cpp
|
||||
MQTTGWSubscribeHandler.cpp
|
||||
MQTTSNGateway.cpp
|
||||
MQTTSNGWBrokerRecvTask.cpp
|
||||
MQTTSNGWBrokerSendTask.cpp
|
||||
MQTTSNGWClient.cpp
|
||||
MQTTSNGWClientRecvTask.cpp
|
||||
MQTTSNGWClientSendTask.cpp
|
||||
MQTTSNGWConnectionHandler.cpp
|
||||
MQTTSNGWLogmonitor.cpp
|
||||
MQTTSNGWPacket.cpp
|
||||
MQTTSNGWPacketHandleTask.cpp
|
||||
MQTTSNGWProcess.cpp
|
||||
MQTTSNGWPublishHandler.cpp
|
||||
MQTTSNGWSubscribeHandler.cpp
|
||||
MQTTSNGWEncapsulatedPacket.cpp
|
||||
MQTTSNGWForwarder.cpp
|
||||
MQTTSNGWQoSm1Proxy.cpp
|
||||
MQTTSNGWAdapter.cpp
|
||||
MQTTSNGWAggregater.cpp
|
||||
MQTTSNGWClientList.cpp
|
||||
MQTTSNGWTopic.cpp
|
||||
MQTTSNGWAdapterManager.cpp
|
||||
MQTTSNAggregateConnectionHandler.cpp
|
||||
MQTTSNGWMessageIdTable.cpp
|
||||
MQTTSNGWAggregateTopicTable.cpp
|
||||
${OS}/${SENSORNET}/SensorNetwork.cpp
|
||||
${OS}/${SENSORNET}/SensorNetwork.h
|
||||
${OS}/Timer.cpp
|
||||
${OS}/Timer.h
|
||||
${OS}/Network.cpp
|
||||
${OS}/Network.h
|
||||
${OS}/Threading.cpp
|
||||
${OS}/Threading.h
|
||||
)
|
||||
|
||||
# linux
|
||||
link_directories("/usr/local/lib")
|
||||
|
||||
# Mac
|
||||
link_directories("/usr/local/opt/openssl/lib")
|
||||
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
|
||||
PUBLIC
|
||||
.
|
||||
${OS}
|
||||
${OS}/${SENSORNET}
|
||||
../../MQTTSNPacket/src
|
||||
/usr/local/include
|
||||
/usr/local/opt/openssl/include
|
||||
)
|
||||
|
||||
IF(SENSORNET MATCHES "rfcomm")
|
||||
|
||||
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||
PRIVATE
|
||||
MQTTSNPacket
|
||||
pthread
|
||||
ssl
|
||||
crypto
|
||||
bluetooth
|
||||
)
|
||||
ELSE()
|
||||
|
||||
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||
PRIVATE
|
||||
MQTTSNPacket
|
||||
pthread
|
||||
ssl
|
||||
crypto
|
||||
)
|
||||
|
||||
ENDIF()
|
||||
|
||||
ADD_EXECUTABLE(MQTT-SNGateway
|
||||
mainGateway.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(MQTT-SNGateway
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(MQTT-SNLogmonitor
|
||||
mainLogmonitor.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(MQTT-SNLogmonitor
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(testPFW
|
||||
tests/mainTestProcess.cpp
|
||||
tests/TestProcess.cpp
|
||||
tests/TestQue.cpp
|
||||
tests/TestTree23.cpp
|
||||
tests/TestTopics.cpp
|
||||
tests/TestTopicIdMap.cpp
|
||||
tests/TestTask.cpp
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(testPFW
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
|
||||
ADD_TEST(NAME testPFW
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/..
|
||||
COMMAND testPFW -f ./gateway.conf)
|
||||
@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
MQTTGWConnectionHandler::MQTTGWConnectionHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTGWConnectionHandler::~MQTTGWConnectionHandler()
|
||||
@@ -32,68 +32,67 @@ MQTTGWConnectionHandler::~MQTTGWConnectionHandler()
|
||||
|
||||
void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint8_t rc = MQTT_SERVER_UNAVAILABLE;
|
||||
Connack resp;
|
||||
packet->getCONNACK(&resp);
|
||||
uint8_t rc = MQTT_SERVER_UNAVAILABLE;
|
||||
Connack resp;
|
||||
packet->getCONNACK(&resp);
|
||||
|
||||
/* convert MQTT ReturnCode to MQTT-SN one */
|
||||
if (resp.rc == MQTT_CONNECTION_ACCEPTED)
|
||||
{
|
||||
rc = MQTTSN_RC_ACCEPTED;
|
||||
}
|
||||
else if (resp.rc == MQTT_UNACCEPTABLE_PROTOCOL_VERSION)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" ClientID : %s Requested Protocol version is not supported.\n", client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n",
|
||||
client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_SERVER_UNAVAILABLE)
|
||||
{
|
||||
rc = MQTTSN_RC_REJECTED_CONGESTED;
|
||||
WRITELOG(" ClientID : %s The Network Connection has been made but the MQTT service is unavailable.\n",
|
||||
client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_BAD_USERNAME_OR_PASSWORD)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" Gateway Configuration Error: The data in the user name or password is malformed.\n");
|
||||
}
|
||||
else if (resp.rc == MQTT_NOT_AUTHORIZED)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" Gateway Configuration Error: The Client is not authorized to connect.\n");
|
||||
}
|
||||
/* convert MQTT ReturnCode to MQTT-SN one */
|
||||
if (resp.rc == MQTT_CONNECTION_ACCEPTED)
|
||||
{
|
||||
rc = MQTTSN_RC_ACCEPTED;
|
||||
}
|
||||
else if (resp.rc == MQTT_UNACCEPTABLE_PROTOCOL_VERSION)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" ClientID : %s Requested Protocol version is not supported.\n", client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n", client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_SERVER_UNAVAILABLE)
|
||||
{
|
||||
rc = MQTTSN_RC_REJECTED_CONGESTED;
|
||||
WRITELOG(" ClientID : %s The Network Connection has been made but the MQTT service is unavailable.\n",
|
||||
client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_BAD_USERNAME_OR_PASSWORD)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" Gateway Configuration Error: The data in the user name or password is malformed.\n");
|
||||
}
|
||||
else if (resp.rc == MQTT_NOT_AUTHORIZED)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" Gateway Configuration Error: The Client is not authorized to connect.\n");
|
||||
}
|
||||
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setCONNACK(rc);
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setCONNACK(rc);
|
||||
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
client->connackSended(rc); // update the client's status
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
client->connackSended(rc); // update the client's status
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
|
||||
void MQTTGWConnectionHandler::handlePingresp(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setPINGRESP();
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
client->updateStatus(snPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setPINGRESP();
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
client->updateStatus(snPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
|
||||
void MQTTGWConnectionHandler::handleDisconnect(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
client->disconnected();
|
||||
client->getNetwork()->close();
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
client->disconnected();
|
||||
client->getNetwork()->close();
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@ namespace MQTTSNGW
|
||||
class MQTTGWConnectionHandler
|
||||
{
|
||||
public:
|
||||
MQTTGWConnectionHandler(Gateway* gateway);
|
||||
~MQTTGWConnectionHandler();
|
||||
void handleConnack(Client* client, MQTTGWPacket* packet);
|
||||
void handlePingresp(Client* client, MQTTGWPacket* packet);
|
||||
void handleDisconnect(Client* client, MQTTGWPacket* packet);
|
||||
MQTTGWConnectionHandler(Gateway* gateway);
|
||||
~MQTTGWConnectionHandler();
|
||||
void handleConnack(Client* client, MQTTGWPacket* packet);
|
||||
void handlePingresp(Client* client, MQTTGWPacket* packet);
|
||||
void handleDisconnect(Client* client, MQTTGWPacket* packet);
|
||||
private:
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,9 +28,8 @@ void writeInt(unsigned char** pptr, int msgId);
|
||||
/**
|
||||
* List of the predefined MQTT v3 packet names.
|
||||
*/
|
||||
static const char* mqtt_packet_names[] =
|
||||
{ "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP", "SUBSCRIBE", "SUBACK",
|
||||
"UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
|
||||
static const char* mqtt_packet_names[] = { "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP",
|
||||
"SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
|
||||
|
||||
/**
|
||||
* Encodes the message length according to the MQTT algorithm
|
||||
@@ -40,17 +39,18 @@ static const char* mqtt_packet_names[] =
|
||||
*/
|
||||
int MQTTPacket_encode(char* buf, int length)
|
||||
{
|
||||
int rc = 0;
|
||||
do
|
||||
{
|
||||
char d = length % 128;
|
||||
length /= 128;
|
||||
/* if there are more digits to encode, set the top bit of this digit */
|
||||
if (length > 0)
|
||||
d |= 0x80;
|
||||
buf[rc++] = d;
|
||||
} while (length > 0);
|
||||
return rc;
|
||||
int rc = 0;
|
||||
do
|
||||
{
|
||||
char d = length % 128;
|
||||
length /= 128;
|
||||
/* if there are more digits to encode, set the top bit of this digit */
|
||||
if (length > 0)
|
||||
d |= 0x80;
|
||||
buf[rc++] = d;
|
||||
}
|
||||
while (length > 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,10 +60,10 @@ int MQTTPacket_encode(char* buf, int length)
|
||||
*/
|
||||
int readInt(char** pptr)
|
||||
{
|
||||
char* ptr = *pptr;
|
||||
int len = 256 * ((unsigned char) (*ptr)) + (unsigned char) (*(ptr + 1));
|
||||
*pptr += 2;
|
||||
return len;
|
||||
char* ptr = *pptr;
|
||||
int len = 256 * ((unsigned char) (*ptr)) + (unsigned char) (*(ptr + 1));
|
||||
*pptr += 2;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,20 +80,20 @@ int readInt(char** pptr)
|
||||
*/
|
||||
char* readUTFlen(char** pptr, char* enddata, int* len)
|
||||
{
|
||||
char* string = NULL;
|
||||
char* string = NULL;
|
||||
|
||||
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
|
||||
{
|
||||
*len = readInt(pptr);
|
||||
if (&(*pptr)[*len] <= enddata)
|
||||
{
|
||||
string = (char*)calloc(*len + 1, 1);
|
||||
memcpy(string, *pptr, (size_t)*len);
|
||||
string[*len] = '\0';
|
||||
*pptr += *len;
|
||||
}
|
||||
}
|
||||
return string;
|
||||
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
|
||||
{
|
||||
*len = readInt(pptr);
|
||||
if (&(*pptr)[*len] <= enddata)
|
||||
{
|
||||
string = (char*) calloc(*len + 1, 1);
|
||||
memcpy(string, *pptr, (size_t) *len);
|
||||
string[*len] = '\0';
|
||||
*pptr += *len;
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,8 +108,8 @@ char* readUTFlen(char** pptr, char* enddata, int* len)
|
||||
*/
|
||||
char* readUTF(char** pptr, char* enddata)
|
||||
{
|
||||
int len;
|
||||
return readUTFlen(pptr, enddata, &len);
|
||||
int len;
|
||||
return readUTFlen(pptr, enddata, &len);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,9 +119,9 @@ char* readUTF(char** pptr, char* enddata)
|
||||
*/
|
||||
unsigned char readChar(char** pptr)
|
||||
{
|
||||
unsigned char c = **pptr;
|
||||
(*pptr)++;
|
||||
return c;
|
||||
unsigned char c = **pptr;
|
||||
(*pptr)++;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,8 +131,8 @@ unsigned char readChar(char** pptr)
|
||||
*/
|
||||
void writeChar(unsigned char** pptr, char c)
|
||||
{
|
||||
**pptr = c;
|
||||
(*pptr)++;
|
||||
**pptr = c;
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,10 +142,10 @@ void writeChar(unsigned char** pptr, char c)
|
||||
*/
|
||||
void writeInt(unsigned char** pptr, int anInt)
|
||||
{
|
||||
**pptr = (unsigned char)(anInt / 256);
|
||||
(*pptr)++;
|
||||
**pptr = (unsigned char)(anInt % 256);
|
||||
(*pptr)++;
|
||||
**pptr = (unsigned char) (anInt / 256);
|
||||
(*pptr)++;
|
||||
**pptr = (unsigned char) (anInt % 256);
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,10 +155,10 @@ void writeInt(unsigned char** pptr, int anInt)
|
||||
*/
|
||||
void writeUTF(unsigned char** pptr, const char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
writeInt(pptr, len);
|
||||
memcpy(*pptr, string, (size_t)len);
|
||||
*pptr += len;
|
||||
int len = (int) strlen(string);
|
||||
writeInt(pptr, len);
|
||||
memcpy(*pptr, string, (size_t) len);
|
||||
*pptr += len;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,479 +167,480 @@ void writeUTF(unsigned char** pptr, const char* string)
|
||||
*/
|
||||
MQTTGWPacket::MQTTGWPacket()
|
||||
{
|
||||
_data = 0;
|
||||
_header.byte = 0;
|
||||
_remainingLength = 0;
|
||||
_data = 0;
|
||||
_header.byte = 0;
|
||||
_remainingLength = 0;
|
||||
}
|
||||
|
||||
MQTTGWPacket::~MQTTGWPacket()
|
||||
{
|
||||
if (_data)
|
||||
{
|
||||
free(_data);
|
||||
}
|
||||
if (_data)
|
||||
{
|
||||
free(_data);
|
||||
}
|
||||
}
|
||||
|
||||
int MQTTGWPacket::recv(Network* network)
|
||||
{
|
||||
int len = 0;
|
||||
int multiplier = 1;
|
||||
unsigned char c;
|
||||
int len = 0;
|
||||
int multiplier = 1;
|
||||
unsigned char c;
|
||||
|
||||
/* read First Byte of Packet */
|
||||
int rc = network->recv((unsigned char*)&_header.byte, 1);
|
||||
if ( rc <= 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
/* read RemainingLength */
|
||||
do
|
||||
{
|
||||
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
if (network->recv(&c, 1) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
_remainingLength += (c & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
/* read First Byte of Packet */
|
||||
int rc = network->recv((unsigned char*) &_header.byte, 1);
|
||||
if (rc <= 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
/* read RemainingLength */
|
||||
do
|
||||
{
|
||||
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
if (network->recv(&c, 1) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
_remainingLength += (c & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
}
|
||||
while ((c & 128) != 0);
|
||||
|
||||
if ( _remainingLength > 0 )
|
||||
{
|
||||
/* allocate buffer */
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if ( !_data )
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
if (_remainingLength > 0)
|
||||
{
|
||||
/* allocate buffer */
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (!_data)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* read Payload */
|
||||
int remlen = network->recv(_data, _remainingLength);
|
||||
/* read Payload */
|
||||
int remlen = network->recv(_data, _remainingLength);
|
||||
|
||||
if (remlen == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if ( remlen != _remainingLength )
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
return 1 + len + _remainingLength;
|
||||
if (remlen == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (remlen != _remainingLength)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
return 1 + len + _remainingLength;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::send(Network* network)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
memset(buf, 0, MQTTSNGW_MAX_PACKET_SIZE);
|
||||
int len = getPacketData(buf);
|
||||
return network->send(buf, len);
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
memset(buf, 0, MQTTSNGW_MAX_PACKET_SIZE);
|
||||
int len = getPacketData(buf);
|
||||
return network->send(buf, len);
|
||||
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getAck(Ack* ack)
|
||||
{
|
||||
if (PUBACK != _header.bits.type && PUBREC != _header.bits.type && PUBREL != _header.bits.type
|
||||
&& PUBCOMP != _header.bits.type && UNSUBACK != _header.bits.type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char* ptr = (char*) _data;
|
||||
ack->header.byte = _header.byte;
|
||||
ack->msgId = readInt((char**) &ptr);
|
||||
return 1;
|
||||
if (PUBACK != _header.bits.type && PUBREC != _header.bits.type && PUBREL != _header.bits.type
|
||||
&& PUBCOMP != _header.bits.type && UNSUBACK != _header.bits.type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char* ptr = (char*) _data;
|
||||
ack->header.byte = _header.byte;
|
||||
ack->msgId = readInt((char**) &ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getCONNACK(Connack* resp)
|
||||
{
|
||||
if (_header.bits.type != CONNACK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char* ptr = (char*) _data;
|
||||
resp->header.byte = _header.byte;
|
||||
resp->flags.all = *ptr++;
|
||||
resp->rc = readChar(&ptr);
|
||||
return 1;
|
||||
if (_header.bits.type != CONNACK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char* ptr = (char*) _data;
|
||||
resp->header.byte = _header.byte;
|
||||
resp->flags.all = *ptr++;
|
||||
resp->rc = readChar(&ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getSUBACK(unsigned short* msgId, unsigned char* rc)
|
||||
{
|
||||
if (_header.bits.type != SUBACK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char *ptr = (char*) _data;
|
||||
*msgId = readInt((char**) &ptr);
|
||||
*rc = readChar(&ptr);
|
||||
return 1;
|
||||
if (_header.bits.type != SUBACK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char *ptr = (char*) _data;
|
||||
*msgId = readInt((char**) &ptr);
|
||||
*rc = readChar(&ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getPUBLISH(Publish* pub)
|
||||
{
|
||||
if (_header.bits.type != PUBLISH)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char* ptr = (char*) _data;
|
||||
pub->header = _header;
|
||||
pub->topiclen = readInt((char**) &ptr);
|
||||
pub->topic = (char*) _data + 2;
|
||||
ptr += pub->topiclen;
|
||||
if (_header.bits.qos > 0)
|
||||
{
|
||||
pub->msgId = readInt(&ptr);
|
||||
pub->payloadlen = _remainingLength - pub->topiclen - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
pub->msgId = 0;
|
||||
pub->payloadlen = _remainingLength - pub->topiclen - 2;
|
||||
}
|
||||
pub->payload = ptr;
|
||||
return 1;
|
||||
if (_header.bits.type != PUBLISH)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char* ptr = (char*) _data;
|
||||
pub->header = _header;
|
||||
pub->topiclen = readInt((char**) &ptr);
|
||||
pub->topic = (char*) _data + 2;
|
||||
ptr += pub->topiclen;
|
||||
if (_header.bits.qos > 0)
|
||||
{
|
||||
pub->msgId = readInt(&ptr);
|
||||
pub->payloadlen = _remainingLength - pub->topiclen - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
pub->msgId = 0;
|
||||
pub->payloadlen = _remainingLength - pub->topiclen - 2;
|
||||
}
|
||||
pub->payload = ptr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username, unsigned char* password)
|
||||
{
|
||||
clearData();
|
||||
_header = connect->header;
|
||||
clearData();
|
||||
_header = connect->header;
|
||||
|
||||
_remainingLength = ((connect->version == 3) ? 12 : 10) + (int)strlen(connect->clientID) + 2;
|
||||
if (connect->flags.bits.will)
|
||||
{
|
||||
_remainingLength += (int)strlen(connect->willTopic) + 2 + (int)strlen(connect->willMsg) + 2;
|
||||
}
|
||||
if ( connect->flags.bits.username )
|
||||
{
|
||||
_remainingLength += (int)strlen((char*) username) + 2;
|
||||
}
|
||||
if (connect->flags.bits.password)
|
||||
{
|
||||
_remainingLength += (int)strlen((char*) password) + 2;
|
||||
}
|
||||
_remainingLength = ((connect->version == 3) ? 12 : 10) + (int) strlen(connect->clientID) + 2;
|
||||
if (connect->flags.bits.will)
|
||||
{
|
||||
_remainingLength += (int) strlen(connect->willTopic) + 2 + (int) strlen(connect->willMsg) + 2;
|
||||
}
|
||||
if (connect->flags.bits.username)
|
||||
{
|
||||
_remainingLength += (int) strlen((char*) username) + 2;
|
||||
}
|
||||
if (connect->flags.bits.password)
|
||||
{
|
||||
_remainingLength += (int) strlen((char*) password) + 2;
|
||||
}
|
||||
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
unsigned char* ptr = _data;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
unsigned char* ptr = _data;
|
||||
|
||||
if (connect->version == 3)
|
||||
{
|
||||
writeUTF(&ptr, "MQIsdp");
|
||||
writeChar(&ptr, (char) 3);
|
||||
}
|
||||
else if (connect->version == 4)
|
||||
{
|
||||
writeUTF(&ptr, "MQTT");
|
||||
writeChar(&ptr, (char) 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (connect->version == 3)
|
||||
{
|
||||
writeUTF(&ptr, "MQIsdp");
|
||||
writeChar(&ptr, (char) 3);
|
||||
}
|
||||
else if (connect->version == 4)
|
||||
{
|
||||
writeUTF(&ptr, "MQTT");
|
||||
writeChar(&ptr, (char) 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
writeChar(&ptr, connect->flags.all);
|
||||
writeInt(&ptr, connect->keepAliveTimer);
|
||||
writeUTF(&ptr, connect->clientID);
|
||||
if (connect->flags.bits.will)
|
||||
{
|
||||
writeUTF(&ptr, connect->willTopic);
|
||||
writeUTF(&ptr, connect->willMsg);
|
||||
}
|
||||
writeChar(&ptr, connect->flags.all);
|
||||
writeInt(&ptr, connect->keepAliveTimer);
|
||||
writeUTF(&ptr, connect->clientID);
|
||||
if (connect->flags.bits.will)
|
||||
{
|
||||
writeUTF(&ptr, connect->willTopic);
|
||||
writeUTF(&ptr, connect->willMsg);
|
||||
}
|
||||
|
||||
if (connect->flags.bits.username)
|
||||
{
|
||||
writeUTF(&ptr, (const char*) username);
|
||||
}
|
||||
if (connect->flags.bits.password)
|
||||
{
|
||||
writeUTF(&ptr, (const char*) password);
|
||||
}
|
||||
return 1;
|
||||
if (connect->flags.bits.username)
|
||||
{
|
||||
writeUTF(&ptr, (const char*) username);
|
||||
}
|
||||
if (connect->flags.bits.password)
|
||||
{
|
||||
writeUTF(&ptr, (const char*) password);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId)
|
||||
{
|
||||
clearData();
|
||||
_header.byte = 0;
|
||||
_header.bits.type = SUBSCRIBE;
|
||||
_header.bits.qos = 1; // Reserved
|
||||
_remainingLength = (int)strlen(topic) + 5;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, msgId);
|
||||
writeUTF(&ptr, topic);
|
||||
writeChar(&ptr, (char) qos);
|
||||
return 1;
|
||||
}
|
||||
clearData();
|
||||
return 0;
|
||||
clearData();
|
||||
_header.byte = 0;
|
||||
_header.bits.type = SUBSCRIBE;
|
||||
_header.bits.qos = 1; // Reserved
|
||||
_remainingLength = (int) strlen(topic) + 5;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, msgId);
|
||||
writeUTF(&ptr, topic);
|
||||
writeChar(&ptr, (char) qos);
|
||||
return 1;
|
||||
}
|
||||
clearData();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::setUNSUBSCRIBE(const char* topic, unsigned short msgid)
|
||||
{
|
||||
clearData();
|
||||
_header.byte = 0;
|
||||
_header.bits.type = UNSUBSCRIBE;
|
||||
_header.bits.qos = 1;
|
||||
_remainingLength = (int)strlen(topic) + 4;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, msgid);
|
||||
writeUTF(&ptr, topic);
|
||||
return 1;
|
||||
}
|
||||
clearData();
|
||||
return 0;
|
||||
clearData();
|
||||
_header.byte = 0;
|
||||
_header.bits.type = UNSUBSCRIBE;
|
||||
_header.bits.qos = 1;
|
||||
_remainingLength = (int) strlen(topic) + 4;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, msgid);
|
||||
writeUTF(&ptr, topic);
|
||||
return 1;
|
||||
}
|
||||
clearData();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int MQTTGWPacket::setPUBLISH(Publish* pub)
|
||||
{
|
||||
clearData();
|
||||
_header.byte = pub->header.byte;
|
||||
_header.bits.type = PUBLISH;
|
||||
_remainingLength = 4 + pub->topiclen + pub->payloadlen;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, pub->topiclen);
|
||||
memcpy(ptr, pub->topic, pub->topiclen);
|
||||
ptr += pub->topiclen;
|
||||
if ( _header.bits.qos > 0 )
|
||||
{
|
||||
writeInt(&ptr, pub->msgId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_remainingLength -= 2;
|
||||
}
|
||||
memcpy(ptr, pub->payload, pub->payloadlen);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
clearData();
|
||||
return 0;
|
||||
}
|
||||
clearData();
|
||||
_header.byte = pub->header.byte;
|
||||
_header.bits.type = PUBLISH;
|
||||
_remainingLength = 4 + pub->topiclen + pub->payloadlen;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, pub->topiclen);
|
||||
memcpy(ptr, pub->topic, pub->topiclen);
|
||||
ptr += pub->topiclen;
|
||||
if (_header.bits.qos > 0)
|
||||
{
|
||||
writeInt(&ptr, pub->msgId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_remainingLength -= 2;
|
||||
}
|
||||
memcpy(ptr, pub->payload, pub->payloadlen);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
clearData();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int MQTTGWPacket::setAck(unsigned char msgType, unsigned short msgid)
|
||||
{
|
||||
clearData();
|
||||
_remainingLength = 2;
|
||||
_header.bits.type = msgType;
|
||||
_header.bits.qos = (msgType == PUBREL) ? 1 : 0;
|
||||
clearData();
|
||||
_remainingLength = 2;
|
||||
_header.bits.type = msgType;
|
||||
_header.bits.qos = (msgType == PUBREL) ? 1 : 0;
|
||||
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* data = _data;
|
||||
writeInt(&data, msgid);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* data = _data;
|
||||
writeInt(&data, msgid);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::setHeader(unsigned char msgType)
|
||||
{
|
||||
clearData();
|
||||
if (msgType < CONNECT || msgType > DISCONNECT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
_header.bits.type = msgType;
|
||||
return 0;
|
||||
clearData();
|
||||
if (msgType < CONNECT || msgType > DISCONNECT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
_header.bits.type = msgType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getType(void)
|
||||
{
|
||||
return _header.bits.type;
|
||||
return _header.bits.type;
|
||||
}
|
||||
|
||||
const char* MQTTGWPacket::getName(void)
|
||||
{
|
||||
return getType() > DISCONNECT ? "UNKNOWN" : mqtt_packet_names[getType()];
|
||||
return getType() > DISCONNECT ? "UNKNOWN" : mqtt_packet_names[getType()];
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getPacketData(unsigned char* buf)
|
||||
{
|
||||
unsigned char* ptr = buf;
|
||||
*ptr++ = _header.byte;
|
||||
int len = MQTTPacket_encode((char*)ptr, _remainingLength);
|
||||
ptr += len;
|
||||
memcpy(ptr, _data, _remainingLength);
|
||||
return 1 + len + _remainingLength;
|
||||
unsigned char* ptr = buf;
|
||||
*ptr++ = _header.byte;
|
||||
int len = MQTTPacket_encode((char*) ptr, _remainingLength);
|
||||
ptr += len;
|
||||
memcpy(ptr, _data, _remainingLength);
|
||||
return 1 + len + _remainingLength;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getPacketLength(void)
|
||||
{
|
||||
char buf[4];
|
||||
return 1 + MQTTPacket_encode(buf, _remainingLength) + _remainingLength;
|
||||
char buf[4];
|
||||
return 1 + MQTTPacket_encode(buf, _remainingLength) + _remainingLength;
|
||||
}
|
||||
|
||||
void MQTTGWPacket::clearData(void)
|
||||
{
|
||||
if (_data)
|
||||
{
|
||||
free(_data);
|
||||
}
|
||||
_header.byte = 0;
|
||||
_remainingLength = 0;
|
||||
if (_data)
|
||||
{
|
||||
free(_data);
|
||||
}
|
||||
_header.byte = 0;
|
||||
_remainingLength = 0;
|
||||
}
|
||||
|
||||
char* MQTTGWPacket::getMsgId(char* pbuf)
|
||||
{
|
||||
int type = getType();
|
||||
int type = getType();
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
if ( _header.bits.dup )
|
||||
{
|
||||
sprintf(pbuf, "+%04X", pub.msgId);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pbuf, " %04X", pub.msgId);
|
||||
}
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
sprintf(pbuf, " %02X%02X", _data[0], _data[1]);
|
||||
break;
|
||||
default:
|
||||
sprintf(pbuf, " ");
|
||||
break;
|
||||
}
|
||||
if ( strcmp(pbuf, " 0000") == 0 )
|
||||
{
|
||||
sprintf(pbuf, " ");
|
||||
}
|
||||
return pbuf;
|
||||
switch (type)
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
if (_header.bits.dup)
|
||||
{
|
||||
sprintf(pbuf, "+%04X", pub.msgId);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pbuf, " %04X", pub.msgId);
|
||||
}
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
sprintf(pbuf, " %02X%02X", _data[0], _data[1]);
|
||||
break;
|
||||
default:
|
||||
sprintf(pbuf, " ");
|
||||
break;
|
||||
}
|
||||
if (strcmp(pbuf, " 0000") == 0)
|
||||
{
|
||||
sprintf(pbuf, " ");
|
||||
}
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
int MQTTGWPacket::getMsgId(void)
|
||||
{
|
||||
int type = getType();
|
||||
int msgId = 0;
|
||||
int type = getType();
|
||||
int msgId = 0;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
msgId = pub.msgId;
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
msgId = 256 * (unsigned char)_data[0] + (unsigned char)_data[1];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msgId;
|
||||
switch (type)
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
msgId = pub.msgId;
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
msgId = 256 * (unsigned char) _data[0] + (unsigned char) _data[1];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msgId;
|
||||
}
|
||||
|
||||
void MQTTGWPacket::setMsgId(int msgId)
|
||||
{
|
||||
int type = getType();
|
||||
unsigned char* ptr = 0;
|
||||
int type = getType();
|
||||
unsigned char* ptr = 0;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.topiclen = 0;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
pub.msgId = msgId;
|
||||
ptr = _data + pub.topiclen;
|
||||
writeInt(&ptr, pub.msgId);
|
||||
*ptr++ = (unsigned char)(msgId / 256);
|
||||
*ptr = (unsigned char)(msgId % 256);
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
ptr = _data;
|
||||
*ptr++ = (unsigned char)(msgId / 256);
|
||||
*ptr = (unsigned char)(msgId % 256);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.topiclen = 0;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
pub.msgId = msgId;
|
||||
ptr = _data + pub.topiclen;
|
||||
writeInt(&ptr, pub.msgId);
|
||||
*ptr++ = (unsigned char) (msgId / 256);
|
||||
*ptr = (unsigned char) (msgId % 256);
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
ptr = _data;
|
||||
*ptr++ = (unsigned char) (msgId / 256);
|
||||
*ptr = (unsigned char) (msgId % 256);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char* MQTTGWPacket::print(char* pbuf)
|
||||
{
|
||||
uint8_t packetData[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
char* ptr = pbuf;
|
||||
char** pptr = &pbuf;
|
||||
int len = getPacketData(packetData);
|
||||
int size = len > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : len;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(*pptr, " %02X", packetData[i]);
|
||||
*pptr += 3;
|
||||
}
|
||||
**pptr = 0;
|
||||
return ptr;
|
||||
uint8_t packetData[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
char* ptr = pbuf;
|
||||
char** pptr = &pbuf;
|
||||
int len = getPacketData(packetData);
|
||||
int size = len > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : len;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(*pptr, " %02X", packetData[i]);
|
||||
*pptr += 3;
|
||||
}
|
||||
**pptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
MQTTGWPacket& MQTTGWPacket::operator =(MQTTGWPacket& packet)
|
||||
{
|
||||
clearData();
|
||||
this->_header.byte = packet._header.byte;
|
||||
this->_remainingLength = packet._remainingLength;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
memcpy(this->_data, packet._data, _remainingLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
clearData();
|
||||
}
|
||||
return *this;
|
||||
clearData();
|
||||
this->_header.byte = packet._header.byte;
|
||||
this->_remainingLength = packet._remainingLength;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
memcpy(this->_data, packet._data, _remainingLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
clearData();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
UTF8String MQTTGWPacket::getTopic(void)
|
||||
{
|
||||
UTF8String str = {0, nullptr};
|
||||
if ( _header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE )
|
||||
{
|
||||
char* ptr = (char*)(_data + 2);
|
||||
str.len = readInt(&ptr);
|
||||
str.data = (char*)(_data + 4);
|
||||
}
|
||||
return str;
|
||||
UTF8String str = { 0, nullptr };
|
||||
if (_header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE)
|
||||
{
|
||||
char* ptr = (char*) (_data + 2);
|
||||
str.len = readInt(&ptr);
|
||||
str.data = (char*) (_data + 4);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -31,89 +31,100 @@ typedef void* (*pf)(unsigned char, char*, size_t);
|
||||
|
||||
enum msgTypes
|
||||
{
|
||||
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
|
||||
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
|
||||
PINGREQ, PINGRESP, DISCONNECT
|
||||
CONNECT = 1,
|
||||
CONNACK,
|
||||
PUBLISH,
|
||||
PUBACK,
|
||||
PUBREC,
|
||||
PUBREL,
|
||||
PUBCOMP,
|
||||
SUBSCRIBE,
|
||||
SUBACK,
|
||||
UNSUBSCRIBE,
|
||||
UNSUBACK,
|
||||
PINGREQ,
|
||||
PINGRESP,
|
||||
DISCONNECT
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bitfields for the MQTT header byte.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/*unsigned*/ char byte; /**< the whole byte */
|
||||
/*unsigned*/
|
||||
char byte; /**< the whole byte */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
bool dup : 1; /**< DUP flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
bool retain : 1; /**< retained flag bit */
|
||||
} bits;
|
||||
struct
|
||||
{
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
bool dup : 1; /**< DUP flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
bool retain : 1; /**< retained flag bit */
|
||||
}bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
bool retain : 1; /**< retained flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
bool dup : 1; /**< DUP flag bit */
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
} bits;
|
||||
struct
|
||||
{
|
||||
bool retain :1; /**< retained flag bit */
|
||||
unsigned int qos :2; /**< QoS value, 0, 1 or 2 */
|
||||
bool dup :1; /**< DUP flag bit */
|
||||
unsigned int type :4; /**< message type nibble */
|
||||
} bits;
|
||||
#endif
|
||||
} Header;
|
||||
|
||||
|
||||
/**
|
||||
* Data for a connect packet.
|
||||
*/
|
||||
|
||||
enum MQTT_connackCodes{
|
||||
MQTT_CONNECTION_ACCEPTED ,
|
||||
MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
|
||||
MQTT_IDENTIFIER_REJECTED,
|
||||
MQTT_SERVER_UNAVAILABLE,
|
||||
MQTT_BAD_USERNAME_OR_PASSWORD,
|
||||
MQTT_NOT_AUTHORIZED
|
||||
enum MQTT_connackCodes
|
||||
{
|
||||
MQTT_CONNECTION_ACCEPTED,
|
||||
MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
|
||||
MQTT_IDENTIFIER_REJECTED,
|
||||
MQTT_SERVER_UNAVAILABLE,
|
||||
MQTT_BAD_USERNAME_OR_PASSWORD,
|
||||
MQTT_NOT_AUTHORIZED
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Header header; /**< MQTT header byte */
|
||||
union
|
||||
{
|
||||
unsigned char all; /**< all connect flags */
|
||||
Header header; /**< MQTT header byte */
|
||||
union
|
||||
{
|
||||
unsigned char all; /**< all connect flags */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
bool username : 1; /**< 3.1 user name */
|
||||
bool password : 1; /**< 3.1 password */
|
||||
bool willRetain : 1; /**< will retain setting */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
bool will : 1; /**< will flag */
|
||||
bool cleanstart : 1; /**< cleansession flag */
|
||||
int : 1; /**< unused */
|
||||
} bits;
|
||||
struct
|
||||
{
|
||||
bool username : 1; /**< 3.1 user name */
|
||||
bool password : 1; /**< 3.1 password */
|
||||
bool willRetain : 1; /**< will retain setting */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
bool will : 1; /**< will flag */
|
||||
bool cleanstart : 1; /**< cleansession flag */
|
||||
int : 1; /**< unused */
|
||||
}bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
int : 1; /**< unused */
|
||||
bool cleanstart : 1; /**< cleansession flag */
|
||||
bool will : 1; /**< will flag */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
bool willRetain : 1; /**< will retain setting */
|
||||
bool password : 1; /**< 3.1 password */
|
||||
bool username : 1; /**< 3.1 user name */
|
||||
} bits;
|
||||
struct
|
||||
{
|
||||
int :1; /**< unused */
|
||||
bool cleanstart :1; /**< cleansession flag */
|
||||
bool will :1; /**< will flag */
|
||||
unsigned int willQoS :2; /**< will QoS value */
|
||||
bool willRetain :1; /**< will retain setting */
|
||||
bool password :1; /**< 3.1 password */
|
||||
bool username :1; /**< 3.1 user name */
|
||||
} bits;
|
||||
#endif
|
||||
} flags; /**< connect flags byte */
|
||||
} flags; /**< connect flags byte */
|
||||
|
||||
char *Protocol, /**< MQTT protocol name */
|
||||
*clientID, /**< string client id */
|
||||
*willTopic, /**< will topic */
|
||||
*willMsg; /**< will payload */
|
||||
char *Protocol, /**< MQTT protocol name */
|
||||
*clientID, /**< string client id */
|
||||
*willTopic, /**< will topic */
|
||||
*willMsg; /**< will payload */
|
||||
|
||||
int keepAliveTimer; /**< keepalive timeout value in seconds */
|
||||
unsigned char version; /**< MQTT version number */
|
||||
int keepAliveTimer; /**< keepalive timeout value in seconds */
|
||||
unsigned char version; /**< MQTT version number */
|
||||
} Connect;
|
||||
|
||||
#define MQTTPacket_Connect_Initializer {{0}, {0}, nullptr, nullptr, nullptr, nullptr, 0, 0}
|
||||
@@ -121,57 +132,54 @@ typedef struct
|
||||
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
|
||||
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data for a willMessage.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char* topic;
|
||||
char* msg;
|
||||
int retained;
|
||||
int qos;
|
||||
}willMessages;
|
||||
char* topic;
|
||||
char* msg;
|
||||
int retained;
|
||||
int qos;
|
||||
} willMessages;
|
||||
|
||||
/**
|
||||
* Data for a connack packet.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Header header; /**< MQTT header byte */
|
||||
union
|
||||
{
|
||||
unsigned char all; /**< all connack flags */
|
||||
Header header; /**< MQTT header byte */
|
||||
union
|
||||
{
|
||||
unsigned char all; /**< all connack flags */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
unsigned int reserved : 7; /**< message type nibble */
|
||||
bool sessionPresent : 1; /**< was a session found on the server? */
|
||||
} bits;
|
||||
struct
|
||||
{
|
||||
unsigned int reserved : 7; /**< message type nibble */
|
||||
bool sessionPresent : 1; /**< was a session found on the server? */
|
||||
}bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
bool sessionPresent : 1; /**< was a session found on the server? */
|
||||
unsigned int reserved : 7; /**< message type nibble */
|
||||
} bits;
|
||||
struct
|
||||
{
|
||||
bool sessionPresent :1; /**< was a session found on the server? */
|
||||
unsigned int reserved :7; /**< message type nibble */
|
||||
} bits;
|
||||
#endif
|
||||
} flags; /**< connack flags byte */
|
||||
char rc; /**< connack return code */
|
||||
} flags; /**< connack flags byte */
|
||||
char rc; /**< connack return code */
|
||||
} Connack;
|
||||
|
||||
|
||||
/**
|
||||
* Data for a publish packet.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Header header; /**< MQTT header byte */
|
||||
char* topic; /**< topic string */
|
||||
int topiclen;
|
||||
int msgId; /**< MQTT message id */
|
||||
char* payload; /**< binary payload, length delimited */
|
||||
int payloadlen; /**< payload length */
|
||||
Header header; /**< MQTT header byte */
|
||||
char* topic; /**< topic string */
|
||||
int topiclen;
|
||||
int msgId; /**< MQTT message id */
|
||||
char* payload; /**< binary payload, length delimited */
|
||||
int payloadlen; /**< payload length */
|
||||
} Publish;
|
||||
|
||||
#define MQTTPacket_Publish_Initializer {{0}, nullptr, 0, 0, nullptr, 0}
|
||||
@@ -181,8 +189,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Header header; /**< MQTT header byte */
|
||||
int msgId; /**< MQTT message id */
|
||||
Header header; /**< MQTT header byte */
|
||||
int msgId; /**< MQTT message id */
|
||||
} Ack;
|
||||
|
||||
/**
|
||||
@@ -190,8 +198,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char len;
|
||||
char* data;
|
||||
unsigned char len;
|
||||
char* data;
|
||||
} UTF8String;
|
||||
|
||||
/**
|
||||
@@ -200,39 +208,41 @@ typedef struct
|
||||
class MQTTGWPacket
|
||||
{
|
||||
public:
|
||||
MQTTGWPacket();
|
||||
~MQTTGWPacket();
|
||||
int recv(Network* network);
|
||||
int send(Network* network);
|
||||
int getType(void);
|
||||
int getPacketData(unsigned char* buf);
|
||||
int getPacketLength(void);
|
||||
const char* getName(void);
|
||||
MQTTGWPacket();
|
||||
~MQTTGWPacket();
|
||||
int recv(Network* network);
|
||||
int send(Network* network);
|
||||
int getType(void);
|
||||
int getPacketData(unsigned char* buf);
|
||||
int getPacketLength(void);
|
||||
const char* getName(void);
|
||||
|
||||
int getAck(Ack* ack);
|
||||
int getCONNACK(Connack* resp);
|
||||
int getSUBACK(unsigned short* msgId, unsigned char* rc);
|
||||
int getPUBLISH(Publish* pub);
|
||||
int getAck(Ack* ack);
|
||||
int getCONNACK(Connack* resp);
|
||||
int getSUBACK(unsigned short* msgId, unsigned char* rc);
|
||||
int getPUBLISH(Publish* pub);
|
||||
|
||||
int setCONNECT(Connect* conect, unsigned char* username, unsigned char* password);
|
||||
int setPUBLISH(Publish* pub);
|
||||
int setAck(unsigned char msgType, unsigned short msgid);
|
||||
int setHeader(unsigned char msgType);
|
||||
int setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId);
|
||||
int setUNSUBSCRIBE(const char* topics, unsigned short msgid);
|
||||
int setCONNECT(Connect* conect, unsigned char* username,
|
||||
unsigned char* password);
|
||||
int setPUBLISH(Publish* pub);
|
||||
int setAck(unsigned char msgType, unsigned short msgid);
|
||||
int setHeader(unsigned char msgType);
|
||||
int setSUBSCRIBE(const char* topic, unsigned char qos,
|
||||
unsigned short msgId);
|
||||
int setUNSUBSCRIBE(const char* topics, unsigned short msgid);
|
||||
|
||||
UTF8String getTopic(void);
|
||||
char* getMsgId(char* buf);
|
||||
int getMsgId(void);
|
||||
void setMsgId(int msgId);
|
||||
char* print(char* buf);
|
||||
MQTTGWPacket& operator =(MQTTGWPacket& packet);
|
||||
UTF8String getTopic(void);
|
||||
char* getMsgId(char* buf);
|
||||
int getMsgId(void);
|
||||
void setMsgId(int msgId);
|
||||
char* print(char* buf);
|
||||
MQTTGWPacket& operator =(MQTTGWPacket& packet);
|
||||
|
||||
private:
|
||||
void clearData(void);
|
||||
Header _header;
|
||||
int _remainingLength;
|
||||
unsigned char* _data;
|
||||
void clearData(void);
|
||||
Header _header;
|
||||
int _remainingLength;
|
||||
unsigned char* _data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ char* currentDateTime(void);
|
||||
|
||||
MQTTGWPublishHandler::MQTTGWPublishHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTGWPublishHandler::~MQTTGWPublishHandler()
|
||||
@@ -37,266 +37,283 @@ MQTTGWPublishHandler::~MQTTGWPublishHandler()
|
||||
|
||||
void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
if ( !client->isActive() && !client->isSleep() && !client->isAwake())
|
||||
{
|
||||
WRITELOG("%s The client is neither active nor sleep %s%s\n", ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
if (!client->isActive() && !client->isSleep() && !client->isAwake())
|
||||
{
|
||||
WRITELOG("%s The client is neither active nor sleep %s%s\n",
|
||||
ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* client is sleeping. save PUBLISH */
|
||||
if ( client->isSleep() )
|
||||
{
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
/* client is sleeping. save PUBLISH */
|
||||
if (client->isSleep())
|
||||
{
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
|
||||
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(),
|
||||
RIGHTARROW, client->getClientId(), "is sleeping. a message was saved.");
|
||||
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(),
|
||||
RIGHTARROW, client->getClientId(), "is sleeping. a message was saved.");
|
||||
|
||||
if (pub.header.bits.qos == 1)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
}
|
||||
else if ( pub.header.bits.qos == 2)
|
||||
{
|
||||
replyACK(client, &pub, PUBREC);
|
||||
}
|
||||
if (pub.header.bits.qos == 1)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
}
|
||||
else if (pub.header.bits.qos == 2)
|
||||
{
|
||||
replyACK(client, &pub, PUBREC);
|
||||
}
|
||||
|
||||
MQTTGWPacket* msg = new MQTTGWPacket();
|
||||
*msg = *packet;
|
||||
if ( msg->getType() == 0 )
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
return;
|
||||
}
|
||||
client->setClientSleepPacket(msg);
|
||||
return;
|
||||
}
|
||||
MQTTGWPacket* msg = new MQTTGWPacket();
|
||||
*msg = *packet;
|
||||
if (msg->getType() == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
return;
|
||||
}
|
||||
client->setClientSleepPacket(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
|
||||
/* create MQTTSN_topicid */
|
||||
MQTTSN_topicid topicId;
|
||||
uint16_t id = 0;
|
||||
/* create MQTTSN_topicid */
|
||||
MQTTSN_topicid topicId;
|
||||
uint16_t id = 0;
|
||||
|
||||
if (pub.topiclen <= 2)
|
||||
{
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_SHORT;
|
||||
*(topicId.data.short_name) = *pub.topic;
|
||||
*(topicId.data.short_name + 1) = *(pub.topic + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pub.topiclen <= 2)
|
||||
{
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_SHORT;
|
||||
*(topicId.data.short_name) = *pub.topic;
|
||||
*(topicId.data.short_name + 1) = *(pub.topic + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
Topic* tp = client->getTopics()->getTopicByName(&topicId);
|
||||
|
||||
if ( tp )
|
||||
if (tp)
|
||||
{
|
||||
topicId.type = tp->getType();
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
topicId.data.id = tp->getTopicId();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This message might be subscribed with wild card. */
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
Topic* topic = client->getTopics()->match(&topicId);
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG(" Invalid Topic. PUBLISH message is canceled.\n");
|
||||
if (pub.header.bits.qos == 1)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
}
|
||||
else if ( pub.header.bits.qos == 2 )
|
||||
{
|
||||
replyACK(client, &pub, PUBREC);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This message might be subscribed with wild card or not cleanSession*/
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
Topic* topic = client->getTopics()->match(&topicId);
|
||||
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
if (topic == nullptr && client->isCleanSession())
|
||||
{
|
||||
WRITELOG("%sMQTTGWPublishHandler Invalid Topic. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
if (pub.header.bits.qos == 1)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
}
|
||||
else if (pub.header.bits.qos == 2)
|
||||
{
|
||||
replyACK(client, &pub, PUBREC);
|
||||
}
|
||||
|
||||
/* add the Topic and get a TopicId */
|
||||
topic = client->getTopics()->add(&topicId);
|
||||
id = topic->getTopicId();
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
|
||||
if (id > 0)
|
||||
{
|
||||
/* create REGISTER */
|
||||
MQTTSNPacket* regPacket = new MQTTSNPacket();
|
||||
if (topic == nullptr)
|
||||
{
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
topicId.data.id = 0;
|
||||
}
|
||||
|
||||
MQTTSNString topicName = MQTTSNString_initializer;
|
||||
topicName.lenstring.len = topicId.data.long_.len;
|
||||
topicName.lenstring.data = topicId.data.long_.name;
|
||||
/* add the Topic and get a TopicId */
|
||||
topic = client->getTopics()->add(&topicId);
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG(
|
||||
"%sMQTTGWPublishHandler Can't Add a Topic. MAX_TOPIC_PAR_CLIENT is exceeded. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
id = topic->getTopicId();
|
||||
if (id > 0)
|
||||
{
|
||||
/* create REGISTER */
|
||||
MQTTSNPacket* regPacket = new MQTTSNPacket();
|
||||
|
||||
uint16_t regackMsgId = client->getNextSnMsgId();
|
||||
regPacket->setREGISTER(id, regackMsgId, &topicName);
|
||||
MQTTSNString topicName = MQTTSNString_initializer;
|
||||
topicName.lenstring.len = topicId.data.long_.len;
|
||||
topicName.lenstring.data = topicId.data.long_.name;
|
||||
|
||||
/* send REGISTER */
|
||||
Event* evrg = new Event();
|
||||
evrg->setClientSendEvent(client, regPacket);
|
||||
_gateway->getClientSendQue()->post(evrg);
|
||||
uint16_t regackMsgId = client->getNextSnMsgId();
|
||||
regPacket->setREGISTER(id, regackMsgId, &topicName);
|
||||
|
||||
/* send PUBLISH */
|
||||
topicId.data.id = id;
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos,
|
||||
(uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload,
|
||||
pub.payloadlen);
|
||||
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* send REGISTER */
|
||||
Event* evrg = new Event();
|
||||
evrg->setClientSendEvent(client, regPacket);
|
||||
_gateway->getClientSendQue()->post(evrg);
|
||||
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
|
||||
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
/* send PUBLISH */
|
||||
topicId.data.id = id;
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
|
||||
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
|
||||
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
|
||||
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::replyACK(Client* client, Publish* pub, int type)
|
||||
{
|
||||
MQTTGWPacket* pubAck = new MQTTGWPacket();
|
||||
pubAck->setAck(type, (uint16_t)pub->msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubAck);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
MQTTGWPacket* pubAck = new MQTTGWPacket();
|
||||
pubAck->setAck(type, (uint16_t) pub->msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubAck);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t)ack.msgId);
|
||||
if (topicId)
|
||||
{
|
||||
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
|
||||
mqttsnPacket->setPUBACK(topicId->getTopicId(), (uint16_t)ack.msgId, 0);
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t) ack.msgId);
|
||||
if (topicId)
|
||||
{
|
||||
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
|
||||
mqttsnPacket->setPUBACK(topicId->getTopicId(), (uint16_t) ack.msgId, 0);
|
||||
|
||||
client->eraseWaitedPubTopicId((uint16_t)ack.msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, mqttsnPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return;
|
||||
}
|
||||
WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t)ack.msgId, client->getClientId());
|
||||
client->eraseWaitedPubTopicId((uint16_t) ack.msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, mqttsnPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return;
|
||||
}
|
||||
WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t) ack.msgId,
|
||||
client->getClientId());
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int type)
|
||||
{
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
|
||||
if ( client->isActive() || client->isAwake() )
|
||||
{
|
||||
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
|
||||
if (type == PUBREC)
|
||||
{
|
||||
mqttsnPacket->setPUBREC((uint16_t) ack.msgId);
|
||||
}
|
||||
else if (type == PUBREL)
|
||||
{
|
||||
mqttsnPacket->setPUBREL((uint16_t) ack.msgId);
|
||||
}
|
||||
else if (type == PUBCOMP)
|
||||
{
|
||||
mqttsnPacket->setPUBCOMP((uint16_t) ack.msgId);
|
||||
}
|
||||
if (client->isActive() || client->isAwake())
|
||||
{
|
||||
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
|
||||
if (type == PUBREC)
|
||||
{
|
||||
mqttsnPacket->setPUBREC((uint16_t) ack.msgId);
|
||||
}
|
||||
else if (type == PUBREL)
|
||||
{
|
||||
mqttsnPacket->setPUBREL((uint16_t) ack.msgId);
|
||||
}
|
||||
else if (type == PUBCOMP)
|
||||
{
|
||||
mqttsnPacket->setPUBCOMP((uint16_t) ack.msgId);
|
||||
}
|
||||
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, mqttsnPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
else if ( client->isSleep() )
|
||||
{
|
||||
if (type == PUBREL)
|
||||
{
|
||||
MQTTGWPacket* pubComp = new MQTTGWPacket();
|
||||
pubComp->setAck(PUBCOMP, (uint16_t)ack.msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubComp);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, mqttsnPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
else if (client->isSleep())
|
||||
{
|
||||
if (type == PUBREL)
|
||||
{
|
||||
MQTTGWPacket* pubComp = new MQTTGWPacket();
|
||||
pubComp->setAck(PUBCOMP, (uint16_t) ack.msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubComp);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
handlePuback(newClient, packet);
|
||||
}
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handlePuback(newClient, packet);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handleAggregateAck(Client* client, MQTTGWPacket* packet, int type)
|
||||
{
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
handleAck(newClient, packet,type);
|
||||
}
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handleAck(newClient, packet, type);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handleAggregatePubrel(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
replyACK(client, &pub, PUBCOMP);
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
replyACK(client, &pub, PUBCOMP);
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
|
||||
string* topicName = new string(pub.topic, pub.topiclen); // topic deletes topicName when the topic is deleted
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
|
||||
string* topicName = new string(pub.topic, pub.topiclen); // topic deletes topicName when the topic is deleted
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
// ToDo: need to refactor
|
||||
ClientTopicElement* elm = _gateway->getAdapterManager()->getAggregater()->getClientElement(&topic);
|
||||
|
||||
// ToDo: need to refactor
|
||||
ClientTopicElement* elm = _gateway->getAdapterManager()->getAggregater()->getClientElement(&topic);
|
||||
while (elm != nullptr)
|
||||
{
|
||||
Client* devClient = elm->getClient();
|
||||
MQTTGWPacket* msg = new MQTTGWPacket();
|
||||
*msg = *packet;
|
||||
|
||||
while ( elm != nullptr )
|
||||
{
|
||||
Client* devClient = elm->getClient();
|
||||
MQTTGWPacket* msg = new MQTTGWPacket();
|
||||
*msg = *packet;
|
||||
if (msg->getType() == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( msg->getType() == 0 )
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
break;
|
||||
}
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerRecvEvent(devClient, msg);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerRecvEvent(devClient, msg);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
|
||||
elm = elm->getNextClientElement();
|
||||
}
|
||||
elm = elm->getNextClientElement();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,25 +26,23 @@ namespace MQTTSNGW
|
||||
class MQTTGWPublishHandler
|
||||
{
|
||||
public:
|
||||
MQTTGWPublishHandler(Gateway* gateway);
|
||||
~MQTTGWPublishHandler();
|
||||
void handlePublish(Client* client, MQTTGWPacket* packet);
|
||||
void handlePuback(Client* client, MQTTGWPacket* packet);
|
||||
void handleAck(Client* client, MQTTGWPacket* packet, int type);
|
||||
MQTTGWPublishHandler(Gateway* gateway);
|
||||
~MQTTGWPublishHandler();
|
||||
void handlePublish(Client* client, MQTTGWPacket* packet);
|
||||
void handlePuback(Client* client, MQTTGWPacket* packet);
|
||||
void handleAck(Client* client, MQTTGWPacket* packet, int type);
|
||||
|
||||
void handleAggregatePublish(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregatePuback(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregateAck(Client* client, MQTTGWPacket* packet, int type);
|
||||
void handleAggregatePubrel(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregatePublish(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregatePuback(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregateAck(Client* client, MQTTGWPacket* packet, int type);
|
||||
void handleAggregatePubrel(Client* client, MQTTGWPacket* packet);
|
||||
|
||||
private:
|
||||
void replyACK(Client* client, Publish* pub, int type);
|
||||
void replyACK(Client* client, Publish* pub, int type);
|
||||
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTGWPUBLISHHANDLER_H_ */
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
MQTTGWSubscribeHandler::MQTTGWSubscribeHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTGWSubscribeHandler::~MQTTGWSubscribeHandler()
|
||||
@@ -32,68 +32,67 @@ MQTTGWSubscribeHandler::~MQTTGWSubscribeHandler()
|
||||
|
||||
void MQTTGWSubscribeHandler::handleSuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
uint8_t returnCode;
|
||||
int qos = 0;
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
uint8_t returnCode;
|
||||
int qos = 0;
|
||||
|
||||
packet->getSUBACK(&msgId, &rc);
|
||||
TopicIdMapElement* topicId = client->getWaitedSubTopicId(msgId);
|
||||
packet->getSUBACK(&msgId, &rc);
|
||||
TopicIdMapElement* topicId = client->getWaitedSubTopicId(msgId);
|
||||
|
||||
if (topicId)
|
||||
{
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
if (topicId)
|
||||
{
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
|
||||
if (rc == 0x80)
|
||||
{
|
||||
returnCode = MQTTSN_RC_REJECTED_INVALID_TOPIC_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnCode = MQTTSN_RC_ACCEPTED;
|
||||
qos = rc;
|
||||
}
|
||||
snPacket->setSUBACK(qos, topicId->getTopicId(), msgId, returnCode);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, snPacket);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
if (rc == 0x80)
|
||||
{
|
||||
returnCode = MQTTSN_RC_REJECTED_INVALID_TOPIC_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnCode = MQTTSN_RC_ACCEPTED;
|
||||
qos = rc;
|
||||
}
|
||||
snPacket->setSUBACK(qos, topicId->getTopicId(), msgId, returnCode);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, snPacket);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
client->eraseWaitedSubTopicId(msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTGWSubscribeHandler::handleUnsuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setUNSUBACK(ack.msgId);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, snPacket);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setUNSUBACK(ack.msgId);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, snPacket);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
}
|
||||
|
||||
void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
handleSuback(newClient, packet);
|
||||
}
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handleSuback(newClient, packet);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
handleUnsuback(newClient, packet);
|
||||
}
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handleUnsuback(newClient, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,15 +27,15 @@ namespace MQTTSNGW
|
||||
class MQTTGWSubscribeHandler
|
||||
{
|
||||
public:
|
||||
MQTTGWSubscribeHandler(Gateway* gateway);
|
||||
~MQTTGWSubscribeHandler();
|
||||
void handleSuback(Client* clnode, MQTTGWPacket* packet);
|
||||
void handleUnsuback(Client* clnode, MQTTGWPacket* packet);
|
||||
void handleAggregateSuback(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregateUnsuback(Client* client, MQTTGWPacket* packet);
|
||||
MQTTGWSubscribeHandler(Gateway* gateway);
|
||||
~MQTTGWSubscribeHandler();
|
||||
void handleSuback(Client* clnode, MQTTGWPacket* packet);
|
||||
void handleUnsuback(Client* clnode, MQTTGWPacket* packet);
|
||||
void handleAggregateSuback(Client* client, MQTTGWPacket* packet);
|
||||
void handleAggregateUnsuback(Client* client, MQTTGWPacket* packet);
|
||||
|
||||
private:
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ using namespace MQTTSNGW;
|
||||
=====================================*/
|
||||
MQTTSNAggregateConnectionHandler::MQTTSNAggregateConnectionHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
|
||||
@@ -36,124 +36,121 @@ MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CONNECT
|
||||
*/
|
||||
void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
if ( packet->getCONNECT(&data) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
MQTTSNPacket_connectData data;
|
||||
if (packet->getCONNECT(&data) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* return CONNACK when the client is sleeping */
|
||||
if ( client->isSleep() || client->isAwake() )
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
/* return CONNACK when the client is sleeping */
|
||||
if (client->isSleep() || client->isAwake())
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
|
||||
//* clear ConnectData of Client */
|
||||
Connect* connectData = client->getConnectData();
|
||||
memset(connectData, 0, sizeof(Connect));
|
||||
//* clear ConnectData of Client */
|
||||
Connect* connectData = client->getConnectData();
|
||||
memset(connectData, 0, sizeof(Connect));
|
||||
|
||||
client->disconnected();
|
||||
client->disconnected();
|
||||
|
||||
Topics* topics = client->getTopics();
|
||||
Topics* topics = client->getTopics();
|
||||
|
||||
/* CONNECT was not sent yet. prepare Connect data */
|
||||
/* CONNECT was not sent yet. prepare Connect data */
|
||||
|
||||
client->setSessionStatus(false);
|
||||
if (data.cleansession)
|
||||
{
|
||||
/* reset the table of msgNo and TopicId pare */
|
||||
client->clearWaitedPubTopicId();
|
||||
client->clearWaitedSubTopicId();
|
||||
|
||||
client->setSessionStatus(false);
|
||||
if (data.cleansession)
|
||||
{
|
||||
/* reset the table of msgNo and TopicId pare */
|
||||
client->clearWaitedPubTopicId();
|
||||
client->clearWaitedSubTopicId();
|
||||
/* renew the TopicList */
|
||||
if (topics)
|
||||
{
|
||||
Topic* tp = topics->getFirstTopic();
|
||||
while (tp != nullptr)
|
||||
{
|
||||
if (tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(tp, client);
|
||||
}
|
||||
tp = topics->getNextTopic(tp);
|
||||
}
|
||||
topics->eraseNormal();
|
||||
}
|
||||
client->setSessionStatus(true);
|
||||
}
|
||||
|
||||
/* renew the TopicList */
|
||||
if (topics)
|
||||
{
|
||||
Topic* tp = topics->getFirstTopic();
|
||||
while( tp != nullptr )
|
||||
{
|
||||
if ( tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL )
|
||||
{
|
||||
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(tp, client);
|
||||
}
|
||||
tp = topics->getNextTopic(tp);
|
||||
}
|
||||
topics->eraseNormal();
|
||||
}
|
||||
client->setSessionStatus(true);
|
||||
}
|
||||
if (data.willFlag)
|
||||
{
|
||||
/* create & send WILLTOPICREQ message to the client */
|
||||
MQTTSNPacket* reqTopic = new MQTTSNPacket();
|
||||
reqTopic->setWILLTOPICREQ();
|
||||
Event* evwr = new Event();
|
||||
evwr->setClientSendEvent(client, reqTopic);
|
||||
|
||||
if (data.willFlag)
|
||||
{
|
||||
/* create & send WILLTOPICREQ message to the client */
|
||||
MQTTSNPacket* reqTopic = new MQTTSNPacket();
|
||||
reqTopic->setWILLTOPICREQ();
|
||||
Event* evwr = new Event();
|
||||
evwr->setClientSendEvent(client, reqTopic);
|
||||
|
||||
/* Send WILLTOPICREQ to the client */
|
||||
_gateway->getClientSendQue()->post(evwr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create CONNACK & send it to the client */
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
client->connackSended(MQTTSN_RC_ACCEPTED);
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
/* Send WILLTOPICREQ to the client */
|
||||
_gateway->getClientSendQue()->post(evwr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create CONNACK & send it to the client */
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
client->connackSended(MQTTSN_RC_ACCEPTED);
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* WILLMSG
|
||||
*/
|
||||
void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( !client->isWaitWillMsg() )
|
||||
{
|
||||
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
|
||||
return;
|
||||
}
|
||||
if (!client->isWaitWillMsg())
|
||||
{
|
||||
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MQTTSNString willmsg = MQTTSNString_initializer;
|
||||
//Connect* connectData = client->getConnectData();
|
||||
MQTTSNString willmsg = MQTTSNString_initializer;
|
||||
//Connect* connectData = client->getConnectData();
|
||||
|
||||
if( client->isConnectSendable() )
|
||||
{
|
||||
/* save WillMsg in the client */
|
||||
if ( packet->getWILLMSG(&willmsg) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
client->setWillMsg(willmsg);
|
||||
if (client->isConnectSendable())
|
||||
{
|
||||
/* save WillMsg in the client */
|
||||
if (packet->getWILLMSG(&willmsg) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
client->setWillMsg(willmsg);
|
||||
|
||||
/* Send CONNACK to the client */
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
/* Send CONNACK to the client */
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -173,31 +170,31 @@ void MQTTSNAggregateConnectionHandler::handleDisconnect(Client* client, MQTTSNPa
|
||||
*/
|
||||
void MQTTSNAggregateConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( ( client->isSleep() || client->isAwake() ) && client->getClientSleepPacket() )
|
||||
{
|
||||
sendStoredPublish(client);
|
||||
client->holdPingRequest();
|
||||
}
|
||||
if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
|
||||
{
|
||||
sendStoredPublish(client);
|
||||
client->holdPingRequest();
|
||||
}
|
||||
|
||||
/* create and send PINGRESP to the PacketHandler */
|
||||
client->resetPingRequest();
|
||||
/* create and send PINGRESP to the PacketHandler */
|
||||
client->resetPingRequest();
|
||||
|
||||
MQTTGWPacket* pingresp = new MQTTGWPacket();
|
||||
MQTTGWPacket* pingresp = new MQTTGWPacket();
|
||||
|
||||
pingresp->setHeader(PINGRESP);
|
||||
pingresp->setHeader(PINGRESP);
|
||||
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerRecvEvent(client, pingresp);
|
||||
_gateway->getPacketEventQue()->post(evt);
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerRecvEvent(client, pingresp);
|
||||
_gateway->getPacketEventQue()->post(evt);
|
||||
}
|
||||
|
||||
void MQTTSNAggregateConnectionHandler::sendStoredPublish(Client* client)
|
||||
{
|
||||
MQTTGWPacket* msg = nullptr;
|
||||
|
||||
while ( ( msg = client->getClientSleepPacket() ) != nullptr )
|
||||
while ((msg = client->getClientSleepPacket()) != nullptr)
|
||||
{
|
||||
client->deleteFirstClientSleepPacket(); // pop the que to delete element.
|
||||
client->deleteFirstClientSleepPacket(); // pop the que to delete element.
|
||||
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, msg);
|
||||
|
||||
@@ -28,18 +28,18 @@ class MQTTSNPacket;
|
||||
class MQTTSNAggregateConnectionHandler
|
||||
{
|
||||
public:
|
||||
MQTTSNAggregateConnectionHandler(Gateway* gateway);
|
||||
~MQTTSNAggregateConnectionHandler(void);
|
||||
MQTTSNAggregateConnectionHandler(Gateway* gateway);
|
||||
~MQTTSNAggregateConnectionHandler(void);
|
||||
|
||||
void handleConnect(Client* client, MQTTSNPacket* packet);
|
||||
void handleWillmsg(Client* client, MQTTSNPacket* packet);
|
||||
void handleDisconnect(Client* client, MQTTSNPacket* packet);
|
||||
void handlePingreq(Client* client, MQTTSNPacket* packet);
|
||||
void handleConnect(Client* client, MQTTSNPacket* packet);
|
||||
void handleWillmsg(Client* client, MQTTSNPacket* packet);
|
||||
void handleDisconnect(Client* client, MQTTSNPacket* packet);
|
||||
void handlePingreq(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
private:
|
||||
void sendStoredPublish(Client* client);
|
||||
void sendStoredPublish(Client* client);
|
||||
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,116 +24,114 @@
|
||||
#include <string.h>
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Adapter
|
||||
Class Adapter
|
||||
=====================================*/
|
||||
Adapter:: Adapter(Gateway* gw)
|
||||
Adapter::Adapter(Gateway* gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
_proxy = new Proxy(gw);
|
||||
_proxySecure = new Proxy(gw);
|
||||
_gateway = gw;
|
||||
_proxy = new Proxy(gw);
|
||||
_proxySecure = new Proxy(gw);
|
||||
}
|
||||
|
||||
Adapter::~Adapter(void)
|
||||
{
|
||||
if ( _proxy )
|
||||
if (_proxy)
|
||||
{
|
||||
delete _proxy;
|
||||
}
|
||||
|
||||
if ( _proxySecure )
|
||||
{
|
||||
delete _proxySecure;
|
||||
}
|
||||
if (_proxySecure)
|
||||
{
|
||||
delete _proxySecure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
||||
{
|
||||
_isSecure = false;
|
||||
if ( _gateway->hasSecureConnection() )
|
||||
if (_gateway->hasSecureConnection())
|
||||
{
|
||||
_isSecure = true;
|
||||
_isSecure = true;
|
||||
}
|
||||
|
||||
MQTTSNString id = MQTTSNString_initializer;
|
||||
MQTTSNString idSecure = MQTTSNString_initializer;
|
||||
MQTTSNString idSecure = MQTTSNString_initializer;
|
||||
|
||||
string name = string(adpterName);
|
||||
id.cstring = const_cast<char*>(name.c_str());
|
||||
string nameSecure = string(adpterName) + "-S";
|
||||
idSecure.cstring = const_cast<char*>(nameSecure.c_str());
|
||||
string name = string(adpterName);
|
||||
id.cstring = const_cast<char*>(name.c_str());
|
||||
string nameSecure = string(adpterName) + "-S";
|
||||
idSecure.cstring = const_cast<char*>(nameSecure.c_str());
|
||||
|
||||
Client* client = _gateway->getClientList()->createClient(0, &id, true, false, TRANSPEARENT_TYPE);
|
||||
setClient(client, false);
|
||||
client->setAdapterType(adapterType);
|
||||
Client* client = _gateway->getClientList()->createClient(0, &id, true, false, TRANSPEARENT_TYPE);
|
||||
setClient(client, false);
|
||||
client->setAdapterType(adapterType);
|
||||
|
||||
client = _gateway->getClientList()->createClient(0, &idSecure, true, true, TRANSPEARENT_TYPE);
|
||||
setClient(client, true);
|
||||
client->setAdapterType(adapterType);
|
||||
client = _gateway->getClientList()->createClient(0, &idSecure, true, true,
|
||||
TRANSPEARENT_TYPE);
|
||||
setClient(client, true);
|
||||
client->setAdapterType(adapterType);
|
||||
}
|
||||
|
||||
|
||||
Client* Adapter::getClient(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = _gateway->getClientList()->getClient(addr);
|
||||
if ( !client )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if ( client->isQoSm1() )
|
||||
{
|
||||
return client;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Adapter::getClientId(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = getClient(addr);
|
||||
if ( !client )
|
||||
Client* client = _gateway->getClientList()->getClient(addr);
|
||||
if (!client)
|
||||
{
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
else if ( client->isQoSm1() )
|
||||
else if (client->isQoSm1())
|
||||
{
|
||||
return client->getClientId();
|
||||
return client;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Adapter::getClientId(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = getClient(addr);
|
||||
if (!client)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if (client->isQoSm1())
|
||||
{
|
||||
return client->getClientId();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Adapter::isSecure(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = getClient(addr);
|
||||
if ( !client )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if ( client->isSecureNetwork() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Client* client = getClient(addr);
|
||||
if (!client)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (client->isSecureNetwork())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Adapter::isSecure(void)
|
||||
{
|
||||
return _isSecure;
|
||||
return _isSecure;
|
||||
}
|
||||
|
||||
void Adapter::setClient(Client* client, bool secure)
|
||||
{
|
||||
if ( secure )
|
||||
if (secure)
|
||||
{
|
||||
_clientSecure = client;
|
||||
}
|
||||
@@ -157,7 +155,7 @@ void Adapter::checkConnection(void)
|
||||
{
|
||||
_proxy->checkConnection(_client);
|
||||
|
||||
if ( _isSecure )
|
||||
if (_isSecure)
|
||||
{
|
||||
_proxySecure->checkConnection(_clientSecure);
|
||||
}
|
||||
@@ -166,15 +164,16 @@ void Adapter::checkConnection(void)
|
||||
void Adapter::send(MQTTSNPacket* packet, Client* client)
|
||||
{
|
||||
Proxy* proxy = _proxy;
|
||||
if ( client->isSecureNetwork() && !_isSecure )
|
||||
if (client->isSecureNetwork() && !_isSecure)
|
||||
{
|
||||
if ( _isSecure )
|
||||
if (_isSecure)
|
||||
{
|
||||
proxy = _proxySecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s %s No Secure connections %s 's packet is discarded.%s\n", ERRMSG_HEADER, client->getClientId() , ERRMSG_FOOTER);
|
||||
WRITELOG("%s %s No Secure connections %s 's packet is discarded.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -185,13 +184,13 @@ void Adapter::send(MQTTSNPacket* packet, Client* client)
|
||||
|
||||
void Adapter::resetPingTimer(bool secure)
|
||||
{
|
||||
if ( secure )
|
||||
if (secure)
|
||||
{
|
||||
_proxySecure->resetPingTimer();
|
||||
_proxySecure->resetPingTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
_proxy->resetPingTimer();
|
||||
_proxy->resetPingTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,48 +201,47 @@ bool Adapter::isActive(void)
|
||||
|
||||
void Adapter::savePacket(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( client->isSecureNetwork())
|
||||
{
|
||||
_proxySecure->savePacket(client, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
_proxy->savePacket(client, packet);
|
||||
}
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
_proxySecure->savePacket(client, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
_proxy->savePacket(client, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Client* Adapter::getAdapterClient(Client* client)
|
||||
{
|
||||
if ( client->isSecureNetwork() )
|
||||
{
|
||||
return _clientSecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _client;
|
||||
}
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
return _clientSecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _client;
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class Proxy
|
||||
Class Proxy
|
||||
=====================================*/
|
||||
Proxy::Proxy(Gateway* gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
_suspendedPacketEventQue = new EventQue();
|
||||
_gateway = gw;
|
||||
_suspendedPacketEventQue = new EventQue();
|
||||
}
|
||||
Proxy::~Proxy(void)
|
||||
{
|
||||
if ( _suspendedPacketEventQue )
|
||||
{
|
||||
delete _suspendedPacketEventQue;
|
||||
}
|
||||
if (_suspendedPacketEventQue)
|
||||
{
|
||||
delete _suspendedPacketEventQue;
|
||||
}
|
||||
}
|
||||
|
||||
void Proxy::checkConnection(Client* client)
|
||||
{
|
||||
if ( client->isDisconnect() || ( client->isConnecting() && _responseTimer.isTimeup()) )
|
||||
if (client->isDisconnect() || (client->isConnecting() && _responseTimer.isTimeup()))
|
||||
{
|
||||
client->connectSended();
|
||||
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
|
||||
@@ -257,26 +255,25 @@ void Proxy::checkConnection(Client* client)
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
else if ( (client->isActive() && _keepAliveTimer.isTimeup() ) || (_isWaitingResp && _responseTimer.isTimeup() ) )
|
||||
else if ((client->isActive() && _keepAliveTimer.isTimeup()) || (_isWaitingResp && _responseTimer.isTimeup()))
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
MQTTSNString clientId = MQTTSNString_initializer;
|
||||
packet->setPINGREQ(&clientId);
|
||||
Event* ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
|
||||
_isWaitingResp = true;
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
MQTTSNString clientId = MQTTSNString_initializer;
|
||||
packet->setPINGREQ(&clientId);
|
||||
Event* ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
|
||||
_isWaitingResp = true;
|
||||
|
||||
if ( ++_retryCnt > PROXY_MAX_RETRY_CNT )
|
||||
{
|
||||
client->disconnected();
|
||||
}
|
||||
resetPingTimer();
|
||||
if (++_retryCnt > PROXY_MAX_RETRY_CNT)
|
||||
{
|
||||
client->disconnected();
|
||||
}
|
||||
resetPingTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Proxy::resetPingTimer(void)
|
||||
{
|
||||
_keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL);
|
||||
@@ -284,24 +281,24 @@ void Proxy::resetPingTimer(void)
|
||||
|
||||
void Proxy::recv(MQTTSNPacket* packet, Client* client)
|
||||
{
|
||||
if ( packet->getType() == MQTTSN_CONNACK )
|
||||
if (packet->getType() == MQTTSN_CONNACK)
|
||||
{
|
||||
if ( packet->isAccepted() )
|
||||
{
|
||||
if (packet->isAccepted())
|
||||
{
|
||||
_responseTimer.stop();
|
||||
_retryCnt = 0;
|
||||
resetPingTimer();
|
||||
sendSuspendedPacket();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( packet->getType() == MQTTSN_PINGRESP )
|
||||
else if (packet->getType() == MQTTSN_PINGRESP)
|
||||
{
|
||||
_isWaitingResp = false;
|
||||
_responseTimer.stop();
|
||||
_retryCnt = 0;
|
||||
resetPingTimer();
|
||||
_retryCnt = 0;
|
||||
resetPingTimer();
|
||||
}
|
||||
else if ( packet->getType() == MQTTSN_DISCONNECT )
|
||||
else if (packet->getType() == MQTTSN_DISCONNECT)
|
||||
{
|
||||
// blank
|
||||
}
|
||||
@@ -309,18 +306,18 @@ void Proxy::recv(MQTTSNPacket* packet, Client* client)
|
||||
|
||||
void Proxy::savePacket(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTSNPacket* pk = new MQTTSNPacket(*packet);
|
||||
Event* ev = new Event();
|
||||
ev->setClientRecvEvent(client, pk);
|
||||
_suspendedPacketEventQue->post(ev);
|
||||
MQTTSNPacket* pk = new MQTTSNPacket(*packet);
|
||||
Event* ev = new Event();
|
||||
ev->setClientRecvEvent(client, pk);
|
||||
_suspendedPacketEventQue->post(ev);
|
||||
}
|
||||
|
||||
void Proxy::sendSuspendedPacket(void)
|
||||
{
|
||||
while ( _suspendedPacketEventQue->size() )
|
||||
{
|
||||
Event* ev = _suspendedPacketEventQue->wait();
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
while (_suspendedPacketEventQue->size())
|
||||
{
|
||||
Event* ev = _suspendedPacketEventQue->wait();
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,17 +31,18 @@ class EventQue;
|
||||
class Timer;
|
||||
|
||||
/* When you add a new type, Client::setAdapterType() and Client::isAdapter() functions must be modified. */
|
||||
typedef enum{
|
||||
Atype_QoSm1Proxy, Atype_Aggregater
|
||||
}AdapterType;
|
||||
typedef enum
|
||||
{
|
||||
Atype_QoSm1Proxy, Atype_Aggregater
|
||||
} AdapterType;
|
||||
|
||||
/*=====================================
|
||||
Class Adapter
|
||||
Class Adapter
|
||||
=====================================*/
|
||||
class Adapter
|
||||
{
|
||||
public:
|
||||
Adapter(Gateway* gw);
|
||||
Adapter(Gateway* gw);
|
||||
~Adapter(void);
|
||||
|
||||
void setup(const char* adpterName, AdapterType adapterType);
|
||||
@@ -60,18 +61,17 @@ public:
|
||||
void savePacket(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
private:
|
||||
Gateway* _gateway {nullptr};
|
||||
Proxy* _proxy {nullptr};
|
||||
Proxy* _proxySecure {nullptr};
|
||||
Client* _client {nullptr};
|
||||
Client* _clientSecure {nullptr};
|
||||
bool _isActive {false};
|
||||
bool _isSecure{false};
|
||||
Gateway* _gateway { nullptr };
|
||||
Proxy* _proxy { nullptr };
|
||||
Proxy* _proxySecure { nullptr };
|
||||
Client* _client { nullptr };
|
||||
Client* _clientSecure { nullptr };
|
||||
bool _isActive { false };
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Proxy
|
||||
Class Proxy
|
||||
=====================================*/
|
||||
class Proxy
|
||||
{
|
||||
@@ -88,11 +88,12 @@ public:
|
||||
private:
|
||||
void sendSuspendedPacket(void);
|
||||
Gateway* _gateway;
|
||||
EventQue* _suspendedPacketEventQue {nullptr};
|
||||
Timer _keepAliveTimer;
|
||||
Timer _responseTimer;
|
||||
bool _isWaitingResp {false};
|
||||
int _retryCnt {0};
|
||||
EventQue* _suspendedPacketEventQue
|
||||
{ nullptr };
|
||||
Timer _keepAliveTimer;
|
||||
Timer _responseTimer;
|
||||
bool _isWaitingResp { false };
|
||||
int _retryCnt { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -33,42 +33,41 @@ char* currentDateTime(void);
|
||||
=====================================*/
|
||||
AdapterManager::AdapterManager(Gateway* gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
_forwarders = new ForwarderList();
|
||||
_qosm1Proxy = new QoSm1Proxy(gw);
|
||||
_aggregater = new Aggregater(gw);
|
||||
_gateway = gw;
|
||||
_forwarders = new ForwarderList();
|
||||
_qosm1Proxy = new QoSm1Proxy(gw);
|
||||
_aggregater = new Aggregater(gw);
|
||||
}
|
||||
|
||||
|
||||
void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bool qosM1)
|
||||
{
|
||||
if ( aggregate )
|
||||
if (aggregate)
|
||||
{
|
||||
_aggregater->initialize(gwName);
|
||||
_aggregater->initialize(gwName);
|
||||
}
|
||||
|
||||
if ( qosM1 )
|
||||
if (qosM1)
|
||||
{
|
||||
_qosm1Proxy->initialize(gwName);
|
||||
_qosm1Proxy->initialize(gwName);
|
||||
}
|
||||
|
||||
if ( forwarder )
|
||||
if (forwarder)
|
||||
{
|
||||
_forwarders->initialize(_gateway);
|
||||
_forwarders->initialize(_gateway);
|
||||
}
|
||||
}
|
||||
|
||||
AdapterManager::~AdapterManager(void)
|
||||
{
|
||||
if ( _forwarders )
|
||||
if (_forwarders)
|
||||
{
|
||||
delete _forwarders;
|
||||
}
|
||||
if ( _qosm1Proxy )
|
||||
if (_qosm1Proxy)
|
||||
{
|
||||
delete _qosm1Proxy;
|
||||
}
|
||||
if ( _aggregater )
|
||||
if (_aggregater)
|
||||
{
|
||||
delete _aggregater;
|
||||
}
|
||||
@@ -91,119 +90,119 @@ Aggregater* AdapterManager::getAggregater(void)
|
||||
|
||||
bool AdapterManager::isAggregatedClient(Client* client)
|
||||
{
|
||||
if ( !_aggregater->isActive() || client->isQoSm1() || client->isAggregater() || client->isQoSm1Proxy())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!_aggregater->isActive() || client->isQoSm1() || client->isAggregater() || client->isQoSm1Proxy())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Client* AdapterManager::getClient(Client* client)
|
||||
{
|
||||
bool secure = client->isSecureNetwork();
|
||||
Client* newClient = client;
|
||||
bool secure = client->isSecureNetwork();
|
||||
Client* newClient = client;
|
||||
|
||||
if ( client->isQoSm1() )
|
||||
{
|
||||
newClient = _qosm1Proxy->getAdapterClient(client);
|
||||
_qosm1Proxy->resetPingTimer(secure);
|
||||
}
|
||||
else if ( client->isAggregated() )
|
||||
{
|
||||
newClient = _aggregater->getAdapterClient(client);
|
||||
_aggregater->resetPingTimer(secure);
|
||||
}
|
||||
else if ( client->isQoSm1Proxy() )
|
||||
{
|
||||
_qosm1Proxy->resetPingTimer(secure);
|
||||
}
|
||||
else if ( client->isAggregater() )
|
||||
{
|
||||
_aggregater->resetPingTimer(secure);
|
||||
}
|
||||
return newClient;
|
||||
if (client->isQoSm1())
|
||||
{
|
||||
newClient = _qosm1Proxy->getAdapterClient(client);
|
||||
_qosm1Proxy->resetPingTimer(secure);
|
||||
}
|
||||
else if (client->isAggregated())
|
||||
{
|
||||
newClient = _aggregater->getAdapterClient(client);
|
||||
_aggregater->resetPingTimer(secure);
|
||||
}
|
||||
else if (client->isQoSm1Proxy())
|
||||
{
|
||||
_qosm1Proxy->resetPingTimer(secure);
|
||||
}
|
||||
else if (client->isAggregater())
|
||||
{
|
||||
_aggregater->resetPingTimer(secure);
|
||||
}
|
||||
return newClient;
|
||||
}
|
||||
|
||||
int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task)
|
||||
{
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3];
|
||||
Forwarder* fwd = client->getForwarder();
|
||||
int rc = 0;
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3];
|
||||
Forwarder* fwd = client->getForwarder();
|
||||
int rc = 0;
|
||||
|
||||
if ( fwd )
|
||||
{
|
||||
MQTTSNGWEncapsulatedPacket encap(packet);
|
||||
WirelessNodeId* wnId = fwd->getWirelessNodeId(client);
|
||||
encap.setWirelessNodeId(wnId);
|
||||
task->log(client, packet);
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), encap.getName(), RIGHTARROW, fwd->getId(), encap.print(pbuf));
|
||||
rc = encap.unicast(_gateway->getSensorNetwork(),fwd->getSensorNetAddr());
|
||||
}
|
||||
else
|
||||
{
|
||||
task->log(client, packet);
|
||||
if ( client->isQoSm1Proxy() )
|
||||
{
|
||||
_qosm1Proxy->send(packet, client);
|
||||
}
|
||||
else if ( client->isAggregater() )
|
||||
{
|
||||
_aggregater->send(packet, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = packet->unicast(_gateway->getSensorNetwork(), client->getSensorNetAddress());
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
if (fwd)
|
||||
{
|
||||
MQTTSNGWEncapsulatedPacket encap(packet);
|
||||
WirelessNodeId* wnId = fwd->getWirelessNodeId(client);
|
||||
encap.setWirelessNodeId(wnId);
|
||||
task->log(client, packet);
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), encap.getName(), RIGHTARROW, fwd->getId(), encap.print(pbuf));
|
||||
rc = encap.unicast(_gateway->getSensorNetwork(), fwd->getSensorNetAddr());
|
||||
}
|
||||
else
|
||||
{
|
||||
task->log(client, packet);
|
||||
if (client->isQoSm1Proxy())
|
||||
{
|
||||
_qosm1Proxy->send(packet, client);
|
||||
}
|
||||
else if (client->isAggregater())
|
||||
{
|
||||
_aggregater->send(packet, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = packet->unicast(_gateway->getSensorNetwork(), client->getSensorNetAddress());
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void AdapterManager::checkConnection(void)
|
||||
{
|
||||
if ( _aggregater->isActive())
|
||||
{
|
||||
_aggregater->checkConnection();
|
||||
}
|
||||
if (_aggregater->isActive())
|
||||
{
|
||||
_aggregater->checkConnection();
|
||||
}
|
||||
|
||||
if ( _qosm1Proxy->isActive())
|
||||
{
|
||||
_qosm1Proxy->checkConnection();
|
||||
}
|
||||
if (_qosm1Proxy->isActive())
|
||||
{
|
||||
_qosm1Proxy->checkConnection();
|
||||
}
|
||||
}
|
||||
|
||||
Client* AdapterManager::convertClient(uint16_t msgId, uint16_t* clientMsgId)
|
||||
{
|
||||
return _aggregater->convertClient(msgId, clientMsgId);
|
||||
return _aggregater->convertClient(msgId, clientMsgId);
|
||||
}
|
||||
|
||||
bool AdapterManager::isAggregaterActive(void)
|
||||
{
|
||||
return _aggregater->isActive();
|
||||
return _aggregater->isActive();
|
||||
}
|
||||
|
||||
/*
|
||||
AggregateTopicElement* AdapterManager::findTopic(Topic* topic)
|
||||
{
|
||||
return _aggregater->findTopic(topic);
|
||||
}
|
||||
AggregateTopicElement* AdapterManager::findTopic(Topic* topic)
|
||||
{
|
||||
return _aggregater->findTopic(topic);
|
||||
}
|
||||
|
||||
AggregateTopicElement* AdapterManager::addAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
return _aggregater->addAggregateTopic(topic, client);
|
||||
}
|
||||
AggregateTopicElement* AdapterManager::addAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
return _aggregater->addAggregateTopic(topic, client);
|
||||
}
|
||||
|
||||
|
||||
void AdapterManager::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
//_aggregater->removeAggregateTopic(topic, client);
|
||||
}
|
||||
void AdapterManager::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
//_aggregater->removeAggregateTopic(topic, client);
|
||||
}
|
||||
|
||||
void AdapterManager::removeAggregateTopicList(Topics* topics, Client* client)
|
||||
{
|
||||
void AdapterManager::removeAggregateTopicList(Topics* topics, Client* client)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@@ -33,12 +33,12 @@ class ClientRecvTask;
|
||||
class ClientSendTask;
|
||||
|
||||
/*=====================================
|
||||
Class AdapterManager
|
||||
Class AdapterManager
|
||||
=====================================*/
|
||||
class AdapterManager
|
||||
{
|
||||
public:
|
||||
AdapterManager(Gateway* gw);
|
||||
AdapterManager(Gateway* gw);
|
||||
~AdapterManager(void);
|
||||
void initialize(char* gwName, bool aggregater, bool fowarder, bool qosM1);
|
||||
ForwarderList* getForwarderList(void);
|
||||
@@ -49,18 +49,16 @@ public:
|
||||
bool isAggregatedClient(Client* client);
|
||||
Client* getClient(Client* client);
|
||||
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId);
|
||||
int unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task);
|
||||
int unicastToClient(Client* client, MQTTSNPacket* packet,
|
||||
ClientSendTask* task);
|
||||
bool isAggregaterActive(void);
|
||||
|
||||
private:
|
||||
Gateway* _gateway {nullptr};
|
||||
ForwarderList* _forwarders {nullptr};
|
||||
QoSm1Proxy* _qosm1Proxy {nullptr};
|
||||
Aggregater* _aggregater {nullptr};
|
||||
Gateway* _gateway { nullptr };
|
||||
ForwarderList* _forwarders { nullptr };
|
||||
QoSm1Proxy* _qosm1Proxy { nullptr };
|
||||
Aggregater* _aggregater { nullptr };
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
=====================================*/
|
||||
ClientTopicElement::ClientTopicElement(Client* client)
|
||||
{
|
||||
_client = client;
|
||||
_client = client;
|
||||
}
|
||||
|
||||
ClientTopicElement::~ClientTopicElement()
|
||||
@@ -31,12 +31,12 @@ ClientTopicElement::~ClientTopicElement()
|
||||
|
||||
Client* ClientTopicElement::getClient(void)
|
||||
{
|
||||
return _client;
|
||||
return _client;
|
||||
}
|
||||
|
||||
ClientTopicElement* ClientTopicElement::getNextClientElement(void)
|
||||
{
|
||||
return _next;
|
||||
return _next;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -49,122 +49,122 @@ AggregateTopicElement::AggregateTopicElement(void)
|
||||
|
||||
AggregateTopicElement::AggregateTopicElement(Topic* topic, Client* client)
|
||||
{
|
||||
_topic = topic;
|
||||
ClientTopicElement* elm = new ClientTopicElement(client);
|
||||
if ( elm != nullptr )
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
_topic = topic;
|
||||
ClientTopicElement* elm = new ClientTopicElement(client);
|
||||
if (elm != nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
}
|
||||
|
||||
AggregateTopicElement::~AggregateTopicElement(void)
|
||||
{
|
||||
_mutex.lock();
|
||||
if ( _head != nullptr )
|
||||
{
|
||||
ClientTopicElement* p = _tail;
|
||||
while ( p )
|
||||
{
|
||||
ClientTopicElement* pPrev = p;
|
||||
delete p;
|
||||
p = pPrev->_prev;
|
||||
}
|
||||
_head = _tail = nullptr;
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex.lock();
|
||||
if (_head != nullptr)
|
||||
{
|
||||
ClientTopicElement* p = _tail;
|
||||
while (p)
|
||||
{
|
||||
ClientTopicElement* pPrev = p;
|
||||
delete p;
|
||||
p = pPrev->_prev;
|
||||
}
|
||||
_head = _tail = nullptr;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
ClientTopicElement* AggregateTopicElement::add(Client* client)
|
||||
{
|
||||
ClientTopicElement* elm = new ClientTopicElement(client);
|
||||
if ( elm == nullptr )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
ClientTopicElement* elm = new ClientTopicElement(client);
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_mutex.lock();
|
||||
_mutex.lock();
|
||||
|
||||
if ( _head == nullptr )
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientTopicElement* p = find(client);
|
||||
if ( p == nullptr )
|
||||
{
|
||||
p = _tail;
|
||||
_tail = elm;
|
||||
elm->_prev = p;
|
||||
p->_next = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete elm;
|
||||
elm = p;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
return elm;
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientTopicElement* p = find(client);
|
||||
if (p == nullptr)
|
||||
{
|
||||
p = _tail;
|
||||
_tail = elm;
|
||||
elm->_prev = p;
|
||||
p->_next = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete elm;
|
||||
elm = p;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
return elm;
|
||||
}
|
||||
|
||||
ClientTopicElement* AggregateTopicElement::find(Client* client)
|
||||
{
|
||||
ClientTopicElement* p = _head;
|
||||
while ( p != nullptr )
|
||||
{
|
||||
if ( p->_client == client)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return p;
|
||||
ClientTopicElement* p = _head;
|
||||
while (p != nullptr)
|
||||
{
|
||||
if (p->_client == client)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
ClientTopicElement* AggregateTopicElement::getFirstClientTopicElement(void)
|
||||
{
|
||||
return _head;
|
||||
return _head;
|
||||
}
|
||||
|
||||
ClientTopicElement* AggregateTopicElement::getNextClientTopicElement(ClientTopicElement* elmClient)
|
||||
{
|
||||
return elmClient->_next;
|
||||
return elmClient->_next;
|
||||
}
|
||||
|
||||
void AggregateTopicElement::eraseClient(Client* client)
|
||||
{
|
||||
_mutex.lock();
|
||||
_mutex.lock();
|
||||
|
||||
ClientTopicElement* p = find(client);
|
||||
if ( p != nullptr )
|
||||
{
|
||||
if ( p->_prev == nullptr ) // head element
|
||||
{
|
||||
_head = p->_next;
|
||||
if ( p->_next == nullptr ) // head & only one
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->_next->_prev = nullptr; // head & midle
|
||||
}
|
||||
}
|
||||
else if ( p->_next != nullptr ) // middle
|
||||
{
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
else // tail
|
||||
{
|
||||
p->_prev->_next = nullptr;
|
||||
_tail = p->_prev;
|
||||
}
|
||||
delete p;
|
||||
}
|
||||
_mutex.unlock();
|
||||
ClientTopicElement* p = find(client);
|
||||
if (p != nullptr)
|
||||
{
|
||||
if (p->_prev == nullptr) // head element
|
||||
{
|
||||
_head = p->_next;
|
||||
if (p->_next == nullptr) // head & only one
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->_next->_prev = nullptr; // head & midle
|
||||
}
|
||||
}
|
||||
else if (p->_next != nullptr) // middle
|
||||
{
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
else // tail
|
||||
{
|
||||
p->_prev->_next = nullptr;
|
||||
_tail = p->_prev;
|
||||
}
|
||||
delete p;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -183,138 +183,138 @@ AggregateTopicTable::~AggregateTopicTable()
|
||||
|
||||
AggregateTopicElement* AggregateTopicTable::add(Topic* topic, Client* client)
|
||||
{
|
||||
AggregateTopicElement* elm = nullptr;
|
||||
_mutex.lock();
|
||||
elm = getAggregateTopicElement(topic);
|
||||
if ( elm != nullptr )
|
||||
{
|
||||
if ( elm->find(client) == nullptr )
|
||||
{
|
||||
elm->add(client);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Topic* newTopic = topic->duplicate();
|
||||
elm = new AggregateTopicElement(newTopic, client);
|
||||
if ( _head == nullptr )
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
elm->_prev = _tail;
|
||||
_tail->_next = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
return elm;
|
||||
AggregateTopicElement* elm = nullptr;
|
||||
_mutex.lock();
|
||||
elm = getAggregateTopicElement(topic);
|
||||
if (elm != nullptr)
|
||||
{
|
||||
if (elm->find(client) == nullptr)
|
||||
{
|
||||
elm->add(client);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Topic* newTopic = topic->duplicate();
|
||||
elm = new AggregateTopicElement(newTopic, client);
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
elm->_prev = _tail;
|
||||
_tail->_next = elm;
|
||||
_tail = elm;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
return elm;
|
||||
}
|
||||
|
||||
void AggregateTopicTable::erase(Topic* topic, Client* client)
|
||||
{
|
||||
AggregateTopicElement* elm = nullptr;
|
||||
AggregateTopicElement* elm = nullptr;
|
||||
|
||||
_mutex.lock();
|
||||
elm = getAggregateTopicElement(topic);
|
||||
_mutex.lock();
|
||||
elm = getAggregateTopicElement(topic);
|
||||
|
||||
if ( elm != nullptr )
|
||||
{
|
||||
elm->eraseClient(client);
|
||||
}
|
||||
if ( elm->_head == nullptr )
|
||||
{
|
||||
erase(elm);
|
||||
}
|
||||
_mutex.unlock();
|
||||
return;
|
||||
if (elm != nullptr)
|
||||
{
|
||||
elm->eraseClient(client);
|
||||
}
|
||||
if (elm->_head == nullptr)
|
||||
{
|
||||
erase(elm);
|
||||
}
|
||||
_mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
void AggregateTopicTable::erase(AggregateTopicElement* elmTopic)
|
||||
{
|
||||
if ( elmTopic != nullptr )
|
||||
{
|
||||
if ( elmTopic->_prev == nullptr ) // head element
|
||||
{
|
||||
_head = elmTopic->_next;
|
||||
if ( elmTopic->_next == nullptr ) // head & only one
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
elmTopic->_next->_prev = nullptr; // head & midle
|
||||
}
|
||||
}
|
||||
else if ( elmTopic->_next != nullptr ) // middle
|
||||
{
|
||||
elmTopic->_prev->_next = elmTopic->_next;
|
||||
}
|
||||
else // tail
|
||||
{
|
||||
elmTopic->_prev->_next = nullptr;
|
||||
_tail = elmTopic->_prev;
|
||||
}
|
||||
delete elmTopic;
|
||||
}
|
||||
if (elmTopic != nullptr)
|
||||
{
|
||||
if (elmTopic->_prev == nullptr) // head element
|
||||
{
|
||||
_head = elmTopic->_next;
|
||||
if (elmTopic->_next == nullptr) // head & only one
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
elmTopic->_next->_prev = nullptr; // head & midle
|
||||
}
|
||||
}
|
||||
else if (elmTopic->_next != nullptr) // middle
|
||||
{
|
||||
elmTopic->_prev->_next = elmTopic->_next;
|
||||
}
|
||||
else // tail
|
||||
{
|
||||
elmTopic->_prev->_next = nullptr;
|
||||
_tail = elmTopic->_prev;
|
||||
}
|
||||
delete elmTopic;
|
||||
}
|
||||
}
|
||||
|
||||
AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement(Topic* topic)
|
||||
{
|
||||
AggregateTopicElement* elm = _head;
|
||||
AggregateTopicElement* elm = _head;
|
||||
|
||||
while( elm != nullptr )
|
||||
{
|
||||
if ( elm->_topic->isMatch(topic->_topicName) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
elm = elm->_next;
|
||||
}
|
||||
return elm;
|
||||
while (elm != nullptr)
|
||||
{
|
||||
if (elm->_topic->isMatch(topic->_topicName))
|
||||
{
|
||||
break;
|
||||
}
|
||||
elm = elm->_next;
|
||||
}
|
||||
return elm;
|
||||
}
|
||||
|
||||
ClientTopicElement* AggregateTopicTable::getClientElement(Topic* topic)
|
||||
{
|
||||
AggregateTopicElement* elm = getAggregateTopicElement(topic);
|
||||
if ( elm != nullptr )
|
||||
{
|
||||
return elm->_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
AggregateTopicElement* elm = getAggregateTopicElement(topic);
|
||||
if (elm != nullptr)
|
||||
{
|
||||
return elm->_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AggregateTopicTable::print(void)
|
||||
{
|
||||
AggregateTopicElement* elm = _head;
|
||||
AggregateTopicElement* elm = _head;
|
||||
|
||||
printf("Beginning of AggregateTopicTable\n");
|
||||
while( elm != nullptr )
|
||||
{
|
||||
printf("%s\n", elm->_topic->getTopicName()->c_str());
|
||||
printf("Beginning of AggregateTopicTable\n");
|
||||
while (elm != nullptr)
|
||||
{
|
||||
printf("%s\n", elm->_topic->getTopicName()->c_str());
|
||||
|
||||
ClientTopicElement* clElm = elm->getFirstClientTopicElement();
|
||||
Client* client = clElm->getClient();
|
||||
ClientTopicElement* clElm = elm->getFirstClientTopicElement();
|
||||
Client* client = clElm->getClient();
|
||||
|
||||
while ( client != nullptr )
|
||||
{
|
||||
printf(" %s\n", client->getClientId());
|
||||
clElm = clElm->getNextClientElement();
|
||||
if ( clElm != nullptr )
|
||||
{
|
||||
client = clElm->getClient();
|
||||
}
|
||||
else
|
||||
{
|
||||
client = nullptr;
|
||||
}
|
||||
}
|
||||
elm = elm->_next;
|
||||
}
|
||||
printf("End of AggregateTopicTable\n");
|
||||
while (client != nullptr)
|
||||
{
|
||||
printf(" %s\n", client->getClientId());
|
||||
clElm = clElm->getNextClientElement();
|
||||
if (clElm != nullptr)
|
||||
{
|
||||
client = clElm->getClient();
|
||||
}
|
||||
else
|
||||
{
|
||||
client = nullptr;
|
||||
}
|
||||
}
|
||||
elm = elm->_next;
|
||||
}
|
||||
printf("End of AggregateTopicTable\n");
|
||||
}
|
||||
|
||||
@@ -35,24 +35,24 @@ class Mutex;
|
||||
class AggregateTopicTable
|
||||
{
|
||||
public:
|
||||
AggregateTopicTable();
|
||||
~AggregateTopicTable();
|
||||
AggregateTopicTable();
|
||||
~AggregateTopicTable();
|
||||
|
||||
AggregateTopicElement* add(Topic* topic, Client* client);
|
||||
AggregateTopicElement* getAggregateTopicElement(Topic* topic);
|
||||
ClientTopicElement* getClientElement(Topic* topic);
|
||||
void erase(Topic* topic, Client* client);
|
||||
void clear(void);
|
||||
AggregateTopicElement* add(Topic* topic, Client* client);
|
||||
AggregateTopicElement* getAggregateTopicElement(Topic* topic);
|
||||
ClientTopicElement* getClientElement(Topic* topic);
|
||||
void erase(Topic* topic, Client* client);
|
||||
void clear(void);
|
||||
|
||||
void print(void);
|
||||
void print(void);
|
||||
|
||||
private:
|
||||
void erase(AggregateTopicElement* elmTopic);
|
||||
Mutex _mutex;
|
||||
AggregateTopicElement* _head {nullptr};
|
||||
AggregateTopicElement* _tail {nullptr};
|
||||
int _cnt {0};
|
||||
int _maxSize {MAX_MESSAGEID_TABLE_SIZE};
|
||||
void erase(AggregateTopicElement* elmTopic);
|
||||
Mutex _mutex;
|
||||
AggregateTopicElement* _head { nullptr };
|
||||
AggregateTopicElement* _tail { nullptr };
|
||||
int _cnt { 0 };
|
||||
int _maxSize { MAX_MESSAGEID_TABLE_SIZE };
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
@@ -68,17 +68,18 @@ public:
|
||||
|
||||
ClientTopicElement* add(Client* client);
|
||||
ClientTopicElement* getFirstClientTopicElement(void);
|
||||
ClientTopicElement* getNextClientTopicElement(ClientTopicElement* elmClient);
|
||||
ClientTopicElement* getNextClientTopicElement(
|
||||
ClientTopicElement* elmClient);
|
||||
void eraseClient(Client* client);
|
||||
ClientTopicElement* find(Client* client);
|
||||
|
||||
private:
|
||||
Mutex _mutex;
|
||||
Topic* _topic {nullptr};
|
||||
AggregateTopicElement* _next {nullptr};
|
||||
AggregateTopicElement* _prev {nullptr};
|
||||
ClientTopicElement* _head {nullptr};
|
||||
ClientTopicElement* _tail {nullptr};
|
||||
Topic* _topic { nullptr };
|
||||
AggregateTopicElement* _next { nullptr };
|
||||
AggregateTopicElement* _prev { nullptr };
|
||||
ClientTopicElement* _head { nullptr };
|
||||
ClientTopicElement* _tail { nullptr };
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
@@ -96,13 +97,11 @@ public:
|
||||
Client* getClient(void);
|
||||
|
||||
private:
|
||||
Client* _client {nullptr};
|
||||
ClientTopicElement* _next {nullptr};
|
||||
ClientTopicElement* _prev {nullptr};
|
||||
Client* _client { nullptr };
|
||||
ClientTopicElement* _next { nullptr };
|
||||
ClientTopicElement* _prev { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
Aggregater::Aggregater(Gateway* gw) : Adapter(gw)
|
||||
Aggregater::Aggregater(Gateway* gw) :
|
||||
Adapter(gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
_gateway = gw;
|
||||
}
|
||||
|
||||
Aggregater::~Aggregater(void)
|
||||
@@ -38,10 +39,10 @@ Aggregater::~Aggregater(void)
|
||||
|
||||
void Aggregater::initialize(char* gwName)
|
||||
{
|
||||
/* Create Aggregater Client */
|
||||
string name = string(gwName) + string("_Aggregater");
|
||||
setup(name.c_str(), Atype_Aggregater);
|
||||
_isActive = true;
|
||||
/* Create Aggregater Client */
|
||||
string name = string(gwName) + string("_Aggregater");
|
||||
setup(name.c_str(), Atype_Aggregater);
|
||||
_isActive = true;
|
||||
|
||||
//testMessageIdTable();
|
||||
|
||||
@@ -49,100 +50,98 @@ void Aggregater::initialize(char* gwName)
|
||||
|
||||
bool Aggregater::isActive(void)
|
||||
{
|
||||
return _isActive;
|
||||
return _isActive;
|
||||
}
|
||||
|
||||
uint16_t Aggregater::msgId(void)
|
||||
{
|
||||
// Only SecureClient generates msgId to avoid duplication of msgId. Client does not generate it.
|
||||
return Adapter::getSecureClient()->getNextPacketId();
|
||||
// Only SecureClient generates msgId to avoid duplication of msgId. Client does not generate it.
|
||||
return Adapter::getSecureClient()->getNextPacketId();
|
||||
}
|
||||
|
||||
Client* Aggregater::convertClient(uint16_t msgId, uint16_t* clientMsgId)
|
||||
{
|
||||
return _msgIdTable.getClientMsgId(msgId, clientMsgId);
|
||||
return _msgIdTable.getClientMsgId(msgId, clientMsgId);
|
||||
}
|
||||
|
||||
|
||||
uint16_t Aggregater::addMessageIdTable(Client* client, uint16_t msgId)
|
||||
{
|
||||
/* set Non secure client`s nextMsgId. otherwise Id is duplicated.*/
|
||||
/* set Non secure client`s nextMsgId. otherwise Id is duplicated.*/
|
||||
|
||||
MessageIdElement* elm = _msgIdTable.add(this, client, msgId);
|
||||
if ( elm == nullptr )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return elm->_msgId;
|
||||
}
|
||||
MessageIdElement* elm = _msgIdTable.add(this, client, msgId);
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return elm->_msgId;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Aggregater::getMsgId(Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
return _msgIdTable.getMsgId(client, clientMsgId);
|
||||
return _msgIdTable.getMsgId(client, clientMsgId);
|
||||
}
|
||||
|
||||
AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
return _topicTable.add(topic, client);
|
||||
return _topicTable.add(topic, client);
|
||||
}
|
||||
|
||||
|
||||
void Aggregater::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
_topicTable.erase(topic, client);
|
||||
_topicTable.erase(topic, client);
|
||||
}
|
||||
|
||||
AggregateTopicElement* Aggregater::findTopic(Topic* topic)
|
||||
{
|
||||
return _topicTable.getAggregateTopicElement(topic);
|
||||
return _topicTable.getAggregateTopicElement(topic);
|
||||
}
|
||||
|
||||
ClientTopicElement* Aggregater::getClientElement(Topic* topic)
|
||||
{
|
||||
AggregateTopicElement* elm = findTopic(topic);
|
||||
if ( elm != nullptr )
|
||||
{
|
||||
return elm->getFirstClientTopicElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
AggregateTopicElement* elm = findTopic(topic);
|
||||
if (elm != nullptr)
|
||||
{
|
||||
return elm->getFirstClientTopicElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Aggregater::printAggregateTopicTable(void)
|
||||
{
|
||||
_topicTable.print();
|
||||
_topicTable.print();
|
||||
}
|
||||
|
||||
bool Aggregater::testMessageIdTable(void)
|
||||
{
|
||||
Client* client = new Client();
|
||||
uint16_t msgId = 0;
|
||||
Client* client = new Client();
|
||||
uint16_t msgId = 0;
|
||||
|
||||
printf("msgId=%d\n", addMessageIdTable(client,1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 4));
|
||||
|
||||
convertClient(1,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(2,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(5,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(4,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(3,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
return true;
|
||||
convertClient(1, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(2, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(5, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(4, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(3, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,11 @@ class AggregateTopicTable;
|
||||
class Topics;
|
||||
|
||||
/*=====================================
|
||||
Class Aggregater
|
||||
Class Aggregater
|
||||
=====================================*/
|
||||
class Aggregater : public Adapter
|
||||
class Aggregater: public Adapter
|
||||
{
|
||||
friend class MessageIdTable;
|
||||
friend class MessageIdTable;
|
||||
public:
|
||||
Aggregater(Gateway* gw);
|
||||
~Aggregater(void);
|
||||
@@ -44,39 +44,35 @@ public:
|
||||
void initialize(char* gwName);
|
||||
|
||||
const char* getClientId(SensorNetAddress* addr);
|
||||
Client* getClient(SensorNetAddress* addr);
|
||||
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId);
|
||||
uint16_t addMessageIdTable(Client* client, uint16_t msgId);
|
||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||
Client* getClient(SensorNetAddress* addr);
|
||||
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId);
|
||||
uint16_t addMessageIdTable(Client* client, uint16_t msgId);
|
||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||
|
||||
ClientTopicElement* getClientElement(Topic* topic);
|
||||
ClientTopicElement* getNextClientElement(ClientTopicElement* clientElement);
|
||||
Client* getClient(ClientTopicElement* clientElement);
|
||||
ClientTopicElement* getClientElement(Topic* topic);
|
||||
ClientTopicElement* getNextClientElement(ClientTopicElement* clientElement);
|
||||
Client* getClient(ClientTopicElement* clientElement);
|
||||
|
||||
AggregateTopicElement* findTopic(Topic* topic);
|
||||
AggregateTopicElement* addAggregateTopic(Topic* topic, Client* client);
|
||||
AggregateTopicElement* findTopic(Topic* topic);
|
||||
AggregateTopicElement* addAggregateTopic(Topic* topic, Client* client);
|
||||
|
||||
void removeAggregateTopic(Topic* topic, Client* client);
|
||||
void removeAggregateAllTopic(Client* client);
|
||||
bool isActive(void);
|
||||
void removeAggregateTopic(Topic* topic, Client* client);
|
||||
void removeAggregateAllTopic(Client* client);
|
||||
bool isActive(void);
|
||||
|
||||
void printAggregateTopicTable(void);
|
||||
bool testMessageIdTable(void);
|
||||
void printAggregateTopicTable(void);
|
||||
bool testMessageIdTable(void);
|
||||
|
||||
private:
|
||||
uint16_t msgId(void);
|
||||
Gateway* _gateway {nullptr};
|
||||
uint16_t msgId(void);
|
||||
Gateway* _gateway { nullptr };
|
||||
MessageIdTable _msgIdTable;
|
||||
AggregateTopicTable _topicTable;
|
||||
|
||||
bool _isActive {false};
|
||||
bool _isSecure {false};
|
||||
bool _isActive { false };
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "MQTTSNGWBrokerRecvTask.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTSNGWClientList.h"
|
||||
#include "MQTTSNGateway.h"
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -29,14 +30,14 @@ char* currentDateTime(void);
|
||||
=====================================*/
|
||||
BrokerRecvTask::BrokerRecvTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_light = nullptr;
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_light = nullptr;
|
||||
setTaskName("BrokerRecvTask");
|
||||
}
|
||||
|
||||
BrokerRecvTask::~BrokerRecvTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +45,7 @@ BrokerRecvTask::~BrokerRecvTask()
|
||||
*/
|
||||
void BrokerRecvTask::initialize(int argc, char** argv)
|
||||
{
|
||||
_light = _gateway->getLightIndicator();
|
||||
_light = _gateway->getLightIndicator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,133 +53,130 @@ void BrokerRecvTask::initialize(int argc, char** argv)
|
||||
*/
|
||||
void BrokerRecvTask::run(void)
|
||||
{
|
||||
struct timeval timeout;
|
||||
MQTTGWPacket* packet = nullptr;
|
||||
int rc;
|
||||
Event* ev = nullptr;
|
||||
fd_set rset;
|
||||
fd_set wset;
|
||||
struct timeval timeout;
|
||||
MQTTGWPacket* packet = nullptr;
|
||||
int rc;
|
||||
Event* ev = nullptr;
|
||||
fd_set rset;
|
||||
fd_set wset;
|
||||
|
||||
while (true)
|
||||
{
|
||||
_light->blueLight(false);
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("\n%s BrokerRecvTask stopped.", currentDateTime());
|
||||
return;
|
||||
}
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; // 500 msec
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
int maxSock = 0;
|
||||
int sockfd = 0;
|
||||
while (true)
|
||||
{
|
||||
_light->blueLight(false);
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
return;
|
||||
}
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; // 500 msec
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
int maxSock = 0;
|
||||
int sockfd = 0;
|
||||
|
||||
/* Prepare sockets list to read */
|
||||
Client* client = _gateway->getClientList()->getClient(0);
|
||||
/* Prepare sockets list to read */
|
||||
Client* client = _gateway->getClientList()->getClient(0);
|
||||
|
||||
while ( client )
|
||||
{
|
||||
if (client->getNetwork()->isValid())
|
||||
{
|
||||
sockfd = client->getNetwork()->getSock();
|
||||
FD_SET(sockfd, &rset);
|
||||
FD_SET(sockfd, &wset);
|
||||
if (sockfd > maxSock)
|
||||
{
|
||||
maxSock = sockfd;
|
||||
}
|
||||
}
|
||||
client = client->getNextClient();
|
||||
}
|
||||
while (client)
|
||||
{
|
||||
if (client->getNetwork()->isValid())
|
||||
{
|
||||
sockfd = client->getNetwork()->getSock();
|
||||
FD_SET(sockfd, &rset);
|
||||
FD_SET(sockfd, &wset);
|
||||
if (sockfd > maxSock)
|
||||
{
|
||||
maxSock = sockfd;
|
||||
}
|
||||
}
|
||||
client = client->getNextClient();
|
||||
}
|
||||
|
||||
if (maxSock == 0)
|
||||
{
|
||||
usleep(500 * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check sockets is ready to read */
|
||||
int activity = select(maxSock + 1, &rset, 0, 0, &timeout);
|
||||
if (activity > 0)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(0);
|
||||
if (maxSock == 0)
|
||||
{
|
||||
usleep(500 * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check sockets is ready to read */
|
||||
int activity = select(maxSock + 1, &rset, 0, 0, &timeout);
|
||||
|
||||
while ( client )
|
||||
{
|
||||
_light->blueLight(false);
|
||||
if (client->getNetwork()->isValid())
|
||||
{
|
||||
int sockfd = client->getNetwork()->getSock();
|
||||
if (FD_ISSET(sockfd, &rset))
|
||||
{
|
||||
packet = new MQTTGWPacket();
|
||||
rc = 0;
|
||||
/* read sockets */
|
||||
_light->blueLight(true);
|
||||
rc = packet->recv(client->getNetwork());
|
||||
if ( rc > 0 )
|
||||
{
|
||||
if ( log(client, packet) == -1 )
|
||||
{
|
||||
delete packet;
|
||||
goto nextClient;
|
||||
}
|
||||
if (activity > 0)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(0);
|
||||
|
||||
/* post a BrokerRecvEvent */
|
||||
ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( rc == 0 ) // Disconnected
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
delete packet;
|
||||
while (client)
|
||||
{
|
||||
_light->blueLight(false);
|
||||
if (client->getNetwork()->isValid())
|
||||
{
|
||||
int sockfd = client->getNetwork()->getSock();
|
||||
if (FD_ISSET(sockfd, &rset))
|
||||
{
|
||||
packet = new MQTTGWPacket();
|
||||
rc = 0;
|
||||
/* read sockets */
|
||||
_light->blueLight(true);
|
||||
rc = packet->recv(client->getNetwork());
|
||||
if (rc > 0)
|
||||
{
|
||||
if (log(client, packet) == -1)
|
||||
{
|
||||
delete packet;
|
||||
goto nextClient;
|
||||
}
|
||||
|
||||
/* delete client when the client is not authorized & session is clean */
|
||||
_gateway->getClientList()->erase(client);
|
||||
/* post a BrokerRecvEvent */
|
||||
ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rc == 0) // Disconnected
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask %s is disconnected by the broker.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
}
|
||||
else if (rc == -1)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n",
|
||||
ERRMSG_HEADER, errno, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else if (rc == -2)
|
||||
{
|
||||
WRITELOG(
|
||||
"%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else if (rc == -3)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't allocate memories for the packet %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
|
||||
if ( client )
|
||||
{
|
||||
client = client->getNextClient();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (rc == -1)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n", ERRMSG_HEADER, errno, client->getClientId(), ERRMSG_FOOTER);
|
||||
}
|
||||
else if ( rc == -2 )
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n", ERRMSG_HEADER, client->getClientId(),ERRMSG_FOOTER);
|
||||
}
|
||||
else if ( rc == -3 )
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't get memories for the packet %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
}
|
||||
delete packet;
|
||||
|
||||
delete packet;
|
||||
|
||||
if ( (rc == -1 || rc == -2) && ( client->isActive() || client->isSleep() || client->isAwake() ))
|
||||
{
|
||||
/* disconnect the client */
|
||||
packet = new MQTTGWPacket();
|
||||
packet->setHeader(DISCONNECT);
|
||||
ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextClient:
|
||||
client = client->getNextClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((rc == -1 || rc == -2) && (client->isActive() || client->isSleep() || client->isAwake()))
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextClient: client = client->getNextClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,35 +184,38 @@ void BrokerRecvTask::run(void)
|
||||
*/
|
||||
int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5 )* 3];
|
||||
char msgId[6];
|
||||
int rc = 0;
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5) * 3];
|
||||
char msgId[6];
|
||||
int rc = 0;
|
||||
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNACK:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGRESP:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
WRITELOG("Type=%x\n", packet->getType());
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNACK:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGRESP:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
WRITELOG("Type=%x\n", packet->getType());
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -28,21 +28,20 @@ namespace MQTTSNGW
|
||||
class BrokerRecvTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
;
|
||||
|
||||
public:
|
||||
BrokerRecvTask(Gateway* gateway);
|
||||
~BrokerRecvTask();
|
||||
void initialize(int argc, char** argv);
|
||||
void run(void);
|
||||
BrokerRecvTask(Gateway* gateway);
|
||||
~BrokerRecvTask();
|
||||
void initialize(int argc, char** argv);
|
||||
void run(void);
|
||||
|
||||
private:
|
||||
int log(Client*, MQTTGWPacket*);
|
||||
int log(Client*, MQTTGWPacket*);
|
||||
|
||||
Gateway* _gateway;
|
||||
LightIndicator* _light;
|
||||
Gateway* _gateway;
|
||||
LightIndicator* _light;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* MQTTSNGWBROKERRECVTASK_H_ */
|
||||
|
||||
@@ -33,15 +33,15 @@ char* currentDateTime();
|
||||
=====================================*/
|
||||
BrokerSendTask::BrokerSendTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_gwparams = nullptr;
|
||||
_light = nullptr;
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_gwparams = nullptr;
|
||||
_light = nullptr;
|
||||
setTaskName("BrokerSendTask");
|
||||
}
|
||||
|
||||
BrokerSendTask::~BrokerSendTask()
|
||||
{
|
||||
// WRITELOG("BrokerSendTask is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,8 +49,8 @@ BrokerSendTask::~BrokerSendTask()
|
||||
*/
|
||||
void BrokerSendTask::initialize(int argc, char** argv)
|
||||
{
|
||||
_gwparams = _gateway->getGWParams();
|
||||
_light = _gateway->getLightIndicator();
|
||||
_gwparams = _gateway->getGWParams();
|
||||
_light = _gateway->getLightIndicator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,132 +58,137 @@ void BrokerSendTask::initialize(int argc, char** argv)
|
||||
*/
|
||||
void BrokerSendTask::run()
|
||||
{
|
||||
Event* ev = nullptr;
|
||||
MQTTGWPacket* packet = nullptr;
|
||||
Client* client = nullptr;
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
int rc = 0;
|
||||
Event* ev = nullptr;
|
||||
MQTTGWPacket* packet = nullptr;
|
||||
Client* client = nullptr;
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
int rc = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ev = _gateway->getBrokerSendQue()->wait();
|
||||
while (true)
|
||||
{
|
||||
ev = _gateway->getBrokerSendQue()->wait();
|
||||
|
||||
if ( ev->getEventType() == EtStop )
|
||||
{
|
||||
WRITELOG("\n%s BrokerSendTask stopped.", currentDateTime());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ev->getEventType() == EtBrokerSend)
|
||||
{
|
||||
client = ev->getClient();
|
||||
packet = ev->getMQTTGWPacket();
|
||||
if (ev->getEventType() == EtBrokerSend)
|
||||
{
|
||||
client = ev->getClient();
|
||||
packet = ev->getMQTTGWPacket();
|
||||
|
||||
/* Check Client is managed by Adapters */
|
||||
client = adpMgr->getClient(client);
|
||||
/* Check Client is managed by Adapters */
|
||||
client = adpMgr->getClient(client);
|
||||
|
||||
if ( packet->getType() == CONNECT && client->getNetwork()->isValid() )
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
if (packet->getType() == CONNECT && client->getNetwork()->isValid())
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
|
||||
if ( !client->getNetwork()->isValid() )
|
||||
{
|
||||
/* connect to the broker and send a packet */
|
||||
if (!client->getNetwork()->isValid())
|
||||
{
|
||||
/* connect to the broker and send a packet */
|
||||
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*)_gwparams->brokerName, (const char*)_gwparams->portSecure, (const char*)_gwparams->rootCApath,
|
||||
(const char*)_gwparams->rootCAfile, (const char*)_gwparams->certKey, (const char*)_gwparams->privateKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*)_gwparams->brokerName, (const char*)_gwparams->port);
|
||||
}
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->portSecure,
|
||||
(const char*) _gwparams->rootCApath, (const char*) _gwparams->rootCAfile,
|
||||
(const char*) _gwparams->certKey, (const char*) _gwparams->privateKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->port);
|
||||
}
|
||||
|
||||
if ( !rc )
|
||||
{
|
||||
/* disconnect the broker and the client */
|
||||
WRITELOG("%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), errno, strerror(errno), ERRMSG_FOOTER);
|
||||
delete ev;
|
||||
client->getNetwork()->close();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!rc)
|
||||
{
|
||||
/* disconnect the broker and the client */
|
||||
WRITELOG("%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), errno, strerror(errno), ERRMSG_FOOTER);
|
||||
delete ev;
|
||||
client->getNetwork()->close();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* send a packet */
|
||||
_light->blueLight(true);
|
||||
if ( (rc = packet->send(client->getNetwork())) > 0 )
|
||||
{
|
||||
if ( packet->getType() == CONNECT )
|
||||
{
|
||||
client->connectSended();
|
||||
}
|
||||
else if ( packet->getType() == DISCONNECT )
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
}
|
||||
log(client, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s BrokerSendTask: %s can't send a packet to the broker. errno=%d %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), rc == -1 ? errno : 0, strerror(errno), ERRMSG_FOOTER);
|
||||
if ( errno != EBADF )
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
/* send a packet */
|
||||
_light->blueLight(true);
|
||||
if ((rc = packet->send(client->getNetwork())) > 0)
|
||||
{
|
||||
if (packet->getType() == CONNECT)
|
||||
{
|
||||
client->connectSended();
|
||||
}
|
||||
else if (packet->getType() == DISCONNECT)
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
}
|
||||
log(client, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s BrokerSendTask: %s can't send a packet to the broker. errno=%d %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), rc == -1 ? errno : 0, strerror(errno), ERRMSG_FOOTER);
|
||||
if ( errno != EBADF)
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
|
||||
/* Disconnect the client */
|
||||
packet = new MQTTGWPacket();
|
||||
packet->setHeader(DISCONNECT);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev1);
|
||||
}
|
||||
/* Disconnect the client */
|
||||
packet = new MQTTGWPacket();
|
||||
packet->setHeader(DISCONNECT);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev1);
|
||||
}
|
||||
|
||||
_light->blueLight(false);
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
_light->blueLight(false);
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* write message content into stdout or Ringbuffer
|
||||
*/
|
||||
void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5 )* 3];
|
||||
char msgId[6];
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5) * 3];
|
||||
char msgId[6];
|
||||
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGREQ:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case DISCONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGREQ:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case DISCONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,22 +25,22 @@ namespace MQTTSNGW
|
||||
class Adapter;
|
||||
|
||||
/*=====================================
|
||||
Class BrokerSendTask
|
||||
Class BrokerSendTask
|
||||
=====================================*/
|
||||
class BrokerSendTask : public Thread
|
||||
class BrokerSendTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
public:
|
||||
BrokerSendTask(Gateway* gateway);
|
||||
~BrokerSendTask();
|
||||
void initialize(int argc, char** argv);
|
||||
void run();
|
||||
BrokerSendTask(Gateway* gateway);
|
||||
~BrokerSendTask();
|
||||
void initialize(int argc, char** argv);
|
||||
void run();
|
||||
private:
|
||||
void log(Client*, MQTTGWPacket*);
|
||||
Gateway* _gateway;
|
||||
GatewayParams* _gwparams;
|
||||
LightIndicator* _light;
|
||||
void log(Client*, MQTTGWPacket*);
|
||||
Gateway* _gateway;
|
||||
GatewayParams* _gwparams;
|
||||
LightIndicator* _light;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,104 +28,104 @@
|
||||
using namespace MQTTSNGW;
|
||||
char* currentDateTime(void);
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Client
|
||||
=====================================*/
|
||||
static const char* theClientStatus[] = { "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake", "Lost" };
|
||||
static const char* theClientStatus[] = { "InPool", "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake",
|
||||
"Lost" };
|
||||
|
||||
Client::Client(bool secure)
|
||||
{
|
||||
_packetId = 0;
|
||||
_snMsgId = 0;
|
||||
_status = Cstat_Disconnected;
|
||||
_keepAliveMsec = 0;
|
||||
_topics = new Topics();
|
||||
_clientId = nullptr;
|
||||
_willTopic = nullptr;
|
||||
_willMsg = nullptr;
|
||||
_connectData = MQTTPacket_Connect_Initializer;
|
||||
_network = new Network(secure);
|
||||
_secureNetwork = secure;
|
||||
_sensorNetype = true;
|
||||
_connAck = nullptr;
|
||||
_waitWillMsgFlg = false;
|
||||
_sessionStatus = false;
|
||||
_prevClient = nullptr;
|
||||
_nextClient = nullptr;
|
||||
_clientSleepPacketQue.setMaxSize(MAX_SAVED_PUBLISH);
|
||||
_proxyPacketQue.setMaxSize(MAX_SAVED_PUBLISH);
|
||||
_hasPredefTopic = false;
|
||||
_holdPingRequest = false;
|
||||
_forwarder = nullptr;
|
||||
_clientType = Ctype_Regular;
|
||||
_packetId = 0;
|
||||
_snMsgId = 0;
|
||||
_status = Cstat_Free;
|
||||
_keepAliveMsec = 0;
|
||||
_topics = new Topics();
|
||||
_clientId = nullptr;
|
||||
_willTopic = nullptr;
|
||||
_willMsg = nullptr;
|
||||
_connectData = MQTTPacket_Connect_Initializer;
|
||||
_network = new Network(secure);
|
||||
_secureNetwork = secure;
|
||||
_sensorNetype = true;
|
||||
_connAck = nullptr;
|
||||
_waitWillMsgFlg = false;
|
||||
_sessionStatus = false;
|
||||
_prevClient = nullptr;
|
||||
_nextClient = nullptr;
|
||||
_clientSleepPacketQue.setMaxSize(MAX_SAVED_PUBLISH);
|
||||
_proxyPacketQue.setMaxSize(MAX_SAVED_PUBLISH);
|
||||
_hasPredefTopic = false;
|
||||
_holdPingRequest = false;
|
||||
_forwarder = nullptr;
|
||||
_clientType = Ctype_Normal;
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
if ( _topics )
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
if (_topics)
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
|
||||
if ( _clientId )
|
||||
{
|
||||
free(_clientId);
|
||||
}
|
||||
if (_clientId)
|
||||
{
|
||||
free(_clientId);
|
||||
}
|
||||
|
||||
if ( _willTopic )
|
||||
{
|
||||
free(_willTopic);
|
||||
}
|
||||
if (_willTopic)
|
||||
{
|
||||
free(_willTopic);
|
||||
}
|
||||
|
||||
if ( _willMsg )
|
||||
{
|
||||
free(_willMsg);
|
||||
}
|
||||
if (_willMsg)
|
||||
{
|
||||
free(_willMsg);
|
||||
}
|
||||
|
||||
if (_connAck)
|
||||
{
|
||||
delete _connAck;
|
||||
}
|
||||
if (_connAck)
|
||||
{
|
||||
delete _connAck;
|
||||
}
|
||||
|
||||
if (_network)
|
||||
{
|
||||
delete _network;
|
||||
}
|
||||
if (_network)
|
||||
{
|
||||
delete _network;
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMapElement* Client::getWaitedPubTopicId(uint16_t msgId)
|
||||
{
|
||||
return _waitedPubTopicIdMap.getElement(msgId);
|
||||
return _waitedPubTopicIdMap.getElement(msgId);
|
||||
}
|
||||
|
||||
TopicIdMapElement* Client::getWaitedSubTopicId(uint16_t msgId)
|
||||
{
|
||||
return _waitedSubTopicIdMap.getElement(msgId);
|
||||
return _waitedSubTopicIdMap.getElement(msgId);
|
||||
}
|
||||
|
||||
MQTTGWPacket* Client::getClientSleepPacket()
|
||||
{
|
||||
return _clientSleepPacketQue.getPacket();
|
||||
return _clientSleepPacketQue.getPacket();
|
||||
}
|
||||
|
||||
void Client::deleteFirstClientSleepPacket()
|
||||
{
|
||||
_clientSleepPacketQue.pop();
|
||||
_clientSleepPacketQue.pop();
|
||||
}
|
||||
|
||||
int Client::setClientSleepPacket(MQTTGWPacket* packet)
|
||||
{
|
||||
int rc = _clientSleepPacketQue.post(packet);
|
||||
if ( rc )
|
||||
{
|
||||
WRITELOG("%s %s is sleeping. the packet was saved.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s %s is sleeping but discard the packet.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
return rc;
|
||||
int rc = _clientSleepPacketQue.post(packet);
|
||||
if (rc)
|
||||
{
|
||||
WRITELOG("%s %s is sleeping. the packet was saved.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s %s is sleeping but discard the packet.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
MQTTSNPacket* Client::getProxyPacket(void)
|
||||
@@ -141,7 +141,7 @@ void Client::deleteFirstProxyPacket()
|
||||
int Client::setProxyPacket(MQTTSNPacket* packet)
|
||||
{
|
||||
int rc = _proxyPacketQue.post(packet);
|
||||
if ( rc )
|
||||
if (rc)
|
||||
{
|
||||
WRITELOG("%s %s is Disconnected. the packet was saved.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
@@ -154,51 +154,52 @@ int Client::setProxyPacket(MQTTSNPacket* packet)
|
||||
|
||||
Connect* Client::getConnectData(void)
|
||||
{
|
||||
return &_connectData;
|
||||
return &_connectData;
|
||||
}
|
||||
|
||||
void Client::eraseWaitedPubTopicId(uint16_t msgId)
|
||||
{
|
||||
_waitedPubTopicIdMap.erase(msgId);
|
||||
_waitedPubTopicIdMap.erase(msgId);
|
||||
}
|
||||
|
||||
void Client::eraseWaitedSubTopicId(uint16_t msgId)
|
||||
{
|
||||
_waitedSubTopicIdMap.erase(msgId);
|
||||
_waitedSubTopicIdMap.erase(msgId);
|
||||
}
|
||||
|
||||
void Client::clearWaitedPubTopicId(void)
|
||||
{
|
||||
_waitedPubTopicIdMap.clear();
|
||||
_waitedPubTopicIdMap.clear();
|
||||
}
|
||||
|
||||
void Client::clearWaitedSubTopicId(void)
|
||||
{
|
||||
_waitedSubTopicIdMap.clear();
|
||||
_waitedSubTopicIdMap.clear();
|
||||
}
|
||||
|
||||
void Client::setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
void Client::setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_waitedPubTopicIdMap.add(msgId, topicId, type);
|
||||
_waitedPubTopicIdMap.add(msgId, topicId, topic);
|
||||
}
|
||||
void Client::setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
|
||||
void Client::setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_waitedSubTopicIdMap.add(msgId, topicId, type);
|
||||
_waitedSubTopicIdMap.add(msgId, topicId, topic);
|
||||
}
|
||||
|
||||
bool Client::checkTimeover(void)
|
||||
{
|
||||
return (_status == Cstat_Active && _keepAliveTimer.isTimeup());
|
||||
return (_status == Cstat_Active && _keepAliveTimer.isTimeup());
|
||||
}
|
||||
|
||||
void Client::setKeepAlive(MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTSNPacket_connectData param;
|
||||
if (packet->getCONNECT(¶m))
|
||||
{
|
||||
_keepAliveMsec = param.duration * 1000UL;
|
||||
_keepAliveTimer.start(_keepAliveMsec * 1.5);
|
||||
}
|
||||
MQTTSNPacket_connectData param;
|
||||
if (packet->getCONNECT(¶m))
|
||||
{
|
||||
_keepAliveMsec = param.duration * 1000UL;
|
||||
_keepAliveTimer.start(_keepAliveMsec * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setForwarder(Forwarder* forwarder)
|
||||
@@ -214,102 +215,101 @@ Forwarder* Client::getForwarder(void)
|
||||
|
||||
void Client::setSessionStatus(bool status)
|
||||
{
|
||||
_sessionStatus = status;
|
||||
_sessionStatus = status;
|
||||
}
|
||||
|
||||
bool Client::erasable(void)
|
||||
{
|
||||
return _sessionStatus && !_hasPredefTopic && _forwarder == nullptr;
|
||||
return _sessionStatus && !_hasPredefTopic && _forwarder == nullptr;
|
||||
}
|
||||
|
||||
void Client::updateStatus(MQTTSNPacket* packet)
|
||||
{
|
||||
if (((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) && packet->getType() == MQTTSN_CONNECT)
|
||||
{
|
||||
setKeepAlive(packet);
|
||||
}
|
||||
else if (_status == Cstat_Active)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_PINGREQ:
|
||||
case MQTTSN_PUBLISH:
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBREC:
|
||||
if ( _clientType != Ctype_Proxy )
|
||||
{
|
||||
_keepAliveTimer.start(_keepAliveMsec * 1.5);
|
||||
}
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
uint16_t duration;
|
||||
packet->getDISCONNECT(&duration);
|
||||
if (duration)
|
||||
{
|
||||
_status = Cstat_Asleep;
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnected();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_status == Cstat_Awake || _status == Cstat_Asleep)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_CONNECT:
|
||||
_status = Cstat_Active;
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
disconnected();
|
||||
break;
|
||||
case MQTTSN_PINGREQ:
|
||||
_status = Cstat_Awake;
|
||||
break;
|
||||
case MQTTSN_PINGRESP:
|
||||
_status = Cstat_Asleep;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
|
||||
if (((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) && packet->getType() == MQTTSN_CONNECT)
|
||||
{
|
||||
setKeepAlive(packet);
|
||||
}
|
||||
else if (_status == Cstat_Active)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_PINGREQ:
|
||||
case MQTTSN_PUBLISH:
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBREC:
|
||||
if (_clientType != Ctype_Proxy)
|
||||
{
|
||||
_keepAliveTimer.start(_keepAliveMsec * 1.5);
|
||||
}
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
uint16_t duration;
|
||||
packet->getDISCONNECT(&duration);
|
||||
if (duration)
|
||||
{
|
||||
_status = Cstat_Asleep;
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnected();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_status == Cstat_Awake || _status == Cstat_Asleep)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_CONNECT:
|
||||
_status = Cstat_Active;
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
disconnected();
|
||||
break;
|
||||
case MQTTSN_PINGREQ:
|
||||
_status = Cstat_Awake;
|
||||
break;
|
||||
case MQTTSN_PINGRESP:
|
||||
_status = Cstat_Asleep;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
|
||||
}
|
||||
|
||||
void Client::updateStatus(ClientStatus stat)
|
||||
{
|
||||
_status = stat;
|
||||
_status = stat;
|
||||
}
|
||||
|
||||
void Client::connectSended()
|
||||
{
|
||||
_status = Cstat_Connecting;
|
||||
_status = Cstat_Connecting;
|
||||
}
|
||||
|
||||
void Client::connackSended(int rc)
|
||||
{
|
||||
if (rc == MQTTSN_RC_ACCEPTED)
|
||||
{
|
||||
_status = Cstat_Active;
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnected();
|
||||
}
|
||||
if (rc == MQTTSN_RC_ACCEPTED)
|
||||
{
|
||||
_status = Cstat_Active;
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::disconnected(void)
|
||||
{
|
||||
_status = Cstat_Disconnected;
|
||||
_waitWillMsgFlg = false;
|
||||
_status = Cstat_Disconnected;
|
||||
_waitWillMsgFlg = false;
|
||||
}
|
||||
|
||||
void Client::tryConnect(void)
|
||||
@@ -317,66 +317,71 @@ void Client::tryConnect(void)
|
||||
_status = Cstat_TryConnecting;
|
||||
}
|
||||
|
||||
bool Client::isCleanSession(void)
|
||||
{
|
||||
return _sessionStatus;
|
||||
}
|
||||
|
||||
bool Client::isConnectSendable(void)
|
||||
{
|
||||
if ( _status == Cstat_Lost || _status == Cstat_TryConnecting )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (_status == Cstat_Lost || _status == Cstat_TryConnecting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Client::getNextPacketId(void)
|
||||
{
|
||||
_packetId++;
|
||||
if ( _packetId == 0xffff )
|
||||
{
|
||||
_packetId = 1;
|
||||
}
|
||||
return _packetId;
|
||||
_packetId++;
|
||||
if (_packetId == 0xffff)
|
||||
{
|
||||
_packetId = 1;
|
||||
}
|
||||
return _packetId;
|
||||
}
|
||||
|
||||
uint8_t Client::getNextSnMsgId(void)
|
||||
{
|
||||
_snMsgId++;
|
||||
if (_snMsgId == 0)
|
||||
{
|
||||
_snMsgId++;
|
||||
}
|
||||
return _snMsgId;
|
||||
_snMsgId++;
|
||||
if (_snMsgId == 0)
|
||||
{
|
||||
_snMsgId++;
|
||||
}
|
||||
return _snMsgId;
|
||||
}
|
||||
|
||||
Topics* Client::getTopics(void)
|
||||
{
|
||||
return _topics;
|
||||
return _topics;
|
||||
}
|
||||
|
||||
Network* Client::getNetwork(void)
|
||||
{
|
||||
return _network;
|
||||
return _network;
|
||||
}
|
||||
|
||||
void Client::setClientAddress(SensorNetAddress* sensorNetAddr)
|
||||
{
|
||||
_sensorNetAddr = *sensorNetAddr;
|
||||
_sensorNetAddr = *sensorNetAddr;
|
||||
}
|
||||
|
||||
SensorNetAddress* Client::getSensorNetAddress(void)
|
||||
{
|
||||
return &_sensorNetAddr;
|
||||
return &_sensorNetAddr;
|
||||
}
|
||||
|
||||
void Client::setSensorNetType(bool stable)
|
||||
{
|
||||
_sensorNetype = stable;
|
||||
_sensorNetype = stable;
|
||||
}
|
||||
|
||||
void Client::setTopics(Topics* topics)
|
||||
{
|
||||
_topics = topics;
|
||||
_topics = topics;
|
||||
}
|
||||
|
||||
ClientStatus Client::getClientStatus(void)
|
||||
@@ -386,32 +391,32 @@ ClientStatus Client::getClientStatus(void)
|
||||
|
||||
void Client::setWaitWillMsgFlg(bool flg)
|
||||
{
|
||||
_waitWillMsgFlg = flg;
|
||||
_waitWillMsgFlg = flg;
|
||||
}
|
||||
|
||||
bool Client::isWaitWillMsg(void)
|
||||
{
|
||||
return _waitWillMsgFlg;
|
||||
return _waitWillMsgFlg;
|
||||
}
|
||||
|
||||
bool Client::isDisconnect(void)
|
||||
{
|
||||
return (_status == Cstat_Disconnected);
|
||||
return (_status == Cstat_Disconnected);
|
||||
}
|
||||
|
||||
bool Client::isActive(void)
|
||||
{
|
||||
return (_status == Cstat_Active);
|
||||
return (_status == Cstat_Active);
|
||||
}
|
||||
|
||||
bool Client::isSleep(void)
|
||||
{
|
||||
return (_status == Cstat_Asleep);
|
||||
return (_status == Cstat_Asleep);
|
||||
}
|
||||
|
||||
bool Client::isAwake(void)
|
||||
{
|
||||
return (_status == Cstat_Awake);
|
||||
return (_status == Cstat_Awake);
|
||||
}
|
||||
|
||||
bool Client::isConnecting(void)
|
||||
@@ -421,94 +426,94 @@ bool Client::isConnecting(void)
|
||||
|
||||
bool Client::isSecureNetwork(void)
|
||||
{
|
||||
return _secureNetwork;
|
||||
return _secureNetwork;
|
||||
}
|
||||
|
||||
bool Client::isSensorNetStable(void)
|
||||
{
|
||||
return _sensorNetype;
|
||||
return _sensorNetype;
|
||||
}
|
||||
|
||||
WaitREGACKPacketList* Client::getWaitREGACKPacketList()
|
||||
{
|
||||
return &_waitREGACKList;
|
||||
return &_waitREGACKList;
|
||||
}
|
||||
|
||||
Client* Client::getNextClient(void)
|
||||
{
|
||||
return _nextClient;
|
||||
return _nextClient;
|
||||
}
|
||||
|
||||
void Client::setClientId(MQTTSNString id)
|
||||
{
|
||||
if ( _clientId )
|
||||
{
|
||||
free(_clientId);
|
||||
}
|
||||
if (_clientId)
|
||||
{
|
||||
free(_clientId);
|
||||
}
|
||||
|
||||
if ( id.cstring )
|
||||
{
|
||||
_clientId = (char*)calloc(strlen(id.cstring) + 1, 1);
|
||||
memcpy(_clientId, id.cstring, strlen(id.cstring));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (id.cstring)
|
||||
{
|
||||
_clientId = (char*) calloc(strlen(id.cstring) + 1, 1);
|
||||
memcpy(_clientId, id.cstring, strlen(id.cstring));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save clientId into (char*)_clientId NULL terminated */
|
||||
_clientId = (char*)calloc(MQTTSNstrlen(id) + 1, 1);
|
||||
unsigned char* ptr = (unsigned char*)_clientId;
|
||||
writeMQTTSNString((unsigned char**)&ptr, id);
|
||||
}
|
||||
_clientId = (char*) calloc(MQTTSNstrlen(id) + 1, 1);
|
||||
unsigned char* ptr = (unsigned char*) _clientId;
|
||||
writeMQTTSNString((unsigned char**) &ptr, id);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setWillTopic(MQTTSNString willTopic)
|
||||
{
|
||||
if ( _willTopic )
|
||||
{
|
||||
free(_willTopic);
|
||||
}
|
||||
if (_willTopic)
|
||||
{
|
||||
free(_willTopic);
|
||||
}
|
||||
|
||||
_willTopic = (char*)calloc(MQTTSNstrlen(willTopic) + 1, 1);
|
||||
/* save willTopic into (char*)_willTopic with NULL termination */
|
||||
unsigned char* ptr = (unsigned char*)_willTopic;
|
||||
writeMQTTSNString((unsigned char**)&ptr, willTopic);
|
||||
_willTopic = (char*) calloc(MQTTSNstrlen(willTopic) + 1, 1);
|
||||
/* save willTopic into (char*)_willTopic with NULL termination */
|
||||
unsigned char* ptr = (unsigned char*) _willTopic;
|
||||
writeMQTTSNString((unsigned char**) &ptr, willTopic);
|
||||
}
|
||||
|
||||
void Client::setWillMsg(MQTTSNString willMsg)
|
||||
{
|
||||
if ( _willMsg)
|
||||
{
|
||||
free(_willMsg);
|
||||
}
|
||||
if (_willMsg)
|
||||
{
|
||||
free(_willMsg);
|
||||
}
|
||||
|
||||
_willMsg = (char*)calloc(MQTTSNstrlen(willMsg) + 1, 1);
|
||||
/* save willMsg into (char*)_willMsg with NULL termination */
|
||||
unsigned char* ptr = (unsigned char*)_willMsg;
|
||||
writeMQTTSNString((unsigned char**)&ptr, willMsg);
|
||||
_willMsg = (char*) calloc(MQTTSNstrlen(willMsg) + 1, 1);
|
||||
/* save willMsg into (char*)_willMsg with NULL termination */
|
||||
unsigned char* ptr = (unsigned char*) _willMsg;
|
||||
writeMQTTSNString((unsigned char**) &ptr, willMsg);
|
||||
}
|
||||
|
||||
char* Client::getClientId(void)
|
||||
{
|
||||
return _clientId;
|
||||
return _clientId;
|
||||
}
|
||||
|
||||
char* Client::getWillTopic(void)
|
||||
{
|
||||
return _willTopic;
|
||||
return _willTopic;
|
||||
}
|
||||
|
||||
char* Client::getWillMsg(void)
|
||||
{
|
||||
return _willMsg;
|
||||
return _willMsg;
|
||||
}
|
||||
|
||||
const char* Client::getStatus(void)
|
||||
{
|
||||
return theClientStatus[_status];
|
||||
return theClientStatus[_status];
|
||||
}
|
||||
|
||||
bool Client::isQoSm1Proxy(void)
|
||||
{
|
||||
return _clientType == Ctype_Proxy;
|
||||
return _clientType == Ctype_Proxy;
|
||||
}
|
||||
|
||||
bool Client::isForwarded(void)
|
||||
@@ -528,23 +533,23 @@ bool Client::isAggregater(void)
|
||||
|
||||
void Client::setAdapterType(AdapterType type)
|
||||
{
|
||||
switch ( type )
|
||||
switch (type)
|
||||
{
|
||||
case Atype_QoSm1Proxy:
|
||||
_clientType = Ctype_Proxy;
|
||||
break;
|
||||
_clientType = Ctype_Proxy;
|
||||
break;
|
||||
case Atype_Aggregater:
|
||||
_clientType = Ctype_Aggregater;
|
||||
break;
|
||||
_clientType = Ctype_Aggregater;
|
||||
break;
|
||||
default:
|
||||
throw Exception("Client::setAdapterType(): Invalid Type.");
|
||||
break;
|
||||
throw EXCEPTION("Client::setAdapterType(): Invalid Type.", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Client::isAdapter(void)
|
||||
{
|
||||
return _clientType == Ctype_Proxy || _clientType == Ctype_Aggregater;
|
||||
return _clientType == Ctype_Proxy || _clientType == Ctype_Aggregater;
|
||||
}
|
||||
|
||||
bool Client::isQoSm1(void)
|
||||
@@ -554,12 +559,12 @@ bool Client::isQoSm1(void)
|
||||
|
||||
void Client::setQoSm1(void)
|
||||
{
|
||||
_clientType = Ctype_QoS_1;
|
||||
_clientType = Ctype_QoS_1;
|
||||
}
|
||||
|
||||
void Client::setAggregated(void)
|
||||
{
|
||||
_clientType = Ctype_Aggregated;
|
||||
_clientType = Ctype_Aggregated;
|
||||
}
|
||||
|
||||
void Client::holdPingRequest(void)
|
||||
@@ -577,22 +582,20 @@ bool Client::isHoldPingReqest(void)
|
||||
return _holdPingRequest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class WaitREGACKPacket
|
||||
=====================================*/
|
||||
waitREGACKPacket::waitREGACKPacket(MQTTSNPacket* packet, uint16_t REGACKMsgId)
|
||||
{
|
||||
_packet = packet;
|
||||
_msgId = REGACKMsgId;
|
||||
_next = nullptr;
|
||||
_prev = nullptr;
|
||||
_packet = packet;
|
||||
_msgId = REGACKMsgId;
|
||||
_next = nullptr;
|
||||
_prev = nullptr;
|
||||
}
|
||||
|
||||
waitREGACKPacket::~waitREGACKPacket()
|
||||
{
|
||||
delete _packet;
|
||||
delete _packet;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -601,89 +604,89 @@ waitREGACKPacket::~waitREGACKPacket()
|
||||
|
||||
WaitREGACKPacketList::WaitREGACKPacketList()
|
||||
{
|
||||
_first = nullptr;
|
||||
_end = nullptr;
|
||||
_cnt = 0;
|
||||
_first = nullptr;
|
||||
_end = nullptr;
|
||||
_cnt = 0;
|
||||
}
|
||||
|
||||
WaitREGACKPacketList::~WaitREGACKPacketList()
|
||||
{
|
||||
waitREGACKPacket* p = _first;
|
||||
while (p)
|
||||
{
|
||||
waitREGACKPacket* q = p->_next;
|
||||
delete p;
|
||||
p = q;
|
||||
}
|
||||
waitREGACKPacket* p = _first;
|
||||
while (p)
|
||||
{
|
||||
waitREGACKPacket* q = p->_next;
|
||||
delete p;
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
int WaitREGACKPacketList::setPacket(MQTTSNPacket* packet, uint16_t REGACKMsgId)
|
||||
{
|
||||
waitREGACKPacket* elm = new waitREGACKPacket(packet, REGACKMsgId);
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
waitREGACKPacket* elm = new waitREGACKPacket(packet, REGACKMsgId);
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_first == nullptr)
|
||||
{
|
||||
_first = elm;
|
||||
_end = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
_end->_next = elm;
|
||||
elm->_prev = _end;
|
||||
_end = elm;
|
||||
}
|
||||
_cnt++;
|
||||
return 1;
|
||||
if (_first == nullptr)
|
||||
{
|
||||
_first = elm;
|
||||
_end = elm;
|
||||
}
|
||||
else
|
||||
{
|
||||
_end->_next = elm;
|
||||
elm->_prev = _end;
|
||||
_end = elm;
|
||||
}
|
||||
_cnt++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
MQTTSNPacket* WaitREGACKPacketList::getPacket(uint16_t REGACKMsgId)
|
||||
{
|
||||
waitREGACKPacket* p = _first;
|
||||
while (p)
|
||||
{
|
||||
if (p->_msgId == REGACKMsgId)
|
||||
{
|
||||
return p->_packet;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return nullptr;
|
||||
waitREGACKPacket* p = _first;
|
||||
while (p)
|
||||
{
|
||||
if (p->_msgId == REGACKMsgId)
|
||||
{
|
||||
return p->_packet;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WaitREGACKPacketList::erase(uint16_t REGACKMsgId)
|
||||
{
|
||||
waitREGACKPacket* p = _first;
|
||||
while (p)
|
||||
{
|
||||
if (p->_msgId == REGACKMsgId)
|
||||
{
|
||||
if (p->_prev == nullptr)
|
||||
{
|
||||
_first = p->_next;
|
||||
waitREGACKPacket* p = _first;
|
||||
while (p)
|
||||
{
|
||||
if (p->_msgId == REGACKMsgId)
|
||||
{
|
||||
if (p->_prev == nullptr)
|
||||
{
|
||||
_first = p->_next;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
if (p->_next == nullptr)
|
||||
{
|
||||
_end = p->_prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->_next->_prev = p->_prev;
|
||||
}
|
||||
_cnt--;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
if (p->_next == nullptr)
|
||||
{
|
||||
_end = p->_prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->_next->_prev = p->_prev;
|
||||
}
|
||||
_cnt--;
|
||||
break;
|
||||
// Do not delete element. Element is deleted after sending to Client.
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t WaitREGACKPacketList::getCount(void)
|
||||
@@ -691,4 +694,3 @@ uint8_t WaitREGACKPacketList::getCount(void)
|
||||
return _cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
_que = new Que<T>;
|
||||
}
|
||||
|
||||
|
||||
~PacketQue()
|
||||
{
|
||||
clear();
|
||||
@@ -72,8 +71,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
post(T* packet)
|
||||
int post(T* packet)
|
||||
{
|
||||
int rc;
|
||||
_mutex.lock();
|
||||
@@ -113,8 +111,6 @@ private:
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class WaitREGACKPacket
|
||||
=====================================*/
|
||||
@@ -151,26 +147,37 @@ private:
|
||||
waitREGACKPacket* _end;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Client
|
||||
=====================================*/
|
||||
typedef enum
|
||||
{
|
||||
Cstat_Disconnected = 0, Cstat_TryConnecting, Cstat_Connecting, Cstat_Active, Cstat_Asleep, Cstat_Awake, Cstat_Lost
|
||||
Cstat_Free = 0,
|
||||
Cstat_Disconnected,
|
||||
Cstat_TryConnecting,
|
||||
Cstat_Connecting,
|
||||
Cstat_Active,
|
||||
Cstat_Asleep,
|
||||
Cstat_Awake,
|
||||
Cstat_Lost
|
||||
} ClientStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Ctype_Regular = 0, Ctype_Forwarded, Ctype_QoS_1, Ctype_Aggregated, Ctype_Proxy, Ctype_Aggregater
|
||||
}ClientType;
|
||||
Ctype_Normal = 0,
|
||||
Ctype_Forwarded,
|
||||
Ctype_QoS_1,
|
||||
Ctype_Aggregated,
|
||||
Ctype_Proxy,
|
||||
Ctype_Aggregater
|
||||
} ClientType;
|
||||
|
||||
class Forwarder;
|
||||
|
||||
class Client
|
||||
{
|
||||
friend class ClientList;
|
||||
friend class ClientsPool;
|
||||
public:
|
||||
Client(bool secure = false);
|
||||
Client(uint8_t maxInflightMessages, bool secure);
|
||||
@@ -191,10 +198,10 @@ public:
|
||||
void clearWaitedPubTopicId(void);
|
||||
void clearWaitedSubTopicId(void);
|
||||
|
||||
int setClientSleepPacket(MQTTGWPacket*);
|
||||
int setClientSleepPacket(MQTTGWPacket*);
|
||||
int setProxyPacket(MQTTSNPacket* packet);
|
||||
void setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
void setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
|
||||
bool checkTimeover(void);
|
||||
void updateStatus(MQTTSNPacket*);
|
||||
@@ -249,6 +256,7 @@ public:
|
||||
bool isSecureNetwork(void);
|
||||
bool isSensorNetStable(void);
|
||||
bool isWaitWillMsg(void);
|
||||
bool isCleanSession(void);
|
||||
|
||||
void holdPingRequest(void);
|
||||
void resetPingRequest(void);
|
||||
@@ -260,7 +268,7 @@ private:
|
||||
PacketQue<MQTTGWPacket> _clientSleepPacketQue;
|
||||
PacketQue<MQTTSNPacket> _proxyPacketQue;
|
||||
|
||||
WaitREGACKPacketList _waitREGACKList;
|
||||
WaitREGACKPacketList _waitREGACKList;
|
||||
|
||||
Topics* _topics;
|
||||
TopicIdMap _waitedPubTopicIdMap;
|
||||
@@ -285,7 +293,7 @@ private:
|
||||
uint8_t _snMsgId;
|
||||
|
||||
Network* _network; // Broker
|
||||
bool _secureNetwork; // SSL
|
||||
bool _secureNetwork; // SSL
|
||||
bool _sensorNetype; // false: unstable network like a G3
|
||||
SensorNetAddress _sensorNetAddr;
|
||||
|
||||
@@ -299,7 +307,5 @@ private:
|
||||
Client* _prevClient;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWCLIENT_H_ */
|
||||
|
||||
@@ -20,18 +20,20 @@
|
||||
#include <string>
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
extern Gateway* theGateway;
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
const char* common_topic = "*";
|
||||
|
||||
ClientList::ClientList()
|
||||
ClientList::ClientList(Gateway* gw)
|
||||
{
|
||||
_clientCnt = 0;
|
||||
_authorize = false;
|
||||
_firstClient = nullptr;
|
||||
_endClient = nullptr;
|
||||
_clientsPool = new ClientsPool();
|
||||
_gateway = gw;
|
||||
}
|
||||
|
||||
ClientList::~ClientList()
|
||||
@@ -46,43 +48,51 @@ ClientList::~ClientList()
|
||||
delete cl;
|
||||
cl = ncl;
|
||||
};
|
||||
|
||||
if (_clientsPool)
|
||||
{
|
||||
delete _clientsPool;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void ClientList::initialize(bool aggregate)
|
||||
{
|
||||
if (theGateway->getGWParams()->clientAuthentication )
|
||||
_maxClients = _gateway->getGWParams()->maxClients;
|
||||
_clientsPool->allocate(_gateway->getGWParams()->maxClients);
|
||||
|
||||
if (_gateway->getGWParams()->clientAuthentication)
|
||||
{
|
||||
int type = TRANSPEARENT_TYPE;
|
||||
if ( aggregate )
|
||||
{
|
||||
type = AGGREGATER_TYPE;
|
||||
}
|
||||
setClientList(type);
|
||||
int type = TRANSPEARENT_TYPE;
|
||||
if (aggregate)
|
||||
{
|
||||
type = AGGREGATER_TYPE;
|
||||
}
|
||||
setClientList(type);
|
||||
_authorize = true;
|
||||
}
|
||||
|
||||
if ( theGateway->getGWParams()->predefinedTopic )
|
||||
if (_gateway->getGWParams()->predefinedTopic)
|
||||
{
|
||||
setPredefinedTopics(aggregate);
|
||||
setPredefinedTopics(aggregate);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientList::setClientList(int type)
|
||||
{
|
||||
if (!createList(theGateway->getGWParams()->clientListName, type))
|
||||
{
|
||||
throw Exception("ClientList::setClientList No client list defined by config file.");
|
||||
}
|
||||
if (!createList(_gateway->getGWParams()->clientListName, type))
|
||||
{
|
||||
throw EXCEPTION("ClientList::setClientList Client list not found!", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientList::setPredefinedTopics(bool aggrecate)
|
||||
{
|
||||
if ( !readPredefinedList(theGateway->getGWParams()->predefinedTopicFileName, aggrecate) )
|
||||
{
|
||||
throw Exception("ClientList::setPredefinedTopics No predefindTopi list defined by config file.");
|
||||
if (!readPredefinedList(_gateway->getGWParams()->predefinedTopicFileName, aggrecate))
|
||||
{
|
||||
throw EXCEPTION("ClientList::setPredefinedTopics PredefindTopic list not found!", 0);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,17 +158,17 @@ bool ClientList::createList(const char* fileName, int type)
|
||||
forwarder = (data.find("forwarder") != string::npos);
|
||||
secure = (data.find("secureConnection") != string::npos);
|
||||
stable = !(data.find("unstableLine") != string::npos);
|
||||
if ( (qos_1 && type == QOSM1PROXY_TYPE) || (!qos_1 && type == AGGREGATER_TYPE) )
|
||||
if ((qos_1 && type == QOSM1PROXY_TYPE) || (!qos_1 && type == AGGREGATER_TYPE))
|
||||
{
|
||||
createClient(&netAddr, &clientId, stable, secure, type);
|
||||
createClient(&netAddr, &clientId, stable, secure, type);
|
||||
}
|
||||
else if ( forwarder && type == FORWARDER_TYPE)
|
||||
else if (forwarder && type == FORWARDER_TYPE)
|
||||
{
|
||||
theGateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
|
||||
_gateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
|
||||
}
|
||||
else if (type == TRANSPEARENT_TYPE )
|
||||
else if (type == TRANSPEARENT_TYPE)
|
||||
{
|
||||
createClient(&netAddr, &clientId, stable, secure, type);
|
||||
createClient(&netAddr, &clientId, stable, secure, type);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -179,7 +189,8 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
FILE* fp;
|
||||
char buf[MAX_CLIENTID_LENGTH + 256];
|
||||
size_t pos0, pos1;
|
||||
MQTTSNString clientId = MQTTSNString_initializer;;
|
||||
MQTTSNString clientId = MQTTSNString_initializer;
|
||||
;
|
||||
bool rc = false;
|
||||
|
||||
if ((fp = fopen(fileName, "r")) != 0)
|
||||
@@ -201,12 +212,12 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
}
|
||||
|
||||
pos0 = data.find_first_of(",");
|
||||
pos1 = data.find(",", pos0 + 1) ;
|
||||
pos1 = data.find(",", pos0 + 1);
|
||||
string id = data.substr(0, pos0);
|
||||
clientId.cstring = strdup(id.c_str());
|
||||
string topicName = data.substr(pos0 + 1, pos1 - pos0 -1);
|
||||
string topicName = data.substr(pos0 + 1, pos1 - pos0 - 1);
|
||||
uint16_t topicID = stoul(data.substr(pos1 + 1));
|
||||
createPredefinedTopic( &clientId, topicName, topicID, aggregate);
|
||||
createPredefinedTopic(&clientId, topicName, topicID, aggregate);
|
||||
free(clientId.cstring);
|
||||
}
|
||||
fclose(fp);
|
||||
@@ -222,7 +233,7 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
|
||||
void ClientList::erase(Client*& client)
|
||||
{
|
||||
if ( !_authorize && client->erasable())
|
||||
if (!_authorize && client->erasable())
|
||||
{
|
||||
_mutex.lock();
|
||||
Client* prev = client->_prevClient;
|
||||
@@ -247,7 +258,7 @@ void ClientList::erase(Client*& client)
|
||||
}
|
||||
_clientCnt--;
|
||||
Forwarder* fwd = client->getForwarder();
|
||||
if ( fwd )
|
||||
if (fwd)
|
||||
{
|
||||
fwd->eraseClient(client);
|
||||
}
|
||||
@@ -259,14 +270,14 @@ void ClientList::erase(Client*& client)
|
||||
|
||||
Client* ClientList::getClient(SensorNetAddress* addr)
|
||||
{
|
||||
if ( addr )
|
||||
if (addr)
|
||||
{
|
||||
_mutex.lock();
|
||||
Client* client = _firstClient;
|
||||
|
||||
while (client != nullptr)
|
||||
{
|
||||
if (client->getSensorNetAddress()->isMatch(addr) )
|
||||
if (client->getSensorNetAddress()->isMatch(addr))
|
||||
{
|
||||
_mutex.unlock();
|
||||
return client;
|
||||
@@ -280,38 +291,37 @@ Client* ClientList::getClient(SensorNetAddress* addr)
|
||||
|
||||
Client* ClientList::getClient(int index)
|
||||
{
|
||||
Client* client = _firstClient;
|
||||
int p = 0;
|
||||
while ( client != nullptr )
|
||||
{
|
||||
if ( p == index )
|
||||
{
|
||||
return client;
|
||||
}
|
||||
else
|
||||
{
|
||||
client = client->_nextClient;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
Client* client = _firstClient;
|
||||
int p = 0;
|
||||
while (client != nullptr)
|
||||
{
|
||||
if (p == index)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
else
|
||||
{
|
||||
client = client->_nextClient;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Client* ClientList::getClient(MQTTSNString* clientId)
|
||||
{
|
||||
_mutex.lock();
|
||||
Client* client = _firstClient;
|
||||
const char* clID =clientId->cstring;
|
||||
const char* clID = clientId->cstring;
|
||||
|
||||
if (clID == nullptr )
|
||||
if (clID == nullptr)
|
||||
{
|
||||
clID = clientId->lenstring.data;
|
||||
}
|
||||
|
||||
while (client != nullptr)
|
||||
{
|
||||
if (strncmp((const char*)client->getClientId(), clID, MQTTSNstrlen(*clientId)) == 0 )
|
||||
if (strncmp((const char*) client->getClientId(), clID, MQTTSNstrlen(*clientId)) == 0)
|
||||
{
|
||||
_mutex.unlock();
|
||||
return client;
|
||||
@@ -324,57 +334,59 @@ Client* ClientList::getClient(MQTTSNString* clientId)
|
||||
|
||||
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, int type)
|
||||
{
|
||||
return createClient(addr, clientId, false, false, type);
|
||||
return createClient(addr, clientId, false, false, type);
|
||||
}
|
||||
|
||||
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type)
|
||||
{
|
||||
Client* client = nullptr;
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return 0; // full of clients
|
||||
}
|
||||
|
||||
client = getClient(addr);
|
||||
if ( client )
|
||||
Client* client = getClient(addr);
|
||||
if (client)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
/* creat a new client */
|
||||
client = new Client(secure);
|
||||
if ( addr )
|
||||
/* acquire a free client */
|
||||
client = _clientsPool->getClient();
|
||||
|
||||
if (!client)
|
||||
{
|
||||
WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(),
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
client->disconnected();
|
||||
if (addr)
|
||||
{
|
||||
client->setClientAddress(addr);
|
||||
}
|
||||
client->setSensorNetType(unstableLine);
|
||||
if ( MQTTSNstrlen(*clientId) )
|
||||
if (MQTTSNstrlen(*clientId))
|
||||
{
|
||||
client->setClientId(*clientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
MQTTSNString dummyId MQTTSNString_initializer;
|
||||
MQTTSNString dummyId MQTTSNString_initializer;
|
||||
dummyId.cstring = strdup("");
|
||||
client->setClientId(dummyId);
|
||||
free(dummyId.cstring);
|
||||
free(dummyId.cstring);
|
||||
}
|
||||
|
||||
if ( type == AGGREGATER_TYPE )
|
||||
if (type == AGGREGATER_TYPE)
|
||||
{
|
||||
client->setAggregated();
|
||||
client->setAggregated();
|
||||
}
|
||||
else if ( type == QOSM1PROXY_TYPE )
|
||||
else if (type == QOSM1PROXY_TYPE)
|
||||
{
|
||||
client->setQoSm1();
|
||||
}
|
||||
client->getNetwork()->setSecure(secure);
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
/* add the list */
|
||||
if ( _firstClient == nullptr )
|
||||
if (_firstClient == nullptr)
|
||||
{
|
||||
_firstClient = client;
|
||||
_endClient = client;
|
||||
@@ -390,66 +402,40 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
return client;
|
||||
}
|
||||
|
||||
Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
|
||||
Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
|
||||
{
|
||||
if ( topicId == 0 )
|
||||
{
|
||||
WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
if (topicId == 0)
|
||||
{
|
||||
WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( strcmp(clientId->cstring, common_topic) == 0 )
|
||||
{
|
||||
theGateway->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Client* client = getClient(clientId);
|
||||
if (strcmp(clientId->cstring, common_topic) == 0)
|
||||
{
|
||||
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Client *client = getClient(clientId);
|
||||
|
||||
if ( _authorize && client == nullptr )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (_authorize && client == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return nullptr; // full of clients
|
||||
}
|
||||
client = createClient(NULL, clientId, aggregate);
|
||||
|
||||
if ( client == nullptr )
|
||||
{
|
||||
/* creat a new client */
|
||||
client = new Client();
|
||||
client->setClientId(*clientId);
|
||||
if ( aggregate )
|
||||
{
|
||||
client->setAggregated();
|
||||
}
|
||||
_mutex.lock();
|
||||
if (client == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
// create Topic & Add it
|
||||
client->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
client->_hasPredefTopic = true;
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ClientList::getClientCount()
|
||||
@@ -462,4 +448,70 @@ bool ClientList::isAuthorized()
|
||||
return _authorize;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Class ClientsPool
|
||||
******************************/
|
||||
|
||||
ClientsPool::ClientsPool()
|
||||
{
|
||||
_clientCnt = 0;
|
||||
_firstClient = nullptr;
|
||||
_endClient = nullptr;
|
||||
}
|
||||
|
||||
ClientsPool::~ClientsPool()
|
||||
{
|
||||
Client* cl = _firstClient;
|
||||
Client* ncl;
|
||||
|
||||
while (cl != nullptr)
|
||||
{
|
||||
ncl = cl->_nextClient;
|
||||
delete cl;
|
||||
cl = ncl;
|
||||
};
|
||||
}
|
||||
|
||||
void ClientsPool::allocate(int maxClients)
|
||||
{
|
||||
Client* cl = nullptr;
|
||||
|
||||
_firstClient = new Client();
|
||||
|
||||
for (int i = 0; i < maxClients; i++)
|
||||
{
|
||||
if ((cl = new Client()) == nullptr)
|
||||
{
|
||||
throw Exception("ClientsPool::Can't allocate max number of clients\n", 0);
|
||||
}
|
||||
cl->_nextClient = _firstClient;
|
||||
_firstClient = cl;
|
||||
_clientCnt++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Client* ClientsPool::getClient(void)
|
||||
{
|
||||
Client *cl = nullptr;
|
||||
|
||||
while (_firstClient != nullptr)
|
||||
{
|
||||
cl = _firstClient;
|
||||
_firstClient = cl->_nextClient;
|
||||
cl->_nextClient = nullptr;
|
||||
_clientCnt--;
|
||||
break;
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
void ClientsPool::setClient(Client* client)
|
||||
{
|
||||
if (client)
|
||||
{
|
||||
client->_nextClient = _firstClient;
|
||||
_firstClient = client;
|
||||
_clientCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,21 +30,41 @@ namespace MQTTSNGW
|
||||
|
||||
class Client;
|
||||
|
||||
/*=====================================
|
||||
Class ClientsPool
|
||||
=====================================*/
|
||||
class ClientsPool
|
||||
{
|
||||
public:
|
||||
ClientsPool();
|
||||
~ClientsPool();
|
||||
void allocate(int maxClients);
|
||||
Client* getClient(void);
|
||||
void setClient(Client* client);
|
||||
|
||||
private:
|
||||
Client* _firstClient;
|
||||
Client* _endClient;
|
||||
int _clientCnt;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
class ClientList
|
||||
{
|
||||
public:
|
||||
ClientList();
|
||||
ClientList(Gateway* gw);
|
||||
~ClientList();
|
||||
|
||||
void initialize(bool aggregate);
|
||||
void setClientList(int type);
|
||||
void setPredefinedTopics(bool aggregate);
|
||||
void erase(Client*&);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
bool unstableLine, bool secure, int type);
|
||||
bool createList(const char* fileName, int type);
|
||||
Client* getClient(SensorNetAddress* addr);
|
||||
Client* getClient(MQTTSNString* clientId);
|
||||
@@ -55,18 +75,18 @@ public:
|
||||
|
||||
private:
|
||||
bool readPredefinedList(const char* fileName, bool _aggregate);
|
||||
Gateway* _gateway {nullptr};
|
||||
Client* createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t toipcId, bool _aggregate);
|
||||
ClientsPool* _clientsPool;
|
||||
Gateway* _gateway;
|
||||
Client* createPredefinedTopic(MQTTSNString* clientId, string topicName,
|
||||
uint16_t toipcId, bool _aggregate);
|
||||
Client* _firstClient;
|
||||
Client* _endClient;
|
||||
Mutex _mutex;
|
||||
uint16_t _clientCnt;
|
||||
bool _authorize {false};
|
||||
uint16_t _maxClients;
|
||||
bool _authorize { false };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||
#include <cstring>
|
||||
|
||||
//#include "MQTTSNGWForwarder.h"
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
@@ -29,242 +27,262 @@ char* currentDateTime(void);
|
||||
=====================================*/
|
||||
ClientRecvTask::ClientRecvTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
setTaskName("ClientRecvTask");
|
||||
}
|
||||
|
||||
ClientRecvTask::~ClientRecvTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize SensorNetwork
|
||||
*/
|
||||
void ClientRecvTask::initialize(int argc, char** argv)
|
||||
{
|
||||
if ( _sensorNetwork->initialize() < 0 )
|
||||
{
|
||||
throw Exception(" Can't open the sensor network.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a packet from clients via sensor netwwork
|
||||
* and generate a event to execute the packet handling procedure
|
||||
* and creats a event to execute the packet handling procedure
|
||||
* of MQTTSNPacketHandlingTask.
|
||||
*/
|
||||
void ClientRecvTask::run()
|
||||
{
|
||||
Event* ev = nullptr;
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
QoSm1Proxy* qosm1Proxy = adpMgr->getQoSm1Proxy();
|
||||
int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE;
|
||||
ClientList* clientList = _gateway->getClientList();
|
||||
EventQue* packetEventQue = _gateway->getPacketEventQue();
|
||||
Event* ev = nullptr;
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
QoSm1Proxy* qosm1Proxy = adpMgr->getQoSm1Proxy();
|
||||
int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE;
|
||||
ClientList* clientList = _gateway->getClientList();
|
||||
EventQue* packetEventQue = _gateway->getPacketEventQue();
|
||||
EventQue* clientsendQue = _gateway->getClientSendQue();
|
||||
|
||||
char buf[128];
|
||||
char buf[128];
|
||||
|
||||
while (true)
|
||||
{
|
||||
Client* client = nullptr;
|
||||
Forwarder* fwd = nullptr;
|
||||
WirelessNodeId nodeId;
|
||||
while (true)
|
||||
{
|
||||
Client* client = nullptr;
|
||||
Forwarder* fwd = nullptr;
|
||||
WirelessNodeId nodeId;
|
||||
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
int packetLen = packet->recv(_sensorNetwork);
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
int packetLen = packet->recv(_sensorNetwork);
|
||||
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("\n%s ClientRecvTask stopped.", currentDateTime());
|
||||
delete packet;
|
||||
return;
|
||||
}
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete packet;
|
||||
return;
|
||||
}
|
||||
|
||||
if (packetLen < 2 )
|
||||
{
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
if (packetLen < 2)
|
||||
{
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO )
|
||||
{
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
if (packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO)
|
||||
{
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( packet->getType() == MQTTSN_SEARCHGW )
|
||||
{
|
||||
/* write log and post Event */
|
||||
log(0, packet, 0);
|
||||
ev = new Event();
|
||||
ev->setBrodcastEvent(packet);
|
||||
packetEventQue->post(ev);
|
||||
continue;
|
||||
}
|
||||
if (packet->getType() == MQTTSN_SEARCHGW)
|
||||
{
|
||||
/* write log and post Event */
|
||||
log(0, packet, 0);
|
||||
ev = new Event();
|
||||
ev->setBrodcastEvent(packet);
|
||||
packetEventQue->post(ev);
|
||||
continue;
|
||||
}
|
||||
|
||||
SensorNetAddress senderAddr = *_gateway->getSensorNetwork()->getSenderAddress();
|
||||
|
||||
SensorNetAddress* senderAddr = _gateway->getSensorNetwork()->getSenderAddress();
|
||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||
{
|
||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(&senderAddr);
|
||||
|
||||
if ( packet->getType() == MQTTSN_ENCAPSULATED )
|
||||
{
|
||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(senderAddr);
|
||||
if (fwd != nullptr)
|
||||
{
|
||||
MQTTSNString fwdName = MQTTSNString_initializer;
|
||||
fwdName.cstring = const_cast<char *>(fwd->getName());
|
||||
log(0, packet, &fwdName);
|
||||
|
||||
if ( fwd != nullptr )
|
||||
{
|
||||
MQTTSNString fwdName = MQTTSNString_initializer;
|
||||
fwdName.cstring = const_cast<char *>( fwd->getName() );
|
||||
log(0, packet, &fwdName);
|
||||
/* get the packet from the encapsulation message */
|
||||
MQTTSNGWEncapsulatedPacket encap;
|
||||
encap.desirialize(packet->getPacketData(), packet->getPacketLength());
|
||||
nodeId.setId(encap.getWirelessNodeId());
|
||||
client = fwd->getClient(&nodeId);
|
||||
packet = encap.getMQTTSNPacket();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the client belonging to QoS-1Proxy ? */
|
||||
|
||||
/* get the packet from the encapsulation message */
|
||||
MQTTSNGWEncapsulatedPacket encap;
|
||||
encap.desirialize(packet->getPacketData(), packet->getPacketLength());
|
||||
nodeId.setId( encap.getWirelessNodeId() );
|
||||
client = fwd->getClient(&nodeId);
|
||||
packet = encap.getMQTTSNPacket();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the client belonging to QoS-1Proxy ? */
|
||||
if (qosm1Proxy->isActive())
|
||||
{
|
||||
const char *clientName = qosm1Proxy->getClientId(&senderAddr);
|
||||
|
||||
if ( qosm1Proxy->isActive() )
|
||||
{
|
||||
const char* clientName = qosm1Proxy->getClientId(senderAddr);
|
||||
if (clientName != nullptr)
|
||||
{
|
||||
client = qosm1Proxy->getClient();
|
||||
|
||||
if ( clientName != nullptr )
|
||||
{
|
||||
client = qosm1Proxy->getClient();
|
||||
if (!packet->isQoSMinusPUBLISH())
|
||||
{
|
||||
log(clientName, packet);
|
||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n",
|
||||
ERRMSG_HEADER, clientName, senderAddr.sprint(buf), ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !packet->isQoSMinusPUBLISH() )
|
||||
{
|
||||
log(clientName, packet);
|
||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n", ERRMSG_HEADER, clientName, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (client == nullptr)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(&senderAddr);
|
||||
}
|
||||
}
|
||||
|
||||
if ( client == nullptr )
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(senderAddr);
|
||||
}
|
||||
}
|
||||
if (client != nullptr)
|
||||
{
|
||||
log(client, packet, 0);
|
||||
|
||||
if ( client != nullptr )
|
||||
{
|
||||
/* write log and post Event */
|
||||
log(client, packet, 0);
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client,packet);
|
||||
packetEventQue->post(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new client */
|
||||
if (packet->getType() == MQTTSN_CONNECT)
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
memset(&data, 0, sizeof(MQTTSNPacket_connectData));
|
||||
if ( !packet->getCONNECT(&data) )
|
||||
{
|
||||
log(0, packet, &data.clientID);
|
||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT)
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
|
||||
client = clientList->getClient(&data.clientID);
|
||||
/* send DISCONNECT to the client, if it is not connected */
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
ev = new Event();
|
||||
ev->setClientSendEvent(client, snPacket);
|
||||
clientsendQue->post(ev);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
packetEventQue->post(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new client */
|
||||
if (packet->getType() == MQTTSN_CONNECT)
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
memset(&data, 0, sizeof(MQTTSNPacket_connectData));
|
||||
if (!packet->getCONNECT(&data))
|
||||
{
|
||||
log(0, packet, &data.clientID);
|
||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( fwd != nullptr )
|
||||
{
|
||||
if ( client == nullptr )
|
||||
{
|
||||
/* create a new client */
|
||||
client = clientList->createClient(0, &data.clientID, clientType);
|
||||
}
|
||||
/* Add to a forwarded client list of forwarder. */
|
||||
client = clientList->getClient(&data.clientID);
|
||||
|
||||
if (fwd != nullptr)
|
||||
{
|
||||
if (client == nullptr)
|
||||
{
|
||||
/* create a new client */
|
||||
client = clientList->createClient(0, &data.clientID, clientType);
|
||||
}
|
||||
/* Add to a forwarded client list of forwarder. */
|
||||
fwd->addClient(client, &nodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( client )
|
||||
}
|
||||
else
|
||||
{
|
||||
if (client)
|
||||
{
|
||||
/* Authentication is not required */
|
||||
if ( _gateway->getGWParams()->clientAuthentication == false)
|
||||
{
|
||||
client->setClientAddress(senderAddr);
|
||||
}
|
||||
if (_gateway->getGWParams()->clientAuthentication == false)
|
||||
{
|
||||
client->setClientAddress(&senderAddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a new client */
|
||||
client = clientList->createClient(senderAddr, &data.clientID, clientType);
|
||||
client = clientList->createClient(&senderAddr, &data.clientID, clientType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log(client, packet, &data.clientID);
|
||||
log(client, packet, &data.clientID);
|
||||
|
||||
if ( client == nullptr )
|
||||
{
|
||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
if (client == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* post Client RecvEvent */
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
packetEventQue->post(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
log(client, packet, 0);
|
||||
if ( packet->getType() == MQTTSN_ENCAPSULATED )
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n", ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf), ERRMSG_FOOTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
}
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* post Client RecvEvent */
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
packetEventQue->post(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
log(client, packet, 0);
|
||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||
{
|
||||
WRITELOG(
|
||||
"%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id)
|
||||
{
|
||||
const char* clientId;
|
||||
char cstr[MAX_CLIENTID_LENGTH + 1];
|
||||
const char* clientId;
|
||||
char cstr[MAX_CLIENTID_LENGTH + 1];
|
||||
|
||||
if ( id )
|
||||
{
|
||||
if ( id->cstring )
|
||||
{
|
||||
strncpy(cstr, id->cstring, strlen(id->cstring) );
|
||||
clientId = cstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((void*)cstr, 0, id->lenstring.len + 1);
|
||||
strncpy(cstr, id->lenstring.data, id->lenstring.len );
|
||||
if (id)
|
||||
{
|
||||
if (id->cstring)
|
||||
{
|
||||
strncpy(cstr, id->cstring, strlen(id->cstring));
|
||||
clientId = cstr;
|
||||
}
|
||||
}
|
||||
else if ( client )
|
||||
{
|
||||
clientId = client->getClientId();
|
||||
}
|
||||
else
|
||||
{
|
||||
clientId = UNKNOWNCL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((void*) cstr, 0, id->lenstring.len + 1);
|
||||
strncpy(cstr, id->lenstring.data, id->lenstring.len);
|
||||
clientId = cstr;
|
||||
}
|
||||
}
|
||||
else if (client)
|
||||
{
|
||||
clientId = client->getClientId();
|
||||
}
|
||||
else
|
||||
{
|
||||
clientId = UNKNOWNCL;
|
||||
}
|
||||
|
||||
log(clientId, packet);
|
||||
log(clientId, packet);
|
||||
}
|
||||
|
||||
void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
@@ -275,11 +293,13 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_SEARCHGW:
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), LEFTARROW, CLIENT, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
|
||||
LEFTARROW, CLIENT, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNECT:
|
||||
case MQTTSN_PINGREQ:
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
|
||||
LEFTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
@@ -292,18 +312,20 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_ENCAPSULATED:
|
||||
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
WRITELOG(FORMAT_W_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
|
||||
@@ -24,24 +24,24 @@ namespace MQTTSNGW
|
||||
class AdapterManager;
|
||||
|
||||
/*=====================================
|
||||
Class ClientRecvTask
|
||||
Class ClientRecvTask
|
||||
=====================================*/
|
||||
class ClientRecvTask:public Thread
|
||||
class ClientRecvTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
public:
|
||||
ClientRecvTask(Gateway*);
|
||||
~ClientRecvTask(void);
|
||||
virtual void initialize(int argc, char** argv);
|
||||
void run(void);
|
||||
ClientRecvTask(Gateway*);
|
||||
~ClientRecvTask(void);
|
||||
virtual void initialize(int argc, char** argv);
|
||||
void run(void);
|
||||
|
||||
private:
|
||||
void log(Client*, MQTTSNPacket*, MQTTSNString* id);
|
||||
void log(const char* clientId, MQTTSNPacket* packet);
|
||||
void log(Client*, MQTTSNPacket*, MQTTSNString* id);
|
||||
void log(const char* clientId, MQTTSNPacket* packet);
|
||||
|
||||
Gateway* _gateway;
|
||||
SensorNetwork* _sensorNetwork;
|
||||
Gateway* _gateway;
|
||||
SensorNetwork* _sensorNetwork;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,106 +28,110 @@ char* currentDateTime(void);
|
||||
=====================================*/
|
||||
ClientSendTask::ClientSendTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
setTaskName("ClientSendTask");
|
||||
}
|
||||
|
||||
ClientSendTask::~ClientSendTask()
|
||||
{
|
||||
// WRITELOG("ClientSendTask is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
void ClientSendTask::run()
|
||||
{
|
||||
Client* client = nullptr;
|
||||
MQTTSNPacket* packet = nullptr;
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
int rc = 0;
|
||||
Client* client = nullptr;
|
||||
MQTTSNPacket* packet = nullptr;
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
int rc = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Event* ev = _gateway->getClientSendQue()->wait();
|
||||
while (true)
|
||||
{
|
||||
Event* ev = _gateway->getClientSendQue()->wait();
|
||||
|
||||
if (ev->getEventType() == EtStop || _gateway->IsStopping() )
|
||||
{
|
||||
WRITELOG("\n%s ClientSendTask stopped.", currentDateTime());
|
||||
delete ev;
|
||||
break;
|
||||
}
|
||||
if (ev->getEventType() == EtStop || _gateway->IsStopping())
|
||||
{
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ev->getEventType() == EtBroadcast)
|
||||
{
|
||||
packet = ev->getMQTTSNPacket();
|
||||
log(client, packet);
|
||||
if (ev->getEventType() == EtBroadcast)
|
||||
{
|
||||
packet = ev->getMQTTSNPacket();
|
||||
log(client, packet);
|
||||
|
||||
if ( packet->broadcast(_sensorNetwork) < 0 )
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't multicast a packet Error=%d%s\n",
|
||||
ERRMSG_HEADER, errno, ERRMSG_FOOTER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->getEventType() == EtClientSend)
|
||||
{
|
||||
client = ev->getClient();
|
||||
packet = ev->getMQTTSNPacket();
|
||||
rc = adpMgr->unicastToClient(client, packet, this);
|
||||
}
|
||||
else if (ev->getEventType() == EtSensornetSend)
|
||||
{
|
||||
packet = ev->getMQTTSNPacket();
|
||||
log(client, packet);
|
||||
rc = packet->unicast(_sensorNetwork, ev->getSensorNetAddress());
|
||||
}
|
||||
if (packet->broadcast(_sensorNetwork) < 0)
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't multicast a packet Error=%d%s\n",
|
||||
ERRMSG_HEADER, errno, ERRMSG_FOOTER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ev->getEventType() == EtClientSend)
|
||||
{
|
||||
client = ev->getClient();
|
||||
packet = ev->getMQTTSNPacket();
|
||||
rc = adpMgr->unicastToClient(client, packet, this);
|
||||
}
|
||||
else if (ev->getEventType() == EtSensornetSend)
|
||||
{
|
||||
packet = ev->getMQTTSNPacket();
|
||||
log(client, packet);
|
||||
rc = packet->unicast(_sensorNetwork, ev->getSensorNetAddress());
|
||||
}
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't send a packet to the client %s. Error=%d%s\n",
|
||||
ERRMSG_HEADER, (client ? (const char*)client->getClientId() : UNKNOWNCL ), errno, ERRMSG_FOOTER);
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
if (rc < 0)
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't send a packet to the client %s. Error=%d%s\n",
|
||||
ERRMSG_HEADER, (client ? (const char*) client->getClientId() : UNKNOWNCL),
|
||||
errno, ERRMSG_FOOTER);
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3 + 1];
|
||||
char msgId[6];
|
||||
const char* clientId = client ? (const char*)client->getClientId() : UNKNOWNCL ;
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3 + 1];
|
||||
char msgId[6];
|
||||
const char* clientId = client ? (const char*) client->getClientId() : UNKNOWNCL;
|
||||
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_ADVERTISE:
|
||||
case MQTTSN_GWINFO:
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, CLIENTS, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNACK:
|
||||
case MQTTSN_DISCONNECT:
|
||||
case MQTTSN_WILLTOPICREQ:
|
||||
case MQTTSN_WILLMSGREQ:
|
||||
case MQTTSN_WILLTOPICRESP:
|
||||
case MQTTSN_WILLMSGRESP:
|
||||
case MQTTSN_PINGRESP:
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_SUBACK:
|
||||
case MQTTSN_UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_ADVERTISE:
|
||||
case MQTTSN_GWINFO:
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW,
|
||||
CLIENTS, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNACK:
|
||||
case MQTTSN_DISCONNECT:
|
||||
case MQTTSN_WILLTOPICREQ:
|
||||
case MQTTSN_WILLMSGREQ:
|
||||
case MQTTSN_WILLTOPICRESP:
|
||||
case MQTTSN_WILLMSGRESP:
|
||||
case MQTTSN_PINGRESP:
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_SUBACK:
|
||||
case MQTTSN_UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,18 @@ class AdapterManager;
|
||||
=====================================*/
|
||||
class ClientSendTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
public:
|
||||
ClientSendTask(Gateway* gateway);
|
||||
~ClientSendTask(void);
|
||||
void run(void);
|
||||
ClientSendTask(Gateway* gateway);
|
||||
~ClientSendTask(void);
|
||||
void run(void);
|
||||
|
||||
private:
|
||||
void log(Client* client, MQTTSNPacket* packet);
|
||||
void log(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
Gateway* _gateway;
|
||||
SensorNetwork* _sensorNetwork;
|
||||
Gateway* _gateway;
|
||||
SensorNetwork* _sensorNetwork;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ using namespace MQTTSNGW;
|
||||
=====================================*/
|
||||
MQTTSNConnectionHandler::MQTTSNConnectionHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTSNConnectionHandler::~MQTTSNConnectionHandler()
|
||||
@@ -41,11 +41,11 @@ MQTTSNConnectionHandler::~MQTTSNConnectionHandler()
|
||||
*/
|
||||
void MQTTSNConnectionHandler::sendADVERTISE()
|
||||
{
|
||||
MQTTSNPacket* adv = new MQTTSNPacket();
|
||||
adv->setADVERTISE(_gateway->getGWParams()->gatewayId, _gateway->getGWParams()->keepAlive);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrodcastEvent(adv); //broadcast
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
MQTTSNPacket* adv = new MQTTSNPacket();
|
||||
adv->setADVERTISE(_gateway->getGWParams()->gatewayId, _gateway->getGWParams()->keepAlive);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrodcastEvent(adv); //broadcast
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -53,14 +53,14 @@ void MQTTSNConnectionHandler::sendADVERTISE()
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
|
||||
{
|
||||
if (packet->getType() == MQTTSN_SEARCHGW)
|
||||
{
|
||||
MQTTSNPacket* gwinfo = new MQTTSNPacket();
|
||||
gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrodcastEvent(gwinfo);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
if (packet->getType() == MQTTSN_SEARCHGW)
|
||||
{
|
||||
MQTTSNPacket* gwinfo = new MQTTSNPacket();
|
||||
gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrodcastEvent(gwinfo);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,89 +68,91 @@ void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
if ( packet->getCONNECT(&data) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
MQTTSNPacket_connectData data;
|
||||
if (packet->getCONNECT(&data) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* return CONNACK when the client is sleeping */
|
||||
if ( client->isSleep() || client->isAwake() )
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
/* return CONNACK when the client is sleeping */
|
||||
if (client->isSleep() || client->isAwake())
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, packet);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
sendStoredPublish(client);
|
||||
return;
|
||||
}
|
||||
|
||||
//* clear ConnectData of Client */
|
||||
Connect* connectData = client->getConnectData();
|
||||
memset(connectData, 0, sizeof(Connect));
|
||||
if ( !client->isAdapter() )
|
||||
{
|
||||
client->disconnected();
|
||||
}
|
||||
//* clear ConnectData of Client */
|
||||
Connect* connectData = client->getConnectData();
|
||||
memset(connectData, 0, sizeof(Connect));
|
||||
if (!client->isAdapter())
|
||||
{
|
||||
client->disconnected();
|
||||
}
|
||||
|
||||
Topics* topics = client->getTopics();
|
||||
Topics* topics = client->getTopics();
|
||||
|
||||
/* CONNECT was not sent yet. prepare Connect data */
|
||||
connectData->header.bits.type = CONNECT;
|
||||
connectData->clientID = client->getClientId();
|
||||
connectData->version = _gateway->getGWParams()->mqttVersion;
|
||||
connectData->keepAliveTimer = data.duration;
|
||||
connectData->flags.bits.will = data.willFlag;
|
||||
/* CONNECT was not sent yet. prepare Connect data */
|
||||
connectData->header.bits.type = CONNECT;
|
||||
connectData->clientID = client->getClientId();
|
||||
connectData->version = _gateway->getGWParams()->mqttVersion;
|
||||
connectData->keepAliveTimer = data.duration;
|
||||
connectData->flags.bits.will = data.willFlag;
|
||||
|
||||
if ((const char*) _gateway->getGWParams()->loginId != nullptr)
|
||||
{
|
||||
connectData->flags.bits.username = 1;
|
||||
}
|
||||
if ((const char*) _gateway->getGWParams()->loginId != nullptr)
|
||||
{
|
||||
connectData->flags.bits.username = 1;
|
||||
}
|
||||
|
||||
if ((const char*) _gateway->getGWParams()->password != 0)
|
||||
{
|
||||
connectData->flags.bits.password = 1;
|
||||
}
|
||||
if ((const char*) _gateway->getGWParams()->password != 0)
|
||||
{
|
||||
connectData->flags.bits.password = 1;
|
||||
}
|
||||
|
||||
client->setSessionStatus(false);
|
||||
if (data.cleansession)
|
||||
{
|
||||
connectData->flags.bits.cleanstart = 1;
|
||||
/* reset the table of msgNo and TopicId pare */
|
||||
client->clearWaitedPubTopicId();
|
||||
client->clearWaitedSubTopicId();
|
||||
client->setSessionStatus(false);
|
||||
if (data.cleansession)
|
||||
{
|
||||
connectData->flags.bits.cleanstart = 1;
|
||||
/* reset the table of msgNo and TopicId pare */
|
||||
client->clearWaitedPubTopicId();
|
||||
client->clearWaitedSubTopicId();
|
||||
|
||||
/* renew the TopicList */
|
||||
if (topics)
|
||||
{
|
||||
topics->eraseNormal();;
|
||||
}
|
||||
client->setSessionStatus(true);
|
||||
}
|
||||
/* renew the TopicList */
|
||||
if (topics)
|
||||
{
|
||||
topics->eraseNormal();
|
||||
;
|
||||
}
|
||||
client->setSessionStatus(true);
|
||||
}
|
||||
|
||||
if (data.willFlag)
|
||||
{
|
||||
/* create & send WILLTOPICREQ message to the client */
|
||||
MQTTSNPacket* reqTopic = new MQTTSNPacket();
|
||||
reqTopic->setWILLTOPICREQ();
|
||||
Event* evwr = new Event();
|
||||
evwr->setClientSendEvent(client, reqTopic);
|
||||
if (data.willFlag)
|
||||
{
|
||||
/* create & send WILLTOPICREQ message to the client */
|
||||
MQTTSNPacket* reqTopic = new MQTTSNPacket();
|
||||
reqTopic->setWILLTOPICREQ();
|
||||
Event* evwr = new Event();
|
||||
evwr->setClientSendEvent(client, reqTopic);
|
||||
|
||||
/* Send WILLTOPICREQ to the client */
|
||||
_gateway->getClientSendQue()->post(evwr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CONNECT message was not qued in.
|
||||
* create CONNECT message & send it to the broker */
|
||||
MQTTGWPacket* mqMsg = new MQTTGWPacket();
|
||||
mqMsg->setCONNECT(client->getConnectData(), (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, mqMsg);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
/* Send WILLTOPICREQ to the client */
|
||||
_gateway->getClientSendQue()->post(evwr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CONNECT message was not qued in.
|
||||
* create CONNECT message & send it to the broker */
|
||||
MQTTGWPacket* mqMsg = new MQTTGWPacket();
|
||||
mqMsg->setCONNECT(client->getConnectData(), (unsigned char*) _gateway->getGWParams()->loginId,
|
||||
(unsigned char*) _gateway->getGWParams()->password);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, mqMsg);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,29 +160,29 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
int willQos;
|
||||
uint8_t willRetain;
|
||||
MQTTSNString willTopic = MQTTSNString_initializer;
|
||||
int willQos;
|
||||
uint8_t willRetain;
|
||||
MQTTSNString willTopic = MQTTSNString_initializer;
|
||||
|
||||
if ( packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
client->setWillTopic(willTopic);
|
||||
Connect* connectData = client->getConnectData();
|
||||
if (packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
client->setWillTopic(willTopic);
|
||||
Connect* connectData = client->getConnectData();
|
||||
|
||||
/* add the connectData for MQTT CONNECT message */
|
||||
connectData->willTopic = client->getWillTopic();
|
||||
connectData->flags.bits.willQoS = willQos;
|
||||
connectData->flags.bits.willRetain = willRetain;
|
||||
/* add the connectData for MQTT CONNECT message */
|
||||
connectData->willTopic = client->getWillTopic();
|
||||
connectData->flags.bits.willQoS = willQos;
|
||||
connectData->flags.bits.willRetain = willRetain;
|
||||
|
||||
/* Send WILLMSGREQ to the client */
|
||||
client->setWaitWillMsgFlg(true);
|
||||
MQTTSNPacket* reqMsg = new MQTTSNPacket();
|
||||
reqMsg->setWILLMSGREQ();
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, reqMsg);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
/* Send WILLMSGREQ to the client */
|
||||
client->setWaitWillMsgFlg(true);
|
||||
MQTTSNPacket* reqMsg = new MQTTSNPacket();
|
||||
reqMsg->setWILLMSGREQ();
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, reqMsg);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -188,35 +190,36 @@ void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* pack
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( !client->isWaitWillMsg() )
|
||||
{
|
||||
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
|
||||
return;
|
||||
}
|
||||
if (!client->isWaitWillMsg())
|
||||
{
|
||||
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MQTTSNString willmsg = MQTTSNString_initializer;
|
||||
Connect* connectData = client->getConnectData();
|
||||
MQTTSNString willmsg = MQTTSNString_initializer;
|
||||
Connect* connectData = client->getConnectData();
|
||||
|
||||
if( client->isConnectSendable() )
|
||||
{
|
||||
/* save WillMsg in the client */
|
||||
if ( packet->getWILLMSG(&willmsg) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
client->setWillMsg(willmsg);
|
||||
if (client->isConnectSendable())
|
||||
{
|
||||
/* save WillMsg in the client */
|
||||
if (packet->getWILLMSG(&willmsg) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
client->setWillMsg(willmsg);
|
||||
|
||||
/* create CONNECT message */
|
||||
MQTTGWPacket* mqttPacket = new MQTTGWPacket();
|
||||
connectData->willMsg = client->getWillMsg();
|
||||
mqttPacket->setCONNECT(connectData, (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password);
|
||||
/* create CONNECT message */
|
||||
MQTTGWPacket* mqttPacket = new MQTTGWPacket();
|
||||
connectData->willMsg = client->getWillMsg();
|
||||
mqttPacket->setCONNECT(connectData, (unsigned char*) _gateway->getGWParams()->loginId,
|
||||
(unsigned char*) _gateway->getGWParams()->password);
|
||||
|
||||
/* Send CONNECT to the broker */
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerSendEvent(client, mqttPacket);
|
||||
client->setWaitWillMsgFlg(false);
|
||||
_gateway->getBrokerSendQue()->post(evt);
|
||||
}
|
||||
/* Send CONNECT to the broker */
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerSendEvent(client, mqttPacket);
|
||||
client->setWaitWillMsgFlg(false);
|
||||
_gateway->getBrokerSendQue()->post(evt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -226,9 +229,9 @@ void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* pac
|
||||
{
|
||||
uint16_t duration = 0;
|
||||
|
||||
if ( packet->getDISCONNECT(&duration) != 0 )
|
||||
if (packet->getDISCONNECT(&duration) != 0)
|
||||
{
|
||||
if ( duration == 0 )
|
||||
if (duration == 0)
|
||||
{
|
||||
MQTTGWPacket* mqMsg = new MQTTGWPacket();
|
||||
mqMsg->setHeader(DISCONNECT);
|
||||
@@ -250,12 +253,12 @@ void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* pac
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
/* send NOT_SUPPORTED responce to the client */
|
||||
MQTTSNPacket* respMsg = new MQTTSNPacket();
|
||||
respMsg->setWILLTOPICRESP(MQTTSN_RC_NOT_SUPPORTED);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, respMsg);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
/* send NOT_SUPPORTED responce to the client */
|
||||
MQTTSNPacket* respMsg = new MQTTSNPacket();
|
||||
respMsg->setWILLTOPICRESP(MQTTSN_RC_NOT_SUPPORTED);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, respMsg);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -263,12 +266,12 @@ void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* p
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
/* send NOT_SUPPORTED responce to the client */
|
||||
MQTTSNPacket* respMsg = new MQTTSNPacket();
|
||||
respMsg->setWILLMSGRESP(MQTTSN_RC_NOT_SUPPORTED);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, respMsg);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
/* send NOT_SUPPORTED responce to the client */
|
||||
MQTTSNPacket* respMsg = new MQTTSNPacket();
|
||||
respMsg->setWILLMSGRESP(MQTTSN_RC_NOT_SUPPORTED);
|
||||
Event* evt = new Event();
|
||||
evt->setClientSendEvent(client, respMsg);
|
||||
_gateway->getClientSendQue()->post(evt);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -276,31 +279,31 @@ void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* pac
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( ( client->isSleep() || client->isAwake() ) && client->getClientSleepPacket() )
|
||||
{
|
||||
sendStoredPublish(client);
|
||||
client->holdPingRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
|
||||
{
|
||||
sendStoredPublish(client);
|
||||
client->holdPingRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* send PINGREQ to the broker */
|
||||
client->resetPingRequest();
|
||||
client->resetPingRequest();
|
||||
MQTTGWPacket* pingreq = new MQTTGWPacket();
|
||||
pingreq->setHeader(PINGREQ);
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerSendEvent(client, pingreq);
|
||||
_gateway->getBrokerSendQue()->post(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNConnectionHandler::sendStoredPublish(Client* client)
|
||||
{
|
||||
MQTTGWPacket* msg = nullptr;
|
||||
|
||||
while ( ( msg = client->getClientSleepPacket() ) != nullptr )
|
||||
while ((msg = client->getClientSleepPacket()) != nullptr)
|
||||
{
|
||||
// ToDo: This version can't re-send PUBLISH when PUBACK is not returned.
|
||||
client->deleteFirstClientSleepPacket(); // pop the que to delete element.
|
||||
client->deleteFirstClientSleepPacket(); // pop the que to delete element.
|
||||
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, msg);
|
||||
|
||||
@@ -25,21 +25,21 @@ namespace MQTTSNGW
|
||||
class MQTTSNConnectionHandler
|
||||
{
|
||||
public:
|
||||
MQTTSNConnectionHandler(Gateway* gateway);
|
||||
~MQTTSNConnectionHandler();
|
||||
void sendADVERTISE(void);
|
||||
void handleSearchgw(MQTTSNPacket* packet);
|
||||
void handleConnect(Client* client, MQTTSNPacket* packet);
|
||||
void handleWilltopic(Client* client, MQTTSNPacket* packet);
|
||||
void handleWillmsg(Client* client, MQTTSNPacket* packet);
|
||||
void handleDisconnect(Client* client, MQTTSNPacket* packet);
|
||||
void handleWilltopicupd(Client* client, MQTTSNPacket* packet);
|
||||
void handleWillmsgupd(Client* client, MQTTSNPacket* packet);
|
||||
void handlePingreq(Client* client, MQTTSNPacket* packet);
|
||||
MQTTSNConnectionHandler(Gateway* gateway);
|
||||
~MQTTSNConnectionHandler();
|
||||
void sendADVERTISE(void);
|
||||
void handleSearchgw(MQTTSNPacket* packet);
|
||||
void handleConnect(Client* client, MQTTSNPacket* packet);
|
||||
void handleWilltopic(Client* client, MQTTSNPacket* packet);
|
||||
void handleWillmsg(Client* client, MQTTSNPacket* packet);
|
||||
void handleDisconnect(Client* client, MQTTSNPacket* packet);
|
||||
void handleWilltopicupd(Client* client, MQTTSNPacket* packet);
|
||||
void handleWillmsgupd(Client* client, MQTTSNPacket* packet);
|
||||
void handlePingreq(Client* client, MQTTSNPacket* packet);
|
||||
private:
|
||||
void sendStoredPublish(Client* client);
|
||||
void sendStoredPublish(Client* client);
|
||||
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -53,21 +53,26 @@ namespace MQTTSNGW
|
||||
/*=================================
|
||||
* Data Type
|
||||
==================================*/
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
|
||||
#ifdef DEBUG
|
||||
//#define DEBUG_MQTTSN // print out log for debug
|
||||
//#define DEBUG_NW // print out SensorNetwork log
|
||||
#ifdef DEBUG_MQTTSN
|
||||
#define DEBUGLOG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUGLOG(...)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWDEFINES_H_ */
|
||||
|
||||
@@ -21,17 +21,15 @@
|
||||
using namespace MQTTSNGW;
|
||||
using namespace std;
|
||||
|
||||
WirelessNodeId::WirelessNodeId()
|
||||
:
|
||||
_len{0},
|
||||
_nodeId{0}
|
||||
WirelessNodeId::WirelessNodeId() :
|
||||
_len { 0 }, _nodeId { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WirelessNodeId::~WirelessNodeId()
|
||||
{
|
||||
if ( _nodeId )
|
||||
if (_nodeId)
|
||||
{
|
||||
free(_nodeId);
|
||||
}
|
||||
@@ -39,12 +37,12 @@ WirelessNodeId::~WirelessNodeId()
|
||||
|
||||
void WirelessNodeId::setId(uint8_t* id, uint8_t len)
|
||||
{
|
||||
if ( _nodeId )
|
||||
{
|
||||
free(_nodeId);
|
||||
}
|
||||
uint8_t* buf = (uint8_t*)malloc(len);
|
||||
if ( buf )
|
||||
if (_nodeId)
|
||||
{
|
||||
free(_nodeId);
|
||||
}
|
||||
uint8_t* buf = (uint8_t*) malloc(len);
|
||||
if (buf)
|
||||
{
|
||||
memcpy(buf, id, len);
|
||||
_len = len;
|
||||
@@ -64,7 +62,7 @@ void WirelessNodeId::setId(WirelessNodeId* id)
|
||||
|
||||
bool WirelessNodeId::operator ==(WirelessNodeId& id)
|
||||
{
|
||||
if ( _len == id._len )
|
||||
if (_len == id._len)
|
||||
{
|
||||
return memcmp(_nodeId, id._nodeId, _len) == 0;
|
||||
}
|
||||
@@ -77,16 +75,14 @@ bool WirelessNodeId::operator ==(WirelessNodeId& id)
|
||||
/*
|
||||
* Class MQTTSNGWEncapsulatedPacket
|
||||
*/
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket()
|
||||
: _mqttsn{0},
|
||||
_ctrl{0}
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() :
|
||||
_mqttsn { 0 }, _ctrl { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet)
|
||||
: _mqttsn{packet},
|
||||
_ctrl{0}
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) :
|
||||
_mqttsn { packet }, _ctrl { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
@@ -109,18 +105,18 @@ int MQTTSNGWEncapsulatedPacket::serialize(uint8_t* buf)
|
||||
buf[0] = _id._len + 3;
|
||||
buf[1] = MQTTSN_ENCAPSULATED;
|
||||
buf[2] = _ctrl;
|
||||
memcpy( buf + 3, _id._nodeId, _id._len);
|
||||
if ( _mqttsn )
|
||||
memcpy(buf + 3, _id._nodeId, _id._len);
|
||||
if (_mqttsn)
|
||||
{
|
||||
len = _mqttsn->getPacketLength();
|
||||
memcpy(buf + buf[0], _mqttsn->getPacketData(), len);
|
||||
}
|
||||
return buf[0] + len;
|
||||
return buf[0] + len;
|
||||
}
|
||||
|
||||
int MQTTSNGWEncapsulatedPacket::desirialize(unsigned char* buf, unsigned short len)
|
||||
{
|
||||
if ( _mqttsn )
|
||||
if (_mqttsn)
|
||||
{
|
||||
delete _mqttsn;
|
||||
_mqttsn = nullptr;
|
||||
|
||||
@@ -60,6 +60,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
|
||||
using namespace std;
|
||||
|
||||
/*=====================================
|
||||
Class ForwarderList
|
||||
Class ForwarderList
|
||||
=====================================*/
|
||||
|
||||
ForwarderList::ForwarderList()
|
||||
@@ -32,10 +32,10 @@ ForwarderList::ForwarderList()
|
||||
|
||||
ForwarderList::~ForwarderList()
|
||||
{
|
||||
if ( _head )
|
||||
if (_head)
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
Forwarder* next = p->_next;
|
||||
delete p;
|
||||
@@ -44,20 +44,18 @@ ForwarderList::~ForwarderList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ForwarderList::initialize(Gateway* gw)
|
||||
{
|
||||
/* Create Fowarders from clients.conf */
|
||||
gw->getClientList()->setClientList(FORWARDER_TYPE);
|
||||
/* Create Fowarders from clients.conf */
|
||||
gw->getClientList()->setClientList(FORWARDER_TYPE);
|
||||
}
|
||||
|
||||
|
||||
Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_sensorNetAddr.isMatch(addr) )
|
||||
if (p->_sensorNetAddr.isMatch(addr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -66,19 +64,19 @@ Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
|
||||
return p;
|
||||
}
|
||||
|
||||
Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
{
|
||||
Forwarder* fdr = new Forwarder(addr, forwarderId);
|
||||
if ( _head == nullptr )
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = fdr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_next == nullptr )
|
||||
if (p->_next == nullptr)
|
||||
{
|
||||
p->_next = fdr;
|
||||
break;
|
||||
@@ -99,10 +97,10 @@ Forwarder::Forwarder()
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class ForwarderList
|
||||
Class ForwarderList
|
||||
=====================================*/
|
||||
|
||||
Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
{
|
||||
_forwarderName = string(forwarderId->cstring);
|
||||
_sensorNetAddr = *addr;
|
||||
@@ -112,10 +110,10 @@ Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
|
||||
Forwarder::~Forwarder(void)
|
||||
{
|
||||
if ( _headClient )
|
||||
if (_headClient)
|
||||
{
|
||||
ForwarderElement* p = _headClient;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
ForwarderElement* next = p->_next;
|
||||
delete p;
|
||||
@@ -136,11 +134,11 @@ void Forwarder::addClient(Client* client, WirelessNodeId* id)
|
||||
|
||||
client->setForwarder(this);
|
||||
|
||||
if ( p != nullptr )
|
||||
if (p != nullptr)
|
||||
{
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_client == client )
|
||||
if (p->_client == client)
|
||||
{
|
||||
client->setForwarder(this);
|
||||
p->setWirelessNodeId(id);
|
||||
@@ -156,7 +154,7 @@ void Forwarder::addClient(Client* client, WirelessNodeId* id)
|
||||
fclient->setClient(client);
|
||||
fclient->setWirelessNodeId(id);
|
||||
|
||||
if ( prev )
|
||||
if (prev)
|
||||
{
|
||||
prev->_next = fclient;
|
||||
}
|
||||
@@ -171,9 +169,9 @@ Client* Forwarder::getClient(WirelessNodeId* id)
|
||||
Client* cl = nullptr;
|
||||
_mutex.lock();
|
||||
ForwarderElement* p = _headClient;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( *(p->_wirelessNodeId) == *id )
|
||||
if (*(p->_wirelessNodeId) == *id)
|
||||
{
|
||||
cl = p->_client;
|
||||
break;
|
||||
@@ -197,9 +195,9 @@ WirelessNodeId* Forwarder::getWirelessNodeId(Client* client)
|
||||
WirelessNodeId* nodeId = nullptr;
|
||||
_mutex.lock();
|
||||
ForwarderElement* p = _headClient;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_client == client )
|
||||
if (p->_client == client)
|
||||
{
|
||||
nodeId = p->_wirelessNodeId;
|
||||
break;
|
||||
@@ -219,11 +217,11 @@ void Forwarder::eraseClient(Client* client)
|
||||
_mutex.lock();
|
||||
ForwarderElement* p = _headClient;
|
||||
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_client == client )
|
||||
if (p->_client == client)
|
||||
{
|
||||
if ( prev )
|
||||
if (prev)
|
||||
{
|
||||
prev->_next = p->_next;
|
||||
}
|
||||
@@ -251,10 +249,8 @@ SensorNetAddress* Forwarder::getSensorNetAddr(void)
|
||||
* Class ForwardedClient
|
||||
*/
|
||||
|
||||
ForwarderElement::ForwarderElement()
|
||||
: _client{0}
|
||||
, _wirelessNodeId{0}
|
||||
, _next{0}
|
||||
ForwarderElement::ForwarderElement() :
|
||||
_client { 0 }, _wirelessNodeId { 0 }, _next { 0 }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -273,7 +269,7 @@ void ForwarderElement::setClient(Client* client)
|
||||
|
||||
void ForwarderElement::setWirelessNodeId(WirelessNodeId* id)
|
||||
{
|
||||
if ( _wirelessNodeId == nullptr )
|
||||
if (_wirelessNodeId == nullptr)
|
||||
{
|
||||
_wirelessNodeId = new WirelessNodeId();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||
#include "SensorNetwork.h"
|
||||
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class Gateway;
|
||||
@@ -30,7 +29,7 @@ class Client;
|
||||
class WirelessNodeId;
|
||||
|
||||
/*=====================================
|
||||
Class ForwarderElement
|
||||
Class ForwarderElement
|
||||
=====================================*/
|
||||
class ForwarderElement
|
||||
{
|
||||
@@ -48,14 +47,14 @@ private:
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
Class Forwarder
|
||||
Class Forwarder
|
||||
=====================================*/
|
||||
class Forwarder
|
||||
{
|
||||
friend class ForwarderList;
|
||||
public:
|
||||
Forwarder(void);
|
||||
Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId);
|
||||
Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId);
|
||||
~Forwarder();
|
||||
|
||||
void initialize(void);
|
||||
@@ -70,13 +69,13 @@ public:
|
||||
private:
|
||||
string _forwarderName;
|
||||
SensorNetAddress _sensorNetAddr;
|
||||
ForwarderElement* _headClient{nullptr};
|
||||
Forwarder* _next {nullptr};
|
||||
ForwarderElement* _headClient { nullptr };
|
||||
Forwarder* _next { nullptr };
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
Class ForwarderList
|
||||
Class ForwarderList
|
||||
=====================================*/
|
||||
class ForwarderList
|
||||
{
|
||||
@@ -86,7 +85,7 @@ public:
|
||||
|
||||
void initialize(Gateway* gw);
|
||||
Forwarder* getForwarder(SensorNetAddress* addr);
|
||||
Forwarder* addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId);
|
||||
Forwarder* addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId);
|
||||
|
||||
private:
|
||||
Forwarder* _head;
|
||||
@@ -94,6 +93,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
Logmonitor::Logmonitor()
|
||||
{
|
||||
theProcess = this;
|
||||
theProcess = this;
|
||||
}
|
||||
|
||||
Logmonitor::~Logmonitor()
|
||||
@@ -32,17 +32,17 @@ Logmonitor::~Logmonitor()
|
||||
|
||||
void Logmonitor::run()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const char* data = getLog();
|
||||
if ( *data == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", data);
|
||||
}
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
const char* data = getLog();
|
||||
if (*data == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace MQTTSNGW
|
||||
class Logmonitor: public Process
|
||||
{
|
||||
public:
|
||||
Logmonitor();
|
||||
~Logmonitor();
|
||||
void run();
|
||||
Logmonitor();
|
||||
~Logmonitor();
|
||||
void run();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,187 +29,181 @@ MessageIdTable::MessageIdTable()
|
||||
|
||||
MessageIdTable::~MessageIdTable()
|
||||
{
|
||||
_mutex.lock();
|
||||
if ( _head != nullptr )
|
||||
{
|
||||
MessageIdElement* p = _tail;
|
||||
while ( p )
|
||||
{
|
||||
MessageIdElement* pPrev = p;
|
||||
delete p;
|
||||
_cnt--;
|
||||
p = pPrev->_prev;
|
||||
}
|
||||
_head = _tail = nullptr;
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex.lock();
|
||||
if (_head != nullptr)
|
||||
{
|
||||
MessageIdElement* p = _tail;
|
||||
while (p)
|
||||
{
|
||||
MessageIdElement* pPrev = p;
|
||||
delete p;
|
||||
_cnt--;
|
||||
p = pPrev->_prev;
|
||||
}
|
||||
_head = _tail = nullptr;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
if ( _cnt > _maxSize )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (_cnt > _maxSize)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MessageIdElement* elm = new MessageIdElement(0, client, clientMsgId);
|
||||
if ( elm == nullptr )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
_mutex.lock();
|
||||
if ( _head == nullptr )
|
||||
{
|
||||
elm->_msgId = aggregater->msgId();
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageIdElement* p = find(client, clientMsgId);
|
||||
if ( p == nullptr )
|
||||
{
|
||||
elm->_msgId = aggregater->msgId();
|
||||
p = _tail;
|
||||
_tail = elm;
|
||||
elm->_prev = p;
|
||||
p->_next = elm;
|
||||
_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete elm;
|
||||
elm = nullptr;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
return elm;
|
||||
MessageIdElement* elm = new MessageIdElement(0, client, clientMsgId);
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
_mutex.lock();
|
||||
if (_head == nullptr)
|
||||
{
|
||||
elm->_msgId = aggregater->msgId();
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageIdElement* p = find(client, clientMsgId);
|
||||
if (p == nullptr)
|
||||
{
|
||||
elm->_msgId = aggregater->msgId();
|
||||
p = _tail;
|
||||
_tail = elm;
|
||||
elm->_prev = p;
|
||||
p->_next = elm;
|
||||
_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete elm;
|
||||
elm = nullptr;
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
return elm;
|
||||
}
|
||||
|
||||
MessageIdElement* MessageIdTable::find(uint16_t msgId)
|
||||
{
|
||||
MessageIdElement* p = _head;
|
||||
while ( p )
|
||||
{
|
||||
if ( p->_msgId == msgId)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return p;
|
||||
MessageIdElement* p = _head;
|
||||
while (p)
|
||||
{
|
||||
if (p->_msgId == msgId)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
MessageIdElement* p = _head;
|
||||
while ( p )
|
||||
{
|
||||
if ( p->_clientMsgId == clientMsgId && p->_client == client)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return p;
|
||||
MessageIdElement* p = _head;
|
||||
while (p)
|
||||
{
|
||||
if (p->_clientMsgId == clientMsgId && p->_client == client)
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
Client* MessageIdTable::getClientMsgId(uint16_t msgId, uint16_t* clientMsgId)
|
||||
{
|
||||
Client* clt = nullptr;
|
||||
*clientMsgId = 0;
|
||||
_mutex.lock();
|
||||
MessageIdElement* p = find(msgId);
|
||||
if ( p != nullptr )
|
||||
{
|
||||
clt = p->_client;
|
||||
*clientMsgId = p->_clientMsgId;
|
||||
clear(p);
|
||||
}
|
||||
_mutex.unlock();
|
||||
return clt;
|
||||
Client* clt = nullptr;
|
||||
*clientMsgId = 0;
|
||||
_mutex.lock();
|
||||
MessageIdElement* p = find(msgId);
|
||||
if (p != nullptr)
|
||||
{
|
||||
clt = p->_client;
|
||||
*clientMsgId = p->_clientMsgId;
|
||||
clear(p);
|
||||
}
|
||||
_mutex.unlock();
|
||||
return clt;
|
||||
}
|
||||
|
||||
void MessageIdTable::erase(uint16_t msgId)
|
||||
{
|
||||
_mutex.lock();
|
||||
MessageIdElement* p = find(msgId);
|
||||
clear(p);
|
||||
_mutex.unlock();
|
||||
_mutex.lock();
|
||||
MessageIdElement* p = find(msgId);
|
||||
clear(p);
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void MessageIdTable::clear(MessageIdElement* elm)
|
||||
{
|
||||
if ( elm == nullptr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( elm->_prev == nullptr )
|
||||
{
|
||||
_head = elm->_next;
|
||||
if ( _head == nullptr)
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
_head->_prev = nullptr;
|
||||
}
|
||||
delete elm;
|
||||
_cnt--;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
elm->_prev->_next = elm->_next;
|
||||
if ( elm->_next == nullptr )
|
||||
{
|
||||
_tail = elm->_prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
elm->_next->_prev = elm->_prev;
|
||||
}
|
||||
delete elm;
|
||||
_cnt--;
|
||||
return;
|
||||
}
|
||||
if (elm->_prev == nullptr)
|
||||
{
|
||||
_head = elm->_next;
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
_head->_prev = nullptr;
|
||||
}
|
||||
delete elm;
|
||||
_cnt--;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
elm->_prev->_next = elm->_next;
|
||||
if (elm->_next == nullptr)
|
||||
{
|
||||
_tail = elm->_prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
elm->_next->_prev = elm->_prev;
|
||||
}
|
||||
delete elm;
|
||||
_cnt--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
uint16_t msgId = 0;
|
||||
MessageIdElement* p = find(client, clientMsgId);
|
||||
if ( p != nullptr )
|
||||
{
|
||||
msgId = p->_msgId;
|
||||
}
|
||||
return msgId;
|
||||
uint16_t msgId = 0;
|
||||
MessageIdElement* p = find(client, clientMsgId);
|
||||
if (p != nullptr)
|
||||
{
|
||||
msgId = p->_msgId;
|
||||
}
|
||||
return msgId;
|
||||
}
|
||||
|
||||
/*===============================
|
||||
* Class MessageIdElement
|
||||
===============================*/
|
||||
MessageIdElement::MessageIdElement(void)
|
||||
: _msgId{0}
|
||||
, _clientMsgId {0}
|
||||
, _client {nullptr}
|
||||
, _next {nullptr}
|
||||
, _prev {nullptr}
|
||||
MessageIdElement::MessageIdElement(void) :
|
||||
_msgId { 0 }, _clientMsgId { 0 }, _client { nullptr }, _next { nullptr }, _prev { nullptr }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId)
|
||||
: MessageIdElement()
|
||||
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId) :
|
||||
MessageIdElement()
|
||||
{
|
||||
_msgId = msgId;
|
||||
_client = client;
|
||||
_clientMsgId = clientMsgId;
|
||||
_msgId = msgId;
|
||||
_client = client;
|
||||
_clientMsgId = clientMsgId;
|
||||
}
|
||||
|
||||
MessageIdElement::~MessageIdElement(void)
|
||||
|
||||
@@ -34,22 +34,23 @@ class Aggregater;
|
||||
class MessageIdTable
|
||||
{
|
||||
public:
|
||||
MessageIdTable();
|
||||
~MessageIdTable();
|
||||
MessageIdTable();
|
||||
~MessageIdTable();
|
||||
|
||||
MessageIdElement* add(Aggregater* aggregater, Client* client, uint16_t clientMsgId);
|
||||
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
|
||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||
void erase(uint16_t msgId);
|
||||
void clear(MessageIdElement* elm);
|
||||
MessageIdElement* add(Aggregater* aggregater, Client* client,
|
||||
uint16_t clientMsgId);
|
||||
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
|
||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||
void erase(uint16_t msgId);
|
||||
void clear(MessageIdElement* elm);
|
||||
private:
|
||||
MessageIdElement* find(uint16_t msgId);
|
||||
MessageIdElement* find(Client* client, uint16_t clientMsgId);
|
||||
MessageIdElement* _head {nullptr};
|
||||
MessageIdElement* _tail {nullptr};
|
||||
int _cnt {0};
|
||||
int _maxSize {MAX_MESSAGEID_TABLE_SIZE};
|
||||
Mutex _mutex;
|
||||
MessageIdElement* find(uint16_t msgId);
|
||||
MessageIdElement* find(Client* client, uint16_t clientMsgId);
|
||||
MessageIdElement* _head { nullptr };
|
||||
MessageIdElement* _tail{ nullptr };
|
||||
int _cnt { 0 };
|
||||
int _maxSize { MAX_MESSAGEID_TABLE_SIZE };
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
@@ -67,12 +68,11 @@ public:
|
||||
private:
|
||||
uint16_t _msgId;
|
||||
uint16_t _clientMsgId;
|
||||
Client* _client;
|
||||
Client* _client;
|
||||
MessageIdElement* _next;
|
||||
MessageIdElement* _prev;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */
|
||||
|
||||
@@ -29,286 +29,278 @@ void writeInt(unsigned char** pptr, int msgId);
|
||||
|
||||
MQTTSNPacket::MQTTSNPacket(void)
|
||||
{
|
||||
_buf = nullptr;
|
||||
_bufLen = 0;
|
||||
_buf = nullptr;
|
||||
_bufLen = 0;
|
||||
}
|
||||
|
||||
MQTTSNPacket::MQTTSNPacket(MQTTSNPacket& packet)
|
||||
{
|
||||
_buf = (unsigned char*)malloc(packet._bufLen);
|
||||
if (_buf)
|
||||
{
|
||||
_bufLen = packet._bufLen;
|
||||
memcpy(_buf, packet._buf, _bufLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
_buf = nullptr;
|
||||
_bufLen = 0;
|
||||
}
|
||||
_buf = (unsigned char*) malloc(packet._bufLen);
|
||||
if (_buf)
|
||||
{
|
||||
_bufLen = packet._bufLen;
|
||||
memcpy(_buf, packet._buf, _bufLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
_buf = nullptr;
|
||||
_bufLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MQTTSNPacket::~MQTTSNPacket()
|
||||
{
|
||||
if (_buf)
|
||||
{
|
||||
free(_buf);
|
||||
}
|
||||
if (_buf)
|
||||
{
|
||||
free(_buf);
|
||||
}
|
||||
}
|
||||
|
||||
int MQTTSNPacket::unicast(SensorNetwork* network, SensorNetAddress* sendTo)
|
||||
{
|
||||
return network->unicast(_buf, _bufLen, sendTo);
|
||||
return network->unicast(_buf, _bufLen, sendTo);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::broadcast(SensorNetwork* network)
|
||||
{
|
||||
return network->broadcast(_buf, _bufLen);
|
||||
return network->broadcast(_buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::serialize(uint8_t* buf)
|
||||
{
|
||||
buf = _buf;
|
||||
return _bufLen;
|
||||
buf = _buf;
|
||||
return _bufLen;
|
||||
}
|
||||
|
||||
int MQTTSNPacket::desirialize(unsigned char* buf, unsigned short len)
|
||||
{
|
||||
if ( _buf )
|
||||
{
|
||||
free(_buf);
|
||||
}
|
||||
if (_buf)
|
||||
{
|
||||
free(_buf);
|
||||
}
|
||||
|
||||
_buf = (unsigned char*)calloc(len, sizeof(unsigned char));
|
||||
if ( _buf )
|
||||
{
|
||||
memcpy(_buf, buf, len);
|
||||
_bufLen = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bufLen = 0;
|
||||
}
|
||||
return _bufLen;
|
||||
_buf = (unsigned char*) calloc(len, sizeof(unsigned char));
|
||||
if (_buf)
|
||||
{
|
||||
memcpy(_buf, buf, len);
|
||||
_bufLen = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bufLen = 0;
|
||||
}
|
||||
return _bufLen;
|
||||
}
|
||||
|
||||
int MQTTSNPacket::recv(SensorNetwork* network)
|
||||
{
|
||||
uint8_t buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int len = network->read((uint8_t*) buf, MQTTSNGW_MAX_PACKET_SIZE);
|
||||
if (len > 1)
|
||||
{
|
||||
len = desirialize(buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
}
|
||||
return len;
|
||||
uint8_t buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int len = network->read((uint8_t*) buf, MQTTSNGW_MAX_PACKET_SIZE);
|
||||
if (len > 1)
|
||||
{
|
||||
len = desirialize(buf, len);
|
||||
}
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getType(void)
|
||||
{
|
||||
if ( _bufLen == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return _buf[p];
|
||||
if (_bufLen == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return _buf[p];
|
||||
}
|
||||
|
||||
bool MQTTSNPacket::isQoSMinusPUBLISH(void)
|
||||
{
|
||||
if ( _bufLen == 0 )
|
||||
if (_bufLen == 0)
|
||||
{
|
||||
return false;;
|
||||
}
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return ( (_buf[p] == MQTTSN_PUBLISH) && ((_buf[p + 1] & 0x60 ) == 0x60 ));
|
||||
return ((_buf[p] == MQTTSN_PUBLISH) && ((_buf[p + 1] & 0x60) == 0x60));
|
||||
}
|
||||
|
||||
unsigned char* MQTTSNPacket::getPacketData(void)
|
||||
{
|
||||
return _buf;
|
||||
return _buf;
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPacketLength(void)
|
||||
{
|
||||
return _bufLen;
|
||||
return _bufLen;
|
||||
}
|
||||
|
||||
const char* MQTTSNPacket::getName()
|
||||
{
|
||||
return MQTTSNPacket_name(getType());
|
||||
return MQTTSNPacket_name(getType());
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setADVERTISE(uint8_t gatewayid, uint16_t duration)
|
||||
{
|
||||
unsigned char buf[5];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid,
|
||||
(unsigned short) duration);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[5];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, (unsigned short) duration);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setGWINFO(uint8_t gatewayId)
|
||||
{
|
||||
unsigned char buf[3];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_gwinfo(buf, buflen, (unsigned char) gatewayId, 0, 0);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[3];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_gwinfo(buf, buflen, (unsigned char) gatewayId, 0, 0);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setConnect(void)
|
||||
{
|
||||
unsigned char buf[40];
|
||||
int buflen = sizeof(buf);
|
||||
MQTTSNPacket_connectData data;
|
||||
data.clientID.cstring = (char*)"client01";
|
||||
int len = MQTTSNSerialize_connect(buf, buflen, &data);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[40];
|
||||
int buflen = sizeof(buf);
|
||||
MQTTSNPacket_connectData data;
|
||||
data.clientID.cstring = (char*) "client01";
|
||||
int len = MQTTSNSerialize_connect(buf, buflen, &data);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
bool MQTTSNPacket::isAccepted(void)
|
||||
{
|
||||
return ( getType() == MQTTSN_CONNACK) && (_buf[2] == MQTTSN_RC_ACCEPTED);
|
||||
return (getType() == MQTTSN_CONNACK) && (_buf[2] == MQTTSN_RC_ACCEPTED);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setCONNACK(uint8_t returnCode)
|
||||
{
|
||||
unsigned char buf[3];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_connack(buf, buflen, (int) returnCode);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[3];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_connack(buf, buflen, (int) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setWILLTOPICREQ(void)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willtopicreq(buf, buflen);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[2];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willtopicreq(buf, buflen);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setWILLMSGREQ(void)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willmsgreq(buf, buflen);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[2];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willmsgreq(buf, buflen);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* topicName)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
topicName);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, topicName);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode)
|
||||
{
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic,
|
||||
uint8_t* payload, uint16_t payloadlen)
|
||||
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic, uint8_t* payload,
|
||||
uint16_t payloadlen)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained,
|
||||
(unsigned short) msgId, topic, (unsigned char*) payload, (int) payloadlen);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained, (unsigned short) msgId,
|
||||
topic, (unsigned char*) payload, (int) payloadlen);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode)
|
||||
{
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBREC(uint16_t msgId)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pubrec(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pubrec(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBREL(uint16_t msgId)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pubrel(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pubrel(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBCOMP(uint16_t msgId)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pubcomp(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pubcomp(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode)
|
||||
{
|
||||
unsigned char buf[8];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId,
|
||||
(unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[8];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setUNSUBACK(uint16_t msgId)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_unsuback(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_unsuback(buf, buflen, (unsigned short) msgId);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPINGRESP(void)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pingresp(buf, buflen);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[32];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pingresp(buf, buflen);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setDISCONNECT(uint16_t duration)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_disconnect(buf, buflen, (int) duration);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[4];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_disconnect(buf, buflen, (int) duration);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setWILLTOPICRESP(uint8_t returnCode)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willtopicresp(buf, buflen, (int) returnCode);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willtopicresp(buf, buflen, (int) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setWILLMSGRESP(uint8_t returnCode)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willmsgresp(buf, buflen, (int) returnCode);
|
||||
return desirialize(buf, len);
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_willmsgresp(buf, buflen, (int) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setCONNECT(MQTTSNPacket_connectData* options)
|
||||
@@ -323,262 +315,262 @@ int MQTTSNPacket::setPINGREQ(MQTTSNString* clientId)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pingreq( buf, buflen, *clientId);
|
||||
int len = MQTTSNSerialize_pingreq(buf, buflen, *clientId);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getSERCHGW(uint8_t* radius)
|
||||
{
|
||||
return MQTTSNDeserialize_searchgw((unsigned char*) radius, (unsigned char*) _buf, _bufLen);
|
||||
return MQTTSNDeserialize_searchgw((unsigned char*) radius, (unsigned char*) _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getCONNECT(MQTTSNPacket_connectData* data)
|
||||
{
|
||||
return MQTTSNDeserialize_connect(data, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_connect(data, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getCONNACK(uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNSerialize_connack(_buf, _bufLen, (int) *returnCode);
|
||||
return MQTTSNSerialize_connack(_buf, _bufLen, (int) *returnCode);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic)
|
||||
{
|
||||
return MQTTSNDeserialize_willtopic((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_willtopic((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
|
||||
{
|
||||
return MQTTSNDeserialize_willmsg(willmsg, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_willmsg(willmsg, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName)
|
||||
{
|
||||
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName,
|
||||
_buf, _bufLen);
|
||||
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
|
||||
_bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId, MQTTSN_topicid* topic,
|
||||
uint8_t** payload, int* payloadlen)
|
||||
uint8_t** payload, int* payloadlen)
|
||||
{
|
||||
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId,
|
||||
topic, (unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId, topic,
|
||||
(unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode,
|
||||
_buf, _bufLen);
|
||||
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
|
||||
_bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getACK(uint16_t* msgId)
|
||||
{
|
||||
unsigned char type;
|
||||
return MQTTSNDeserialize_ack(&type, (unsigned short*) msgId, _buf, _bufLen);
|
||||
unsigned char type;
|
||||
return MQTTSNDeserialize_ack(&type, (unsigned short*) msgId, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter)
|
||||
{
|
||||
return MQTTSNDeserialize_subscribe((unsigned char*) dup, qos, (unsigned short*) msgId, topicFilter, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_subscribe((unsigned char*) dup, qos, (unsigned short*) msgId, topicFilter, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter)
|
||||
{
|
||||
return MQTTSNDeserialize_unsubscribe((unsigned short*) msgId, topicFilter, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_unsubscribe((unsigned short*) msgId, topicFilter, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPINGREQ(void)
|
||||
{
|
||||
if (getType() == MQTTSN_PINGRESP && _bufLen > 2 )
|
||||
{
|
||||
return _bufLen - 2;
|
||||
}
|
||||
return 0;
|
||||
if (getType() == MQTTSN_PINGRESP && _bufLen > 2)
|
||||
{
|
||||
return _bufLen - 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getDISCONNECT(uint16_t* duration)
|
||||
{
|
||||
int dur = 0;
|
||||
int rc = MQTTSNDeserialize_disconnect(&dur, _buf, _bufLen);
|
||||
*duration = (uint16_t)dur;
|
||||
return rc;
|
||||
int dur = 0;
|
||||
int rc = MQTTSNDeserialize_disconnect(&dur, _buf, _bufLen);
|
||||
*duration = (uint16_t) dur;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic)
|
||||
{
|
||||
return MQTTSNDeserialize_willtopicupd((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_willtopicupd((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getWILLMSGUPD(MQTTSNString* willMsg)
|
||||
{
|
||||
return MQTTSNDeserialize_willmsgupd(willMsg, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_willmsgupd(willMsg, _buf, _bufLen);
|
||||
}
|
||||
|
||||
char* MQTTSNPacket::print(char* pbuf)
|
||||
{
|
||||
char* ptr = pbuf;
|
||||
char** pptr = &pbuf;
|
||||
int size = _bufLen > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : _bufLen;
|
||||
char* ptr = pbuf;
|
||||
char** pptr = &pbuf;
|
||||
int size = _bufLen > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : _bufLen;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(*pptr, " %02X", *(_buf + i));
|
||||
*pptr += 3;
|
||||
}
|
||||
**pptr = 0;
|
||||
return ptr;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(*pptr, " %02X", *(_buf + i));
|
||||
*pptr += 3;
|
||||
}
|
||||
**pptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char* MQTTSNPacket::getMsgId(char* pbuf)
|
||||
{
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
|
||||
switch ( getType() )
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
if ( _buf[p + 1] & 0x80 )
|
||||
{
|
||||
sprintf(pbuf, "+%02X%02X", _buf[p + 4], _buf[p + 5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pbuf, " %02X%02X", _buf[p + 4], _buf[p + 5]);
|
||||
}
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
sprintf(pbuf, " %02X%02X", _buf[4], _buf[5]);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
sprintf(pbuf, " %02X%02X", _buf[2], _buf[3]);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
sprintf(pbuf, " %02X%02X", _buf[p + 2], _buf[p + 3]);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
sprintf(pbuf, " %02X%02X", _buf[5], _buf[6]);
|
||||
break;
|
||||
default:
|
||||
sprintf(pbuf, " ");
|
||||
break;
|
||||
}
|
||||
if ( strcmp(pbuf, " 0000") == 0 )
|
||||
{
|
||||
sprintf(pbuf, " ");
|
||||
}
|
||||
return pbuf;
|
||||
switch (getType())
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
if (_buf[p + 1] & 0x80)
|
||||
{
|
||||
sprintf(pbuf, "+%02X%02X", _buf[p + 4], _buf[p + 5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(pbuf, " %02X%02X", _buf[p + 4], _buf[p + 5]);
|
||||
}
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
sprintf(pbuf, " %02X%02X", _buf[4], _buf[5]);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
sprintf(pbuf, " %02X%02X", _buf[2], _buf[3]);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
sprintf(pbuf, " %02X%02X", _buf[p + 2], _buf[p + 3]);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
sprintf(pbuf, " %02X%02X", _buf[5], _buf[6]);
|
||||
break;
|
||||
default:
|
||||
sprintf(pbuf, " ");
|
||||
break;
|
||||
}
|
||||
if (strcmp(pbuf, " 0000") == 0)
|
||||
{
|
||||
sprintf(pbuf, " ");
|
||||
}
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getMsgId(void)
|
||||
{
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
int msgId = 0;
|
||||
char* ptr = 0;
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
int msgId = 0;
|
||||
char* ptr = 0;
|
||||
|
||||
switch ( getType() )
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
ptr = (char*)_buf + p + 4;
|
||||
msgId = readInt((char**)&ptr);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
ptr = (char*)_buf + 4;
|
||||
msgId = readInt((char**)&ptr);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
ptr = (char*)_buf + 2;
|
||||
msgId = readInt((char**)&ptr);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
ptr = (char*)_buf + p + 2;
|
||||
msgId = readInt((char**)&ptr);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
ptr = (char*)_buf + 5;
|
||||
msgId = readInt((char**)&ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msgId;
|
||||
switch (getType())
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
ptr = (char*) _buf + p + 4;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
ptr = (char*) _buf + 4;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
ptr = (char*) _buf + 2;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
ptr = (char*) _buf + p + 2;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
ptr = (char*) _buf + 5;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msgId;
|
||||
}
|
||||
|
||||
void MQTTSNPacket::setMsgId(uint16_t msgId)
|
||||
{
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
//unsigned char* ptr = 0;
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
//unsigned char* ptr = 0;
|
||||
|
||||
switch ( getType() )
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
_buf[p + 4] = (unsigned char)(msgId / 256);
|
||||
_buf[p + 5] = (unsigned char)(msgId % 256);
|
||||
//ptr = _buf + p + 4;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
_buf[4] = (unsigned char)(msgId / 256);
|
||||
_buf[5] = (unsigned char)(msgId % 256);
|
||||
//ptr = _buf + 4;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
_buf[2] = (unsigned char)(msgId / 256);
|
||||
_buf[3] = (unsigned char)(msgId % 256);
|
||||
//ptr = _buf + 2;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
_buf[p + 2] = (unsigned char)(msgId / 256);
|
||||
_buf[p + 3] = (unsigned char)(msgId % 256);
|
||||
//ptr = _buf + p + 2;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
_buf[5] = (unsigned char)(msgId / 256);
|
||||
_buf[6] = (unsigned char)(msgId % 256);
|
||||
//ptr = _buf + 5;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (getType())
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
_buf[p + 4] = (unsigned char) (msgId / 256);
|
||||
_buf[p + 5] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + p + 4;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
_buf[4] = (unsigned char) (msgId / 256);
|
||||
_buf[5] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + 4;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
_buf[2] = (unsigned char) (msgId / 256);
|
||||
_buf[3] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + 2;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
_buf[p + 2] = (unsigned char) (msgId / 256);
|
||||
_buf[p + 3] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + p + 2;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
_buf[5] = (unsigned char) (msgId / 256);
|
||||
_buf[6] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + 5;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool MQTTSNPacket::isDuplicate(void)
|
||||
{
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return ( _buf[p + 1] & 0x80 );
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return (_buf[p + 1] & 0x80);
|
||||
}
|
||||
|
||||
@@ -22,76 +22,82 @@
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class SensorNetwork;
|
||||
|
||||
class MQTTSNPacket
|
||||
{
|
||||
public:
|
||||
MQTTSNPacket(void);
|
||||
MQTTSNPacket(MQTTSNPacket &packet);
|
||||
~MQTTSNPacket(void);
|
||||
int unicast(SensorNetwork* network, SensorNetAddress* sendTo);
|
||||
int broadcast(SensorNetwork* network);
|
||||
int recv(SensorNetwork* network);
|
||||
int serialize(uint8_t* buf);
|
||||
int desirialize(unsigned char* buf, unsigned short len);
|
||||
int getType(void);
|
||||
unsigned char* getPacketData(void);
|
||||
int getPacketLength(void);
|
||||
const char* getName();
|
||||
MQTTSNPacket(void);
|
||||
MQTTSNPacket(MQTTSNPacket &packet);
|
||||
~MQTTSNPacket(void);
|
||||
int unicast(SensorNetwork* network, SensorNetAddress* sendTo);
|
||||
int broadcast(SensorNetwork* network);
|
||||
int recv(SensorNetwork* network);
|
||||
int serialize(uint8_t* buf);
|
||||
int desirialize(unsigned char* buf, unsigned short len);
|
||||
int getType(void);
|
||||
unsigned char* getPacketData(void);
|
||||
int getPacketLength(void);
|
||||
const char* getName();
|
||||
|
||||
int setConnect(void); // Debug
|
||||
int setADVERTISE(uint8_t gatewayid, uint16_t duration);
|
||||
int setGWINFO(uint8_t gatewayId);
|
||||
int setCONNACK(uint8_t returnCode);
|
||||
int setWILLTOPICREQ(void);
|
||||
int setWILLMSGREQ(void);
|
||||
int setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* TopicName);
|
||||
int setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId,
|
||||
MQTTSN_topicid topic, uint8_t* payload, uint16_t payloadlen);
|
||||
int setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setPUBREC(uint16_t msgId);
|
||||
int setPUBREL(uint16_t msgId);
|
||||
int setPUBCOMP(uint16_t msgId);
|
||||
int setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setUNSUBACK(uint16_t msgId);
|
||||
int setPINGRESP(void);
|
||||
int setDISCONNECT(uint16_t duration);
|
||||
int setWILLTOPICRESP(uint8_t returnCode);
|
||||
int setWILLMSGRESP(uint8_t returnCode);
|
||||
int setConnect(void); // Debug
|
||||
int setADVERTISE(uint8_t gatewayid, uint16_t duration);
|
||||
int setGWINFO(uint8_t gatewayId);
|
||||
int setCONNACK(uint8_t returnCode);
|
||||
int setWILLTOPICREQ(void);
|
||||
int setWILLMSGREQ(void);
|
||||
int setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* TopicName);
|
||||
int setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId,
|
||||
MQTTSN_topicid topic, uint8_t* payload, uint16_t payloadlen);
|
||||
int setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setPUBREC(uint16_t msgId);
|
||||
int setPUBREL(uint16_t msgId);
|
||||
int setPUBCOMP(uint16_t msgId);
|
||||
int setSUBACK(int qos, uint16_t topicId, uint16_t msgId,
|
||||
uint8_t returnCode);
|
||||
int setUNSUBACK(uint16_t msgId);
|
||||
int setPINGRESP(void);
|
||||
int setDISCONNECT(uint16_t duration);
|
||||
int setWILLTOPICRESP(uint8_t returnCode);
|
||||
int setWILLMSGRESP(uint8_t returnCode);
|
||||
|
||||
int setCONNECT(MQTTSNPacket_connectData* options);
|
||||
int setPINGREQ(MQTTSNString* clientId);
|
||||
int setCONNECT(MQTTSNPacket_connectData* options);
|
||||
int setPINGREQ(MQTTSNString* clientId);
|
||||
|
||||
int getSERCHGW(uint8_t* radius);
|
||||
int getCONNECT(MQTTSNPacket_connectData* option);
|
||||
int getCONNACK(uint8_t* returnCode);
|
||||
int getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
||||
int getWILLMSG(MQTTSNString* willmsg);
|
||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName);
|
||||
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
|
||||
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
|
||||
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getACK(uint16_t* msgId);
|
||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getPINGREQ(void);
|
||||
int getDISCONNECT(uint16_t* duration);
|
||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
||||
int getWILLMSGUPD(MQTTSNString* willMsg);
|
||||
int getSERCHGW(uint8_t* radius);
|
||||
int getCONNECT(MQTTSNPacket_connectData* option);
|
||||
int getCONNACK(uint8_t* returnCode);
|
||||
int getWILLTOPIC(int* willQoS, uint8_t* willRetain,
|
||||
MQTTSNString* willTopic);
|
||||
int getWILLMSG(MQTTSNString* willmsg);
|
||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId,
|
||||
MQTTSNString* topicName);
|
||||
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
|
||||
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
|
||||
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getACK(uint16_t* msgId);
|
||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId,
|
||||
MQTTSN_topicid* topicFilter);
|
||||
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getPINGREQ(void);
|
||||
int getDISCONNECT(uint16_t* duration);
|
||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain,
|
||||
MQTTSNString* willTopic);
|
||||
int getWILLMSGUPD(MQTTSNString* willMsg);
|
||||
|
||||
bool isAccepted(void);
|
||||
bool isDuplicate(void);
|
||||
bool isQoSMinusPUBLISH(void);
|
||||
char* getMsgId(char* buf);
|
||||
int getMsgId(void);
|
||||
void setMsgId(uint16_t msgId);
|
||||
char* print(char* buf);
|
||||
bool isAccepted(void);
|
||||
bool isDuplicate(void);
|
||||
bool isQoSMinusPUBLISH(void);
|
||||
char* getMsgId(char* buf);
|
||||
int getMsgId(void);
|
||||
void setMsgId(uint16_t msgId);
|
||||
char* print(char* buf);
|
||||
|
||||
private:
|
||||
unsigned char* _buf; // Ptr to a packet data
|
||||
int _bufLen; // length of the packet data
|
||||
unsigned char* _buf; // Ptr to a packet data
|
||||
int _bufLen; // length of the packet data
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -38,22 +38,24 @@ using namespace MQTTSNGW;
|
||||
|
||||
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
|
||||
char* currentDateTime(void);
|
||||
|
||||
/*=====================================
|
||||
Class PacketHandleTask
|
||||
=====================================*/
|
||||
|
||||
PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_mqttConnection = new MQTTGWConnectionHandler(_gateway);
|
||||
_mqttPublish = new MQTTGWPublishHandler(_gateway);
|
||||
_mqttSubscribe = new MQTTGWSubscribeHandler(_gateway);
|
||||
_mqttsnConnection = new MQTTSNConnectionHandler(_gateway);
|
||||
_mqttsnPublish = new MQTTSNPublishHandler(_gateway);
|
||||
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*) this);
|
||||
_mqttConnection = new MQTTGWConnectionHandler(_gateway);
|
||||
_mqttPublish = new MQTTGWPublishHandler(_gateway);
|
||||
_mqttSubscribe = new MQTTGWSubscribeHandler(_gateway);
|
||||
_mqttsnConnection = new MQTTSNConnectionHandler(_gateway);
|
||||
_mqttsnPublish = new MQTTSNPublishHandler(_gateway);
|
||||
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
|
||||
|
||||
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
|
||||
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
|
||||
setTaskName("PacketHandleTask");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,315 +63,309 @@ PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
||||
*/
|
||||
PacketHandleTask::~PacketHandleTask()
|
||||
{
|
||||
if ( _mqttConnection )
|
||||
{
|
||||
delete _mqttConnection;
|
||||
}
|
||||
if ( _mqttPublish )
|
||||
{
|
||||
delete _mqttPublish;
|
||||
}
|
||||
if ( _mqttSubscribe )
|
||||
{
|
||||
delete _mqttSubscribe;
|
||||
}
|
||||
if ( _mqttsnConnection )
|
||||
{
|
||||
delete _mqttsnConnection;
|
||||
}
|
||||
if ( _mqttsnPublish )
|
||||
{
|
||||
delete _mqttsnPublish;
|
||||
}
|
||||
if ( _mqttsnSubscribe )
|
||||
{
|
||||
delete _mqttsnSubscribe;
|
||||
}
|
||||
if (_mqttConnection)
|
||||
{
|
||||
delete _mqttConnection;
|
||||
}
|
||||
if (_mqttPublish)
|
||||
{
|
||||
delete _mqttPublish;
|
||||
}
|
||||
if (_mqttSubscribe)
|
||||
{
|
||||
delete _mqttSubscribe;
|
||||
}
|
||||
if (_mqttsnConnection)
|
||||
{
|
||||
delete _mqttsnConnection;
|
||||
}
|
||||
if (_mqttsnPublish)
|
||||
{
|
||||
delete _mqttsnPublish;
|
||||
}
|
||||
if (_mqttsnSubscribe)
|
||||
{
|
||||
delete _mqttsnSubscribe;
|
||||
}
|
||||
|
||||
if ( _mqttsnAggrConnection )
|
||||
{
|
||||
delete _mqttsnAggrConnection;
|
||||
}
|
||||
if (_mqttsnAggrConnection)
|
||||
{
|
||||
delete _mqttsnAggrConnection;
|
||||
}
|
||||
}
|
||||
|
||||
void PacketHandleTask::run()
|
||||
{
|
||||
Event* ev = nullptr;
|
||||
EventQue* eventQue = _gateway->getPacketEventQue();
|
||||
Event* ev = nullptr;
|
||||
EventQue* eventQue = _gateway->getPacketEventQue();
|
||||
AdapterManager* adpMgr = _gateway->getAdapterManager();
|
||||
|
||||
Client* client = nullptr;
|
||||
MQTTSNPacket* snPacket = nullptr;
|
||||
MQTTGWPacket* brPacket = nullptr;
|
||||
char msgId[6];
|
||||
memset(msgId, 0, 6);
|
||||
Client* client = nullptr;
|
||||
MQTTSNPacket* snPacket = nullptr;
|
||||
MQTTGWPacket* brPacket = nullptr;
|
||||
char msgId[6];
|
||||
memset(msgId, 0, 6);
|
||||
|
||||
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
|
||||
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* wait Event */
|
||||
ev = eventQue->timedwait(EVENT_QUE_TIME_OUT);
|
||||
while (true)
|
||||
{
|
||||
/* wait Event */
|
||||
ev = eventQue->timedwait(EVENT_QUE_TIME_OUT);
|
||||
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("\n%s PacketHandleTask stopped.", currentDateTime());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev->getEventType() == EtTimeout)
|
||||
{
|
||||
/*------ Check Keep Alive Timer & send Advertise ------*/
|
||||
if (_advertiseTimer.isTimeup())
|
||||
{
|
||||
_mqttsnConnection->sendADVERTISE();
|
||||
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
|
||||
}
|
||||
if (ev->getEventType() == EtTimeout)
|
||||
{
|
||||
/*------ Check Keep Alive Timer & send Advertise ------*/
|
||||
if (_advertiseTimer.isTimeup())
|
||||
{
|
||||
_mqttsnConnection->sendADVERTISE();
|
||||
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
|
||||
}
|
||||
|
||||
/*------ Check Adapters Connect or PINGREQ ------*/
|
||||
adpMgr->checkConnection();
|
||||
}
|
||||
/*------ Check Adapters Connect or PINGREQ ------*/
|
||||
adpMgr->checkConnection();
|
||||
}
|
||||
|
||||
/*------ Handle SEARCHGW Message ---------*/
|
||||
else if (ev->getEventType() == EtBroadcast)
|
||||
{
|
||||
snPacket = ev->getMQTTSNPacket();
|
||||
_mqttsnConnection->handleSearchgw(snPacket);
|
||||
}
|
||||
/*------ Handle SEARCHGW Message ---------*/
|
||||
else if (ev->getEventType() == EtBroadcast)
|
||||
{
|
||||
snPacket = ev->getMQTTSNPacket();
|
||||
_mqttsnConnection->handleSearchgw(snPacket);
|
||||
}
|
||||
|
||||
/*------ Handle Messages form Clients ---------*/
|
||||
else if (ev->getEventType() == EtClientRecv)
|
||||
{
|
||||
client = ev->getClient();
|
||||
snPacket = ev->getMQTTSNPacket();
|
||||
/*------ Handle Messages form Clients ---------*/
|
||||
else if (ev->getEventType() == EtClientRecv)
|
||||
{
|
||||
client = ev->getClient();
|
||||
snPacket = ev->getMQTTSNPacket();
|
||||
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the client.\n", snPacket->getName(), snPacket->getMsgId(msgId));
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the client.\n", snPacket->getName(), snPacket->getMsgId(msgId));
|
||||
|
||||
if ( adpMgr->isAggregatedClient(client) )
|
||||
{
|
||||
aggregatePacketHandler(client, snPacket); // client is converted to Aggregater by BrokerSendTask
|
||||
}
|
||||
else
|
||||
{
|
||||
transparentPacketHandler(client, snPacket);
|
||||
}
|
||||
if (adpMgr->isAggregatedClient(client))
|
||||
{
|
||||
aggregatePacketHandler(client, snPacket); // client is converted to Aggregater by BrokerSendTask
|
||||
}
|
||||
else
|
||||
{
|
||||
transparentPacketHandler(client, snPacket);
|
||||
}
|
||||
|
||||
/* Reset the Timer for PINGREQ. */
|
||||
client->updateStatus(snPacket);
|
||||
}
|
||||
/*------ Handle Messages form Broker ---------*/
|
||||
else if (ev->getEventType() == EtBrokerRecv)
|
||||
{
|
||||
client = ev->getClient();
|
||||
brPacket = ev->getMQTTGWPacket();
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
|
||||
|
||||
/* Reset the Timer for PINGREQ. */
|
||||
client->updateStatus(snPacket);
|
||||
}
|
||||
/*------ Handle Messages form Broker ---------*/
|
||||
else if ( ev->getEventType() == EtBrokerRecv )
|
||||
{
|
||||
client = ev->getClient();
|
||||
brPacket = ev->getMQTTGWPacket();
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
|
||||
|
||||
|
||||
if ( client->isAggregater() )
|
||||
{
|
||||
aggregatePacketHandler(client, brPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
transparentPacketHandler(client, brPacket);
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
if (client->isAggregater())
|
||||
{
|
||||
aggregatePacketHandler(client, brPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
transparentPacketHandler(client, brPacket);
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_CONNECT:
|
||||
_mqttsnAggrConnection->handleConnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPIC:
|
||||
_mqttsnConnection->handleWilltopic(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSG:
|
||||
_mqttsnAggrConnection->handleWillmsg(client, packet);
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
_mqttsnAggrConnection->handleDisconnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
_mqttsnConnection->handleWilltopicupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSGUPD:
|
||||
_mqttsnConnection->handleWillmsgupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_PINGREQ:
|
||||
_mqttsnAggrConnection->handlePingreq(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBLISH:
|
||||
_mqttsnPublish->handleAggregatePublish(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBACK);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREC);
|
||||
break;
|
||||
case MQTTSN_PUBREL:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREL);
|
||||
break;
|
||||
case MQTTSN_PUBCOMP:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBCOMP);
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
_mqttsnPublish->handleRegister(client, packet);
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
_mqttsnPublish->handleRegAck(client, packet);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
_mqttsnSubscribe->handleAggregateSubscribe(client, packet);
|
||||
break;
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
_mqttsnSubscribe->handleAggregateUnsubscribe(client, packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_CONNECT:
|
||||
_mqttsnAggrConnection->handleConnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPIC:
|
||||
_mqttsnConnection->handleWilltopic(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSG:
|
||||
_mqttsnAggrConnection->handleWillmsg(client, packet);
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
_mqttsnAggrConnection->handleDisconnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
_mqttsnConnection->handleWilltopicupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSGUPD:
|
||||
_mqttsnConnection->handleWillmsgupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_PINGREQ:
|
||||
_mqttsnAggrConnection->handlePingreq(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBLISH:
|
||||
_mqttsnPublish->handleAggregatePublish(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBACK);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREC);
|
||||
break;
|
||||
case MQTTSN_PUBREL:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREL);
|
||||
break;
|
||||
case MQTTSN_PUBCOMP:
|
||||
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBCOMP);
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
_mqttsnPublish->handleRegister(client, packet);
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
_mqttsnPublish->handleRegAck(client, packet);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
_mqttsnSubscribe->handleAggregateSubscribe(client, packet);
|
||||
break;
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
_mqttsnSubscribe->handleAggregateUnsubscribe(client, packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNACK:
|
||||
_mqttConnection->handleConnack(client, packet);
|
||||
break;
|
||||
case PINGRESP:
|
||||
_mqttConnection->handlePingresp(client, packet);
|
||||
break;
|
||||
case PUBLISH:
|
||||
_mqttPublish->handleAggregatePublish(client, packet);
|
||||
break;
|
||||
case PUBACK:
|
||||
_mqttPublish->handleAggregatePuback(client, packet);
|
||||
break;
|
||||
case PUBREC:
|
||||
_mqttPublish->handleAggregateAck(client, packet, PUBREC);
|
||||
break;
|
||||
case PUBREL:
|
||||
_mqttPublish->handleAggregatePubrel(client, packet);
|
||||
break;
|
||||
case PUBCOMP:
|
||||
_mqttPublish->handleAggregateAck(client, packet, PUBCOMP);
|
||||
break;
|
||||
case SUBACK:
|
||||
_mqttSubscribe->handleAggregateSuback(client, packet);
|
||||
break;
|
||||
case UNSUBACK:
|
||||
_mqttSubscribe->handleAggregateUnsuback(client, packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNACK:
|
||||
_mqttConnection->handleConnack(client, packet);
|
||||
break;
|
||||
case PINGRESP:
|
||||
_mqttConnection->handlePingresp(client, packet);
|
||||
break;
|
||||
case PUBLISH:
|
||||
_mqttPublish->handleAggregatePublish(client, packet);
|
||||
break;
|
||||
case PUBACK:
|
||||
_mqttPublish->handleAggregatePuback(client, packet);
|
||||
break;
|
||||
case PUBREC:
|
||||
_mqttPublish->handleAggregateAck(client, packet, PUBREC);
|
||||
break;
|
||||
case PUBREL:
|
||||
_mqttPublish->handleAggregatePubrel(client, packet);
|
||||
break;
|
||||
case PUBCOMP:
|
||||
_mqttPublish->handleAggregateAck(client, packet, PUBCOMP);
|
||||
break;
|
||||
case SUBACK:
|
||||
_mqttSubscribe->handleAggregateSuback(client, packet);
|
||||
break;
|
||||
case UNSUBACK:
|
||||
_mqttSubscribe->handleAggregateUnsuback(client, packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_CONNECT:
|
||||
_mqttsnConnection->handleConnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPIC:
|
||||
_mqttsnConnection->handleWilltopic(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSG:
|
||||
_mqttsnConnection->handleWillmsg(client, packet);
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
_mqttsnConnection->handleDisconnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
_mqttsnConnection->handleWilltopicupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSGUPD:
|
||||
_mqttsnConnection->handleWillmsgupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_PINGREQ:
|
||||
_mqttsnConnection->handlePingreq(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBLISH:
|
||||
_mqttsnPublish->handlePublish(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
_mqttsnPublish->handlePuback(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
_mqttsnPublish->handleAck(client, packet, PUBREC);
|
||||
break;
|
||||
case MQTTSN_PUBREL:
|
||||
_mqttsnPublish->handleAck(client, packet, PUBREL);
|
||||
break;
|
||||
case MQTTSN_PUBCOMP:
|
||||
_mqttsnPublish->handleAck(client, packet, PUBCOMP);
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
_mqttsnPublish->handleRegister(client, packet);
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
_mqttsnPublish->handleRegAck(client, packet);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
_mqttsnSubscribe->handleSubscribe(client, packet);
|
||||
break;
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
_mqttsnSubscribe->handleUnsubscribe(client, packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_CONNECT:
|
||||
_mqttsnConnection->handleConnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPIC:
|
||||
_mqttsnConnection->handleWilltopic(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSG:
|
||||
_mqttsnConnection->handleWillmsg(client, packet);
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
_mqttsnConnection->handleDisconnect(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
_mqttsnConnection->handleWilltopicupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_WILLMSGUPD:
|
||||
_mqttsnConnection->handleWillmsgupd(client, packet);
|
||||
break;
|
||||
case MQTTSN_PINGREQ:
|
||||
_mqttsnConnection->handlePingreq(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBLISH:
|
||||
_mqttsnPublish->handlePublish(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
_mqttsnPublish->handlePuback(client, packet);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
_mqttsnPublish->handleAck(client, packet, PUBREC);
|
||||
break;
|
||||
case MQTTSN_PUBREL:
|
||||
_mqttsnPublish->handleAck(client, packet, PUBREL);
|
||||
break;
|
||||
case MQTTSN_PUBCOMP:
|
||||
_mqttsnPublish->handleAck(client, packet, PUBCOMP);
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
_mqttsnPublish->handleRegister(client, packet);
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
_mqttsnPublish->handleRegAck(client, packet);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
_mqttsnSubscribe->handleSubscribe(client, packet);
|
||||
break;
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
_mqttsnSubscribe->handleUnsubscribe(client, packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNACK:
|
||||
_mqttConnection->handleConnack(client, packet);
|
||||
break;
|
||||
case PINGRESP:
|
||||
_mqttConnection->handlePingresp(client, packet);
|
||||
break;
|
||||
case PUBLISH:
|
||||
_mqttPublish->handlePublish(client, packet);
|
||||
break;
|
||||
case PUBACK:
|
||||
_mqttPublish->handlePuback(client, packet);
|
||||
break;
|
||||
case PUBREC:
|
||||
_mqttPublish->handleAck(client, packet, PUBREC);
|
||||
break;
|
||||
case PUBREL:
|
||||
_mqttPublish->handleAck(client, packet, PUBREL);
|
||||
break;
|
||||
case PUBCOMP:
|
||||
_mqttPublish->handleAck(client, packet, PUBCOMP);
|
||||
break;
|
||||
case SUBACK:
|
||||
_mqttSubscribe->handleSuback(client, packet);
|
||||
break;
|
||||
case UNSUBACK:
|
||||
_mqttSubscribe->handleUnsuback(client, packet);
|
||||
break;
|
||||
case DISCONNECT:
|
||||
client->disconnected(); // Just change Client's status to "Disconnected"
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNACK:
|
||||
_mqttConnection->handleConnack(client, packet);
|
||||
break;
|
||||
case PINGRESP:
|
||||
_mqttConnection->handlePingresp(client, packet);
|
||||
break;
|
||||
case PUBLISH:
|
||||
_mqttPublish->handlePublish(client, packet);
|
||||
break;
|
||||
case PUBACK:
|
||||
_mqttPublish->handlePuback(client, packet);
|
||||
break;
|
||||
case PUBREC:
|
||||
_mqttPublish->handleAck(client, packet, PUBREC);
|
||||
break;
|
||||
case PUBREL:
|
||||
_mqttPublish->handleAck(client, packet, PUBREL);
|
||||
break;
|
||||
case PUBCOMP:
|
||||
_mqttPublish->handleAck(client, packet, PUBCOMP);
|
||||
break;
|
||||
case SUBACK:
|
||||
_mqttSubscribe->handleSuback(client, packet);
|
||||
break;
|
||||
case UNSUBACK:
|
||||
_mqttSubscribe->handleUnsuback(client, packet);
|
||||
break;
|
||||
case DISCONNECT:
|
||||
client->disconnected(); // Just change Client's status to "Disconnected"
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,40 +40,39 @@ class MQTTSNAggregateConnectionHandler;
|
||||
class Thread;
|
||||
class Timer;
|
||||
/*=====================================
|
||||
Class PacketHandleTask
|
||||
Class PacketHandleTask
|
||||
=====================================*/
|
||||
class PacketHandleTask : public Thread
|
||||
class PacketHandleTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend class MQTTGWAggregatePublishHandler;
|
||||
friend class MQTTGWAggregateSubscribeHandler;
|
||||
friend class MQTTSNAggregateConnectionHandler;
|
||||
friend class MQTTSNAggregatePublishHandler;
|
||||
friend class MQTTSNAggregateSubscribeHandler;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend class MQTTGWAggregatePublishHandler;
|
||||
friend class MQTTGWAggregateSubscribeHandler;
|
||||
friend class MQTTSNAggregateConnectionHandler;
|
||||
friend class MQTTSNAggregatePublishHandler;
|
||||
friend class MQTTSNAggregateSubscribeHandler;
|
||||
public:
|
||||
PacketHandleTask(Gateway* gateway);
|
||||
~PacketHandleTask();
|
||||
void run();
|
||||
PacketHandleTask(Gateway* gateway);
|
||||
~PacketHandleTask();
|
||||
void run();
|
||||
private:
|
||||
void aggregatePacketHandler(Client*client, MQTTSNPacket* packet);
|
||||
void aggregatePacketHandler(Client*client, MQTTGWPacket* packet);
|
||||
void transparentPacketHandler(Client*client, MQTTSNPacket* packet);
|
||||
void transparentPacketHandler(Client*client, MQTTGWPacket* packet);
|
||||
void aggregatePacketHandler(Client*client, MQTTSNPacket* packet);
|
||||
void aggregatePacketHandler(Client*client, MQTTGWPacket* packet);
|
||||
void transparentPacketHandler(Client*client, MQTTSNPacket* packet);
|
||||
void transparentPacketHandler(Client*client, MQTTGWPacket* packet);
|
||||
|
||||
Gateway* _gateway {nullptr};
|
||||
Timer _advertiseTimer;
|
||||
Timer _sendUnixTimer;
|
||||
MQTTGWConnectionHandler* _mqttConnection {nullptr};
|
||||
MQTTGWPublishHandler* _mqttPublish {nullptr};
|
||||
MQTTGWSubscribeHandler* _mqttSubscribe {nullptr};
|
||||
MQTTSNConnectionHandler* _mqttsnConnection {nullptr};
|
||||
MQTTSNPublishHandler* _mqttsnPublish {nullptr};
|
||||
MQTTSNSubscribeHandler* _mqttsnSubscribe {nullptr};
|
||||
|
||||
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection {nullptr};
|
||||
Gateway* _gateway
|
||||
{ nullptr };
|
||||
Timer _advertiseTimer;
|
||||
Timer _sendUnixTimer;
|
||||
MQTTGWConnectionHandler* _mqttConnection { nullptr };
|
||||
MQTTGWPublishHandler* _mqttPublish { nullptr };
|
||||
MQTTGWSubscribeHandler* _mqttSubscribe { nullptr };
|
||||
MQTTSNConnectionHandler* _mqttsnConnection { nullptr };
|
||||
MQTTSNPublishHandler* _mqttsnPublish { nullptr };
|
||||
MQTTSNSubscribeHandler* _mqttsnSubscribe { nullptr };
|
||||
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection { nullptr };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGWPACKETHANDLETASK_H_ */
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <Timer.h>
|
||||
@@ -44,7 +44,7 @@ volatile int theSignaled = 0;
|
||||
|
||||
static void signalHandler(int sig)
|
||||
{
|
||||
theSignaled = sig;
|
||||
theSignaled = sig;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -52,23 +52,25 @@ static void signalHandler(int sig)
|
||||
====================================*/
|
||||
Process::Process()
|
||||
{
|
||||
_argc = 0;
|
||||
_argv = 0;
|
||||
_configDir = CONFIG_DIRECTORY;
|
||||
_configFile = CONFIG_FILE;
|
||||
_log = 0;
|
||||
_argc = 0;
|
||||
_argv = 0;
|
||||
_configDir = CONFIG_DIRECTORY;
|
||||
_configFile = CONFIG_FILE;
|
||||
_log = 0;
|
||||
_rbsem = NULL;
|
||||
_rb = NULL;
|
||||
}
|
||||
|
||||
Process::~Process()
|
||||
{
|
||||
if (_rb )
|
||||
{
|
||||
delete _rb;
|
||||
}
|
||||
if ( _rbsem )
|
||||
{
|
||||
delete _rbsem;
|
||||
}
|
||||
if (_rb)
|
||||
{
|
||||
delete _rb;
|
||||
}
|
||||
if (_rbsem)
|
||||
{
|
||||
delete _rbsem;
|
||||
}
|
||||
}
|
||||
|
||||
void Process::run()
|
||||
@@ -78,168 +80,185 @@ void Process::run()
|
||||
|
||||
void Process::initialize(int argc, char** argv)
|
||||
{
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
_argc = argc;
|
||||
_argv = argv;
|
||||
signal(SIGINT, signalHandler);
|
||||
signal(SIGTERM, signalHandler);
|
||||
signal(SIGHUP, signalHandler);
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
_argc = argc;
|
||||
_argv = argv;
|
||||
signal(SIGINT, signalHandler);
|
||||
signal(SIGTERM, signalHandler);
|
||||
signal(SIGHUP, signalHandler);
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(_argc, _argv, "f:")) != -1)
|
||||
{
|
||||
if ( opt == 'f' )
|
||||
{
|
||||
string config = string(optarg);
|
||||
size_t pos = 0;
|
||||
if ( (pos = config.find_last_of("/")) == string::npos )
|
||||
{
|
||||
_configFile = optarg;
|
||||
}
|
||||
else
|
||||
{
|
||||
_configFile = config.substr(pos + 1, config.size() - pos - 1);;
|
||||
_configDir = config.substr(0, pos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
_rbsem = new NamedSemaphore(MQTTSNGW_RB_SEMAPHOR_NAME, 0);
|
||||
_rb = new RingBuffer(_configDir.c_str());
|
||||
int opt;
|
||||
while ((opt = getopt(_argc, _argv, "f:")) != -1)
|
||||
{
|
||||
if (opt == 'f')
|
||||
{
|
||||
string config = string(optarg);
|
||||
size_t pos = 0;
|
||||
if ((pos = config.find_last_of("/")) == string::npos)
|
||||
{
|
||||
_configFile = optarg;
|
||||
}
|
||||
else
|
||||
{
|
||||
_configFile = config.substr(pos + 1, config.size() - pos - 1);
|
||||
_configDir = config.substr(0, pos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
_rbsem = new NamedSemaphore(MQTTSNGW_RB_SEMAPHOR_NAME, 0);
|
||||
_rb = new RingBuffer(_configDir.c_str());
|
||||
|
||||
if (getParam("ShearedMemory", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_log = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_log = 0;
|
||||
}
|
||||
}
|
||||
if (getParam("ShearedMemory", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_log = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_log = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Process::putLog(const char* format, ...)
|
||||
{
|
||||
_mt.lock();
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
vsprintf(_rbdata, format, arg);
|
||||
va_end(arg);
|
||||
if (strlen(_rbdata))
|
||||
{
|
||||
if ( _log > 0 )
|
||||
{
|
||||
_rb->put(_rbdata);
|
||||
_rbsem->post();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", _rbdata);
|
||||
}
|
||||
}
|
||||
_mt.unlock();
|
||||
_mt.lock();
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
vsprintf(_rbdata, format, arg);
|
||||
va_end(arg);
|
||||
if (strlen(_rbdata))
|
||||
{
|
||||
if (_log > 0)
|
||||
{
|
||||
_rb->put(_rbdata);
|
||||
_rbsem->post();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", _rbdata);
|
||||
}
|
||||
}
|
||||
_mt.unlock();
|
||||
}
|
||||
|
||||
int Process::getArgc()
|
||||
{
|
||||
return _argc;
|
||||
return _argc;
|
||||
}
|
||||
|
||||
char** Process::getArgv()
|
||||
{
|
||||
return _argv;
|
||||
return _argv;
|
||||
}
|
||||
|
||||
int Process::getParam(const char* parameter, char* value)
|
||||
{
|
||||
char str[MQTTSNGW_PARAM_MAX];
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
FILE *fp;
|
||||
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;
|
||||
string configPath = _configDir + _configFile;
|
||||
int i = 0, j = 0;
|
||||
string configPath = _configDir + _configFile;
|
||||
|
||||
if ((fp = fopen(configPath.c_str(), "r")) == NULL)
|
||||
{
|
||||
throw Exception("No config file:[" + configPath + "]\n");
|
||||
}
|
||||
if ((fp = fopen(configPath.c_str(), "r")) == NULL)
|
||||
{
|
||||
throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (!strncmp(str, parameter, strlen(parameter)))
|
||||
{
|
||||
while (str[i++] != '=')
|
||||
{
|
||||
;
|
||||
}
|
||||
while (str[i] != '\n')
|
||||
{
|
||||
param[j++] = str[i++];
|
||||
}
|
||||
param[j] = '\0';
|
||||
int paramlen = strlen(parameter);
|
||||
|
||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||
;
|
||||
param[i + 1] = '\0';
|
||||
for (i = 0; isspace(param[i]); i++)
|
||||
;
|
||||
if (i > 0)
|
||||
{
|
||||
j = 0;
|
||||
while (param[i])
|
||||
param[j++] = param[i++];
|
||||
param[j] = '\0';
|
||||
}
|
||||
strcpy(value, param);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return -2;
|
||||
while (true)
|
||||
{
|
||||
int pos = 0;
|
||||
int len = 0;
|
||||
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (str[0] == '#' || str[0] == '\n')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
len = strlen(str);
|
||||
for (pos = 0; i < len; pos++)
|
||||
{
|
||||
if (str[pos] == '=')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == paramlen)
|
||||
{
|
||||
if (strncmp(str, parameter, paramlen) == 0)
|
||||
{
|
||||
strcpy(param, str + pos + 1);
|
||||
param[len - pos - 2] = '\0';
|
||||
|
||||
|
||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||
;
|
||||
param[i + 1] = '\0';
|
||||
for (i = 0; isspace(param[i]); i++)
|
||||
;
|
||||
if (i > 0)
|
||||
{
|
||||
j = 0;
|
||||
while (param[i])
|
||||
param[j++] = param[i++];
|
||||
param[j] = '\0';
|
||||
}
|
||||
strcpy(value, param);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
|
||||
const char* Process::getLog()
|
||||
{
|
||||
int len = 0;
|
||||
_mt.lock();
|
||||
while ((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0)
|
||||
{
|
||||
_rbsem->timedwait(1000);
|
||||
if ( checkSignal() == SIGINT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(_rbdata + len) = 0;
|
||||
_mt.unlock();
|
||||
return _rbdata;
|
||||
int len = 0;
|
||||
_mt.lock();
|
||||
while ((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0)
|
||||
{
|
||||
_rbsem->timedwait(1000);
|
||||
if (checkSignal() == SIGINT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(_rbdata + len) = 0;
|
||||
_mt.unlock();
|
||||
return _rbdata;
|
||||
}
|
||||
|
||||
void Process::resetRingBuffer()
|
||||
{
|
||||
_rb->reset();
|
||||
_rb->reset();
|
||||
}
|
||||
|
||||
int Process::checkSignal(void)
|
||||
{
|
||||
return theSignaled;
|
||||
return theSignaled;
|
||||
}
|
||||
|
||||
const string* Process::getConfigDirName(void)
|
||||
{
|
||||
return &_configDir;
|
||||
return &_configDir;
|
||||
}
|
||||
|
||||
const string* Process::getConfigFileName(void)
|
||||
{
|
||||
return &_configFile;
|
||||
return &_configFile;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -247,130 +266,110 @@ const string* Process::getConfigFileName(void)
|
||||
====================================*/
|
||||
MultiTaskProcess::MultiTaskProcess()
|
||||
{
|
||||
theMultiTaskProcess = this;
|
||||
_threadCount = 0;
|
||||
_stopCount = 0;
|
||||
theMultiTaskProcess = this;
|
||||
_threadCount = 0;
|
||||
_stopCount = 0;
|
||||
}
|
||||
|
||||
MultiTaskProcess::~MultiTaskProcess()
|
||||
{
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threadList[i]->stop();
|
||||
}
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threadList[i]->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskProcess::initialize(int argc, char** argv)
|
||||
{
|
||||
Process::initialize(argc, argv);
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threadList[i]->initialize(argc, argv);
|
||||
}
|
||||
Process::initialize(argc, argv);
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threadList[i]->initialize(argc, argv);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MultiTaskProcess::run(void)
|
||||
{
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threadList[i]->start();
|
||||
}
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threadList[i]->start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
if (theProcess->checkSignal() == SIGINT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
catch(Exception* ex)
|
||||
{
|
||||
ex->writeMessage();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
if (theProcess->checkSignal() == SIGINT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskProcess::waitStop(void)
|
||||
{
|
||||
while (_stopCount < _threadCount)
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
while (_stopCount < _threadCount)
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskProcess::threadStopped(void)
|
||||
{
|
||||
_mutex.lock();
|
||||
_stopCount++;
|
||||
_mutex.unlock();
|
||||
_mutex.lock();
|
||||
_stopCount++;
|
||||
_mutex.unlock();
|
||||
|
||||
}
|
||||
|
||||
void MultiTaskProcess::abort(void)
|
||||
{
|
||||
signalHandler(SIGINT);
|
||||
}
|
||||
|
||||
void MultiTaskProcess::attach(Thread* thread)
|
||||
{
|
||||
_mutex.lock();
|
||||
if (_threadCount < MQTTSNGW_MAX_TASK)
|
||||
{
|
||||
_threadList[_threadCount] = thread;
|
||||
_threadCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mutex.unlock();
|
||||
throw Exception("Full of Threads");
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex.lock();
|
||||
if (_threadCount < MQTTSNGW_MAX_TASK)
|
||||
{
|
||||
_threadList[_threadCount] = thread;
|
||||
_threadCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mutex.unlock();
|
||||
throw Exception("The maximum number of threads has been exceeded.", -1);
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
int MultiTaskProcess::getParam(const char* parameter, char* value)
|
||||
{
|
||||
_mutex.lock();
|
||||
int rc = Process::getParam(parameter, value);
|
||||
_mutex.unlock();
|
||||
if (rc == -1)
|
||||
{
|
||||
throw Exception("No config file.");
|
||||
}
|
||||
return rc;
|
||||
_mutex.lock();
|
||||
int rc = Process::getParam(parameter, value);
|
||||
_mutex.unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class Exception
|
||||
======================================*/
|
||||
Exception::Exception(const string& message)
|
||||
Exception::Exception(const char* message, const int errNo)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = 0;
|
||||
_fileName = 0;
|
||||
_functionName = 0;
|
||||
_line = 0;
|
||||
_message = message;
|
||||
_errNo = errNo;
|
||||
_fileName = nullptr;
|
||||
_functionName = nullptr;
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
Exception::Exception(const int exNo, const string& message)
|
||||
Exception::Exception(const char* message, const int errNo, const char* file, const char* function, const int line)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = exNo;
|
||||
_fileName = nullptr;
|
||||
_functionName = nullptr;
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
Exception::Exception(const int exNo, const string& message, const char* file,
|
||||
const char* function, const int line)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = exNo;
|
||||
_fileName = file;
|
||||
_functionName = function;
|
||||
_line = line;
|
||||
_message = message;
|
||||
_errNo = errNo;
|
||||
_fileName = getFileName(file);
|
||||
;
|
||||
_functionName = function;
|
||||
_line = line;
|
||||
}
|
||||
|
||||
Exception::~Exception() throw ()
|
||||
@@ -380,38 +379,67 @@ Exception::~Exception() throw ()
|
||||
|
||||
const char* Exception::what() const throw ()
|
||||
{
|
||||
return _message.c_str();
|
||||
return _message;
|
||||
}
|
||||
|
||||
const char* Exception::getFileName()
|
||||
{
|
||||
return _fileName;
|
||||
return _fileName;
|
||||
}
|
||||
|
||||
const char* Exception::getFunctionName()
|
||||
{
|
||||
return _functionName;
|
||||
return _functionName;
|
||||
}
|
||||
|
||||
const int Exception::getLineNo()
|
||||
{
|
||||
return _line;
|
||||
return _line;
|
||||
}
|
||||
|
||||
const int Exception::getExceptionNo()
|
||||
const int Exception::getErrNo()
|
||||
{
|
||||
return _exNo;
|
||||
return _errNo;
|
||||
}
|
||||
|
||||
void Exception::writeMessage()
|
||||
{
|
||||
if (getExceptionNo() == 0 )
|
||||
{
|
||||
WRITELOG("%s %s\n", currentDateTime(), what());
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s:%-6d %s line %-4d %s() : %s\n", currentDateTime(), getExceptionNo(),
|
||||
getFileName(), getLineNo(), getFunctionName(), what());
|
||||
}
|
||||
if (_fileName == nullptr)
|
||||
{
|
||||
if (_errNo == 0)
|
||||
{
|
||||
WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s%s %s.\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message, _errNo,
|
||||
strerror(_errNo), CLR_HDR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_errNo == 0)
|
||||
{
|
||||
WRITELOG("%s%s %s. %s line %-4d %s()%s\n", currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName,
|
||||
CLR_HDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s%s %s. %s line %-4d %s()\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message,
|
||||
_fileName, _line, _functionName, _errNo, strerror(_errNo), CLR_HDR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* Exception::getFileName(const char* file)
|
||||
{
|
||||
for (int len = strlen(file); len > 0; len--)
|
||||
{
|
||||
if (*(file + len) == '/')
|
||||
{
|
||||
return file + len + 1;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
MQTTSNPublishHandler::MQTTSNPublishHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTSNPublishHandler::~MQTTSNPublishHandler()
|
||||
@@ -37,263 +37,267 @@ MQTTSNPublishHandler::~MQTTSNPublishHandler()
|
||||
|
||||
MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint8_t dup;
|
||||
int qos;
|
||||
uint8_t retained;
|
||||
uint16_t msgId;
|
||||
uint8_t* payload;
|
||||
uint8_t dup;
|
||||
int qos;
|
||||
uint8_t retained;
|
||||
uint16_t msgId;
|
||||
uint16_t tid;
|
||||
uint8_t* payload;
|
||||
MQTTSN_topicid topicid;
|
||||
int payloadlen;
|
||||
Publish pub = MQTTPacket_Publish_Initializer;
|
||||
int payloadlen;
|
||||
Publish pub = MQTTPacket_Publish_Initializer;
|
||||
|
||||
char shortTopic[2];
|
||||
char shortTopic[2];
|
||||
|
||||
if ( !_gateway->getAdapterManager()->getQoSm1Proxy()->isActive() )
|
||||
{
|
||||
if ( client->isQoSm1() )
|
||||
{
|
||||
_gateway->getAdapterManager()->getQoSm1Proxy()->savePacket(client, packet);
|
||||
if (!_gateway->getAdapterManager()->getQoSm1Proxy()->isActive())
|
||||
{
|
||||
if (client->isQoSm1())
|
||||
{
|
||||
_gateway->getAdapterManager()->getQoSm1Proxy()->savePacket(client, packet);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if ( packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) ==0 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
pub.msgId = msgId;
|
||||
pub.header.bits.dup = dup;
|
||||
pub.header.bits.qos = ( qos == 3 ? 0 : qos );
|
||||
pub.header.bits.retain = retained;
|
||||
if (packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
pub.msgId = msgId;
|
||||
pub.header.bits.dup = dup;
|
||||
pub.header.bits.qos = (qos == 3 ? 0 : qos);
|
||||
pub.header.bits.retain = retained;
|
||||
tid = topicid.data.id;
|
||||
|
||||
Topic* topic = nullptr;
|
||||
Topic* topic = nullptr;
|
||||
|
||||
if( topicid.type == MQTTSN_TOPIC_TYPE_SHORT )
|
||||
{
|
||||
shortTopic[0] = topicid.data.short_name[0];
|
||||
shortTopic[1] = topicid.data.short_name[1];
|
||||
pub.topic = shortTopic;
|
||||
pub.topiclen = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicid);
|
||||
if ( !topic )
|
||||
{
|
||||
topic = _gateway->getTopics()->getTopicById(&topicid);
|
||||
if ( topic )
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
}
|
||||
}
|
||||
if (topicid.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||
{
|
||||
shortTopic[0] = topicid.data.short_name[0];
|
||||
shortTopic[1] = topicid.data.short_name[1];
|
||||
pub.topic = shortTopic;
|
||||
pub.topiclen = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicid);
|
||||
if (!topic)
|
||||
{
|
||||
topic = _gateway->getTopics()->getTopicById(&topicid);
|
||||
if (topic)
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
}
|
||||
}
|
||||
|
||||
if( !topic && qos == 3 )
|
||||
{
|
||||
WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
if (!topic && qos == 3)
|
||||
{
|
||||
WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( ( qos == 0 || qos == 3 ) && msgId > 0 )
|
||||
{
|
||||
WRITELOG("%s Invalid MsgId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
if ((qos == 0 || qos == 3) && msgId > 0)
|
||||
{
|
||||
WRITELOG("%s Invalid MsgId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( !topic && msgId && qos > 0 && qos < 3 )
|
||||
{
|
||||
/* Reply PubAck with INVALID_TOPIC_ID to the client */
|
||||
MQTTSNPacket* pubAck = new MQTTSNPacket();
|
||||
pubAck->setPUBACK( topicid.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, pubAck);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
if ( topic )
|
||||
{
|
||||
pub.topic = (char*)topic->getTopicName()->data();
|
||||
pub.topiclen = topic->getTopicName()->length();
|
||||
}
|
||||
}
|
||||
/* Save a msgId & a TopicId pare for PUBACK */
|
||||
if( msgId && qos > 0 && qos < 3)
|
||||
{
|
||||
client->setWaitedPubTopicId(msgId, topicid.data.id, topicid.type);
|
||||
}
|
||||
if (!topic && msgId && qos > 0 && qos < 3)
|
||||
{
|
||||
/* Reply PubAck with INVALID_TOPIC_ID to the client */
|
||||
MQTTSNPacket* pubAck = new MQTTSNPacket();
|
||||
pubAck->setPUBACK(topicid.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, pubAck);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
if (topic)
|
||||
{
|
||||
pub.topic = (char*) topic->getTopicName()->data();
|
||||
pub.topiclen = topic->getTopicName()->length();
|
||||
topicid.data.long_.name = pub.topic;
|
||||
topicid.data.long_.len = pub.topiclen;
|
||||
}
|
||||
}
|
||||
/* Save a msgId & a TopicId pare for PUBACK */
|
||||
if (msgId && qos > 0 && qos < 3)
|
||||
{
|
||||
client->setWaitedPubTopicId(msgId, tid, &topicid);
|
||||
}
|
||||
|
||||
pub.payload = (char*)payload;
|
||||
pub.payloadlen = payloadlen;
|
||||
pub.payload = (char*) payload;
|
||||
pub.payloadlen = payloadlen;
|
||||
|
||||
MQTTGWPacket* publish = new MQTTGWPacket();
|
||||
publish->setPUBLISH(&pub);
|
||||
MQTTGWPacket* publish = new MQTTGWPacket();
|
||||
publish->setPUBLISH(&pub);
|
||||
|
||||
if ( _gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated() )
|
||||
{
|
||||
return publish;
|
||||
}
|
||||
else
|
||||
{
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, publish);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
if (_gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated())
|
||||
{
|
||||
return publish;
|
||||
}
|
||||
else
|
||||
{
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, publish);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handlePuback(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t topicId;
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
|
||||
if ( client->isActive() )
|
||||
{
|
||||
if ( packet->getPUBACK(&topicId, &msgId, &rc) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( rc == MQTTSN_RC_ACCEPTED)
|
||||
{
|
||||
if ( !_gateway->getAdapterManager()->getAggregater()->isActive() )
|
||||
{
|
||||
MQTTGWPacket* pubAck = new MQTTGWPacket();
|
||||
pubAck->setAck(PUBACK, msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubAck);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
else if ( rc == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID)
|
||||
{
|
||||
WRITELOG(" PUBACK %d : Invalid Topic ID\n", msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType)
|
||||
{
|
||||
uint16_t msgId;
|
||||
|
||||
if ( client->isActive() )
|
||||
{
|
||||
if ( packet->getACK(&msgId) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
MQTTGWPacket* ackPacket = new MQTTGWPacket();
|
||||
ackPacket->setAck(packetType, msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, ackPacket);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t msgId;
|
||||
MQTTSNString topicName = MQTTSNString_initializer;;
|
||||
MQTTSN_topicid topicid;
|
||||
|
||||
if ( client->isActive() || client->isAwake())
|
||||
{
|
||||
if ( packet->getREGISTER(&id, &msgId, &topicName) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topicid.data.long_.len = topicName.lenstring.len;
|
||||
topicid.data.long_.name = topicName.lenstring.data;
|
||||
|
||||
id = client->getTopics()->add(&topicid)->getTopicId();
|
||||
|
||||
MQTTSNPacket* regAck = new MQTTSNPacket();
|
||||
regAck->setREGACK(id, msgId, MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, regAck);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t topicId;
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
if ( client->isActive() || client->isAwake())
|
||||
|
||||
if (client->isActive())
|
||||
{
|
||||
if ( packet->getREGACK(&id, &msgId, &rc) == 0 )
|
||||
if (packet->getPUBACK(&topicId, &msgId, &rc) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == MQTTSN_RC_ACCEPTED)
|
||||
{
|
||||
if (!_gateway->getAdapterManager()->getAggregater()->isActive())
|
||||
{
|
||||
MQTTGWPacket* pubAck = new MQTTGWPacket();
|
||||
pubAck->setAck(PUBACK, msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubAck);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
else if (rc == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID)
|
||||
{
|
||||
WRITELOG(" PUBACK %d : Invalid Topic ID\n", msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType)
|
||||
{
|
||||
uint16_t msgId;
|
||||
|
||||
if (client->isActive())
|
||||
{
|
||||
if (packet->getACK(&msgId) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MQTTGWPacket* ackPacket = new MQTTGWPacket();
|
||||
ackPacket->setAck(packetType, msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, ackPacket);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t msgId;
|
||||
MQTTSNString topicName = MQTTSNString_initializer;
|
||||
;
|
||||
MQTTSN_topicid topicid;
|
||||
|
||||
if (client->isActive() || client->isAwake())
|
||||
{
|
||||
if (packet->getREGISTER(&id, &msgId, &topicName) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topicid.data.long_.len = topicName.lenstring.len;
|
||||
topicid.data.long_.name = topicName.lenstring.data;
|
||||
|
||||
id = client->getTopics()->add(&topicid)->getTopicId();
|
||||
|
||||
MQTTSNPacket* regAck = new MQTTSNPacket();
|
||||
regAck->setREGACK(id, msgId, MQTTSN_RC_ACCEPTED);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, regAck);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleRegAck(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
if (client->isActive() || client->isAwake())
|
||||
{
|
||||
if (packet->getREGACK(&id, &msgId, &rc) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* get PUBLISH message */
|
||||
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
|
||||
|
||||
if ( regAck != nullptr )
|
||||
if (regAck != nullptr)
|
||||
{
|
||||
client->getWaitREGACKPacketList()->erase(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, regAck);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0 )
|
||||
|
||||
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0)
|
||||
{
|
||||
/* send PINGREQ to the broker */
|
||||
client->resetPingRequest();
|
||||
MQTTGWPacket* pingreq = new MQTTGWPacket();
|
||||
pingreq->setHeader(PINGREQ);
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerSendEvent(client, pingreq);
|
||||
_gateway->getBrokerSendQue()->post(evt);
|
||||
client->resetPingRequest();
|
||||
MQTTGWPacket* pingreq = new MQTTGWPacket();
|
||||
pingreq->setHeader(PINGREQ);
|
||||
Event* evt = new Event();
|
||||
evt->setBrokerSendEvent(client, pingreq);
|
||||
_gateway->getBrokerSendQue()->post(evt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
int msgId = 0;
|
||||
MQTTGWPacket* publish = handlePublish(client, packet);
|
||||
if ( publish != nullptr )
|
||||
{
|
||||
if ( publish->getMsgId() > 0 )
|
||||
{
|
||||
if ( packet->isDuplicate() )
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
else
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
publish->setMsgId(msgId);
|
||||
}
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, publish);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
int msgId = 0;
|
||||
MQTTGWPacket* publish = handlePublish(client, packet);
|
||||
if (publish != nullptr)
|
||||
{
|
||||
if (publish->getMsgId() > 0)
|
||||
{
|
||||
if (packet->isDuplicate())
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
else
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
publish->setMsgId(msgId);
|
||||
}
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, publish);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleAggregateAck(Client* client, MQTTSNPacket* packet, int type)
|
||||
{
|
||||
if ( type == MQTTSN_PUBREC )
|
||||
{
|
||||
uint16_t msgId;
|
||||
if (type == MQTTSN_PUBREC)
|
||||
{
|
||||
uint16_t msgId;
|
||||
|
||||
if ( packet->getACK(&msgId) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
MQTTSNPacket* ackPacket = new MQTTSNPacket();
|
||||
ackPacket->setPUBREL(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, ackPacket);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
if (packet->getACK(&msgId) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MQTTSNPacket* ackPacket = new MQTTSNPacket();
|
||||
ackPacket->setPUBREL(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, ackPacket);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,19 +25,19 @@ namespace MQTTSNGW
|
||||
class MQTTSNPublishHandler
|
||||
{
|
||||
public:
|
||||
MQTTSNPublishHandler(Gateway* gateway);
|
||||
~MQTTSNPublishHandler();
|
||||
MQTTGWPacket* handlePublish(Client* client, MQTTSNPacket* packet);
|
||||
void handlePuback(Client* client, MQTTSNPacket* packet);
|
||||
void handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType);
|
||||
void handleRegister(Client* client, MQTTSNPacket* packet);
|
||||
void handleRegAck( Client* client, MQTTSNPacket* packet);
|
||||
MQTTSNPublishHandler(Gateway* gateway);
|
||||
~MQTTSNPublishHandler();
|
||||
MQTTGWPacket* handlePublish(Client* client, MQTTSNPacket* packet);
|
||||
void handlePuback(Client* client, MQTTSNPacket* packet);
|
||||
void handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType);
|
||||
void handleRegister(Client* client, MQTTSNPacket* packet);
|
||||
void handleRegAck(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
void handleAggregatePublish(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateAck(Client* client, MQTTSNPacket* packet, int type);
|
||||
void handleAggregatePublish(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateAck(Client* client, MQTTSNPacket* packet, int type);
|
||||
|
||||
private:
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
/*=====================================
|
||||
Class QoSm1Proxy
|
||||
Class QoSm1Proxy
|
||||
=====================================*/
|
||||
QoSm1Proxy:: QoSm1Proxy(Gateway* gw) : Adapter(gw)
|
||||
QoSm1Proxy::QoSm1Proxy(Gateway* gw) :
|
||||
Adapter(gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
}
|
||||
@@ -37,24 +37,22 @@ QoSm1Proxy::~QoSm1Proxy(void)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QoSm1Proxy::initialize(char* gwName)
|
||||
{
|
||||
if ( _gateway->hasSecureConnection() )
|
||||
if (_gateway->hasSecureConnection())
|
||||
{
|
||||
_isSecure = true;
|
||||
_isSecure = true;
|
||||
}
|
||||
|
||||
/* Create QoS-1 Clients from clients.conf */
|
||||
_gateway->getClientList()->setClientList(QOSM1PROXY_TYPE);
|
||||
/* Create QoS-1 Clients from clients.conf */
|
||||
_gateway->getClientList()->setClientList(QOSM1PROXY_TYPE);
|
||||
|
||||
/* Create a client for QoS-1 proxy */
|
||||
string name = string(gwName) + string("_QoS-1");
|
||||
setup(name.c_str(), Atype_QoSm1Proxy);
|
||||
_isActive = true;
|
||||
/* Create a client for QoS-1 proxy */
|
||||
string name = string(gwName) + string("_QoS-1");
|
||||
setup(name.c_str(), Atype_QoSm1Proxy);
|
||||
_isActive = true;
|
||||
}
|
||||
|
||||
|
||||
bool QoSm1Proxy::isActive(void)
|
||||
{
|
||||
return _isActive;
|
||||
|
||||
@@ -27,12 +27,12 @@ class SensorNetAddress;
|
||||
class MQTTSNPacket;
|
||||
|
||||
/*=====================================
|
||||
Class QoSm1Proxy
|
||||
Class QoSm1Proxy
|
||||
=====================================*/
|
||||
class QoSm1Proxy : public Adapter
|
||||
class QoSm1Proxy: public Adapter
|
||||
{
|
||||
public:
|
||||
QoSm1Proxy(Gateway* gw);
|
||||
QoSm1Proxy(Gateway* gw);
|
||||
~QoSm1Proxy(void);
|
||||
|
||||
void initialize(char* GWnAME);
|
||||
@@ -41,13 +41,10 @@ public:
|
||||
private:
|
||||
Gateway* _gateway;
|
||||
|
||||
bool _isActive {false};
|
||||
bool _isSecure {false};
|
||||
bool _isActive { false };
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */
|
||||
|
||||
@@ -26,7 +26,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
MQTTSNSubscribeHandler::MQTTSNSubscribeHandler(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway = gateway;
|
||||
}
|
||||
|
||||
MQTTSNSubscribeHandler::~MQTTSNSubscribeHandler()
|
||||
@@ -36,63 +36,71 @@ MQTTSNSubscribeHandler::~MQTTSNSubscribeHandler()
|
||||
|
||||
MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint8_t dup;
|
||||
int qos;
|
||||
uint16_t msgId;
|
||||
MQTTSN_topicid topicFilter;
|
||||
Topic* topic = nullptr;
|
||||
uint8_t dup;
|
||||
int qos;
|
||||
uint16_t msgId;
|
||||
MQTTSN_topicid topicFilter;
|
||||
Topic* topic = nullptr;
|
||||
uint16_t topicId = 0;
|
||||
MQTTGWPacket* subscribe;
|
||||
Event* ev1;
|
||||
Event* evsuback;
|
||||
|
||||
if ( packet->getSUBSCRIBE(&dup, &qos, &msgId, &topicFilter) == 0 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (packet->getSUBSCRIBE(&dup, &qos, &msgId, &topicFilter) == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (msgId == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED )
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicFilter);
|
||||
|
||||
if ( !topic )
|
||||
if (!topic)
|
||||
{
|
||||
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
||||
if ( topic )
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
}
|
||||
else
|
||||
{
|
||||
goto RespExit;
|
||||
}
|
||||
/* Search the topic in Client common topic table */
|
||||
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
||||
if (topic)
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
topicId = topic->getTopicId();
|
||||
subscribe = new MQTTGWPacket();
|
||||
subscribe->setSUBSCRIBE((char*)topic->getTopicName()->c_str(), (uint8_t)qos, (uint16_t)msgId);
|
||||
subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), (uint8_t) qos, (uint16_t) msgId);
|
||||
|
||||
}
|
||||
else if (topicFilter.type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
topic = client->getTopics()->getTopicByName(&topicFilter);
|
||||
if ( topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
topic = client->getTopics()->add(&topicFilter);
|
||||
if ( topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
topicId = topic->getTopicId();
|
||||
subscribe = new MQTTGWPacket();
|
||||
|
||||
subscribe->setSUBSCRIBE((char*)topic->getTopicName()->c_str(), (uint8_t)qos, (uint16_t)msgId);
|
||||
subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), (uint8_t) qos, (uint16_t) msgId);
|
||||
}
|
||||
else //MQTTSN_TOPIC_TYPE_SHORT
|
||||
{
|
||||
@@ -103,73 +111,70 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
topicId = topicFilter.data.short_name[0] << 8;
|
||||
topicId |= topicFilter.data.short_name[1];
|
||||
subscribe = new MQTTGWPacket();
|
||||
subscribe->setSUBSCRIBE(topicstr, (uint8_t)qos, (uint16_t)msgId);
|
||||
subscribe->setSUBSCRIBE(topicstr, (uint8_t) qos, (uint16_t) msgId);
|
||||
}
|
||||
|
||||
client->setWaitedSubTopicId(msgId, topicId, topicFilter.type);
|
||||
client->setWaitedSubTopicId(msgId, topicId, &topicFilter);
|
||||
|
||||
if ( !client->isAggregated() )
|
||||
if (!client->isAggregated())
|
||||
{
|
||||
ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, subscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, subscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return subscribe;
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
|
||||
RespExit:
|
||||
MQTTSNPacket* sSuback = new MQTTSNPacket();
|
||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_NOT_SUPPORTED);
|
||||
evsuback = new Event();
|
||||
evsuback->setClientSendEvent(client, sSuback);
|
||||
_gateway->getClientSendQue()->post(evsuback);
|
||||
return nullptr;
|
||||
RespExit: MQTTSNPacket* sSuback = new MQTTSNPacket();
|
||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
evsuback = new Event();
|
||||
evsuback->setClientSendEvent(client, sSuback);
|
||||
_gateway->getClientSendQue()->post(evsuback);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t msgId;
|
||||
MQTTSN_topicid topicFilter;
|
||||
uint16_t msgId;
|
||||
MQTTSN_topicid topicFilter;
|
||||
MQTTGWPacket* unsubscribe = nullptr;
|
||||
|
||||
if ( packet->getUNSUBSCRIBE(&msgId, &topicFilter) == 0 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
if (packet->getUNSUBSCRIBE(&msgId, &topicFilter) == 0)
|
||||
{
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (msgId == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||
{
|
||||
char shortTopic[3];
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||
{
|
||||
char shortTopic[3];
|
||||
shortTopic[0] = topicFilter.data.short_name[0];
|
||||
shortTopic[1] = topicFilter.data.short_name[1];
|
||||
shortTopic[2] = 0;
|
||||
unsubscribe = new MQTTGWPacket();
|
||||
unsubscribe->setUNSUBSCRIBE(shortTopic, msgId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Topic* topic = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Topic* topic = nullptr;
|
||||
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
topic = client->getTopics()->getTopicByName(&topicFilter);
|
||||
}
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
topic = client->getTopics()->getTopicByName(&topicFilter);
|
||||
}
|
||||
|
||||
if ( topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
MQTTSNPacket* sUnsuback = new MQTTSNPacket();
|
||||
sUnsuback->setUNSUBACK(msgId);
|
||||
@@ -183,85 +188,87 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
|
||||
unsubscribe = new MQTTGWPacket();
|
||||
unsubscribe->setUNSUBSCRIBE(topic->getTopicName()->c_str(), msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !client->isAggregated() )
|
||||
if (!client->isAggregated())
|
||||
{
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, unsubscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, unsubscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return unsubscribe;
|
||||
return unsubscribe;
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTGWPacket* subscribe = handleSubscribe(client, packet);
|
||||
MQTTGWPacket* subscribe = handleSubscribe(client, packet);
|
||||
|
||||
if ( subscribe != nullptr )
|
||||
{
|
||||
int msgId = 0;
|
||||
if ( packet->isDuplicate() )
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
else
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
if (subscribe != nullptr)
|
||||
{
|
||||
int msgId = 0;
|
||||
if (packet->isDuplicate())
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
else
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
{
|
||||
WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
if (msgId == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
UTF8String str = subscribe->getTopic();
|
||||
string* topicName = new string(str.data, str.len); // topicName is delete by topic
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
UTF8String str = subscribe->getTopic();
|
||||
string* topicName = new string(str.data, str.len); // topicName is delete by topic
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
|
||||
_gateway->getAdapterManager()->getAggregater()->addAggregateTopic(&topic, client);
|
||||
_gateway->getAdapterManager()->getAggregater()->addAggregateTopic(&topic, client);
|
||||
|
||||
subscribe->setMsgId(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerSendEvent(client, subscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev);
|
||||
}
|
||||
subscribe->setMsgId(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerSendEvent(client, subscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet);
|
||||
if ( unsubscribe != nullptr )
|
||||
{
|
||||
int msgId = 0;
|
||||
if ( packet->isDuplicate() )
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
else
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet);
|
||||
if (unsubscribe != nullptr)
|
||||
{
|
||||
int msgId = 0;
|
||||
if (packet->isDuplicate())
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
else
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
{
|
||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
if (msgId == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
UTF8String str = unsubscribe->getTopic();
|
||||
string* topicName = new string(str.data, str.len); // topicName is delete by topic
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(&topic, client);
|
||||
UTF8String str = unsubscribe->getTopic();
|
||||
string* topicName = new string(str.data, str.len); // topicName is delete by topic
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(&topic, client);
|
||||
|
||||
unsubscribe->setMsgId(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerSendEvent(client, unsubscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev);
|
||||
}
|
||||
unsubscribe->setMsgId(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setBrokerSendEvent(client, unsubscribe);
|
||||
_gateway->getBrokerSendQue()->post(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,23 +24,22 @@
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
/*=====================================
|
||||
Class MQTTSNSubscribeHandler
|
||||
Class MQTTSNSubscribeHandler
|
||||
=====================================*/
|
||||
class MQTTSNSubscribeHandler
|
||||
{
|
||||
public:
|
||||
MQTTSNSubscribeHandler(Gateway* gateway);
|
||||
~MQTTSNSubscribeHandler();
|
||||
MQTTGWPacket* handleSubscribe(Client* client, MQTTSNPacket* packet);
|
||||
MQTTGWPacket* handleUnsubscribe(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateSubscribe(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet);
|
||||
MQTTSNSubscribeHandler(Gateway* gateway);
|
||||
~MQTTSNSubscribeHandler();
|
||||
MQTTGWPacket* handleSubscribe(Client* client, MQTTSNPacket* packet);
|
||||
MQTTGWPacket* handleUnsubscribe(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateSubscribe(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
private:
|
||||
Gateway* _gateway;
|
||||
Gateway* _gateway;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */
|
||||
|
||||
@@ -27,35 +27,35 @@ using namespace MQTTSNGW;
|
||||
Topic::Topic()
|
||||
{
|
||||
_type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
_topicName = nullptr;
|
||||
_topicId = 0;
|
||||
_next = nullptr;
|
||||
_topicName = nullptr;
|
||||
_topicId = 0;
|
||||
_next = nullptr;
|
||||
}
|
||||
|
||||
Topic::Topic(string* topic, MQTTSN_topicTypes type)
|
||||
{
|
||||
_type = type;
|
||||
_topicName = topic;
|
||||
_topicId = 0;
|
||||
_next = nullptr;
|
||||
_topicName = topic;
|
||||
_topicId = 0;
|
||||
_next = nullptr;
|
||||
}
|
||||
|
||||
Topic::~Topic()
|
||||
{
|
||||
if ( _topicName )
|
||||
{
|
||||
delete _topicName;
|
||||
}
|
||||
if (_topicName)
|
||||
{
|
||||
delete _topicName;
|
||||
}
|
||||
}
|
||||
|
||||
string* Topic::getTopicName(void)
|
||||
{
|
||||
return _topicName;
|
||||
return _topicName;
|
||||
}
|
||||
|
||||
uint16_t Topic::getTopicId(void)
|
||||
{
|
||||
return _topicId;
|
||||
return _topicId;
|
||||
}
|
||||
|
||||
MQTTSN_topicTypes Topic::getType(void)
|
||||
@@ -65,103 +65,103 @@ MQTTSN_topicTypes Topic::getType(void)
|
||||
|
||||
Topic* Topic::duplicate(void)
|
||||
{
|
||||
Topic* newTopic = new Topic();
|
||||
newTopic->_type = _type;
|
||||
newTopic->_topicId = _topicId;
|
||||
newTopic->_topicName = new string(_topicName->c_str());
|
||||
return newTopic;
|
||||
Topic* newTopic = new Topic();
|
||||
newTopic->_type = _type;
|
||||
newTopic->_topicId = _topicId;
|
||||
newTopic->_topicName = new string(_topicName->c_str());
|
||||
return newTopic;
|
||||
}
|
||||
|
||||
bool Topic::isMatch(string* topicName)
|
||||
{
|
||||
string::size_type tlen = _topicName->size();
|
||||
string::size_type tlen = _topicName->size();
|
||||
|
||||
string::size_type tpos = 0;
|
||||
string::size_type tloc = 0;
|
||||
string::size_type pos = 0;
|
||||
string::size_type loc = 0;
|
||||
string wildcard = "#";
|
||||
string wildcards = "+";
|
||||
string::size_type tpos = 0;
|
||||
string::size_type tloc = 0;
|
||||
string::size_type pos = 0;
|
||||
string::size_type loc = 0;
|
||||
string wildcard = "#";
|
||||
string wildcards = "+";
|
||||
|
||||
while(true)
|
||||
{
|
||||
loc = topicName->find('/', pos);
|
||||
tloc = _topicName->find('/', tpos);
|
||||
while (true)
|
||||
{
|
||||
loc = topicName->find('/', pos);
|
||||
tloc = _topicName->find('/', tpos);
|
||||
|
||||
if ( loc != string::npos && tloc != string::npos )
|
||||
{
|
||||
string subtopic = topicName->substr(pos, loc - pos);
|
||||
string subtopict = _topicName->substr(tpos, tloc - tpos);
|
||||
if (subtopict == wildcard)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (subtopict == wildcards)
|
||||
{
|
||||
if ( (tpos = tloc + 1 ) > tlen )
|
||||
{
|
||||
pos = loc + 1;
|
||||
loc = topicName->find('/', pos);
|
||||
if ( loc == string::npos )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pos = loc + 1;
|
||||
}
|
||||
else if ( subtopic != subtopict )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (tpos = tloc + 1) > tlen )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (loc != string::npos && tloc != string::npos)
|
||||
{
|
||||
string subtopic = topicName->substr(pos, loc - pos);
|
||||
string subtopict = _topicName->substr(tpos, tloc - tpos);
|
||||
if (subtopict == wildcard)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (subtopict == wildcards)
|
||||
{
|
||||
if ((tpos = tloc + 1) > tlen)
|
||||
{
|
||||
pos = loc + 1;
|
||||
loc = topicName->find('/', pos);
|
||||
if (loc == string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pos = loc + 1;
|
||||
}
|
||||
else if (subtopic != subtopict)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((tpos = tloc + 1) > tlen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos = loc + 1;
|
||||
}
|
||||
}
|
||||
else if ( loc == string::npos && tloc == string::npos )
|
||||
{
|
||||
string subtopic = topicName->substr(pos);
|
||||
string subtopict = _topicName->substr(tpos);
|
||||
if ( subtopict == wildcard || subtopict == wildcards)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ( subtopic == subtopict )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( loc == string::npos && tloc != string::npos )
|
||||
{
|
||||
string subtopic = topicName->substr(pos);
|
||||
string subtopict = _topicName->substr(tpos, tloc - tpos);
|
||||
if ( subtopic != subtopict)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
pos = loc + 1;
|
||||
}
|
||||
}
|
||||
else if (loc == string::npos && tloc == string::npos)
|
||||
{
|
||||
string subtopic = topicName->substr(pos);
|
||||
string subtopict = _topicName->substr(tpos);
|
||||
if (subtopict == wildcard || subtopict == wildcards)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (subtopic == subtopict)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (loc == string::npos && tloc != string::npos)
|
||||
{
|
||||
string subtopic = topicName->substr(pos);
|
||||
string subtopict = _topicName->substr(tpos, tloc - tpos);
|
||||
if (subtopic != subtopict)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tpos = tloc + 1;
|
||||
tpos = tloc + 1;
|
||||
|
||||
return _topicName->substr(tpos) == wildcard;
|
||||
}
|
||||
else if ( loc != string::npos && tloc == string::npos )
|
||||
{
|
||||
return _topicName->substr(tpos) == wildcard;
|
||||
}
|
||||
}
|
||||
return _topicName->substr(tpos) == wildcard;
|
||||
}
|
||||
else if (loc != string::npos && tloc == string::npos)
|
||||
{
|
||||
return _topicName->substr(tpos) == wildcard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Topic::print(void)
|
||||
@@ -198,11 +198,11 @@ Topic* Topics::getTopicByName(const MQTTSN_topicid* topicid)
|
||||
string sname = string(ch, ch + topicid->data.long_.len);
|
||||
while (p)
|
||||
{
|
||||
if ( p->_topicName->compare(sname) == 0 )
|
||||
{
|
||||
return p;
|
||||
}
|
||||
p = p->_next;
|
||||
if (p->_topicName->compare(sname) == 0)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
p = p->_next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ Topic* Topics::getTopicById(const MQTTSN_topicid* topicid)
|
||||
|
||||
while (p)
|
||||
{
|
||||
if ( p->_type == topicid->type && p->_topicId == topicid->data.id )
|
||||
if (p->_type == topicid->type && p->_topicId == topicid->data.id)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
@@ -225,14 +225,14 @@ Topic* Topics::getTopicById(const MQTTSN_topicid* topicid)
|
||||
// For MQTTSN_TOPIC_TYPE_NORMAL */
|
||||
Topic* Topics::add(const MQTTSN_topicid* topicid)
|
||||
{
|
||||
if (topicid->type != MQTTSN_TOPIC_TYPE_NORMAL )
|
||||
if (topicid->type != MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Topic* topic = getTopicByName(topicid);
|
||||
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
return topic;
|
||||
}
|
||||
@@ -244,18 +244,17 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
||||
{
|
||||
MQTTSN_topicid topicId;
|
||||
|
||||
if ( _cnt >= MAX_TOPIC_PAR_CLIENT )
|
||||
if (_cnt >= MAX_TOPIC_PAR_CLIENT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
topicId.data.long_.name = (char*)const_cast<char*>(topicName);
|
||||
topicId.data.long_.name = (char*) const_cast<char*>(topicName);
|
||||
topicId.data.long_.len = strlen(topicName);
|
||||
|
||||
|
||||
Topic* topic = getTopicByName(&topicId);
|
||||
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
return topic;
|
||||
}
|
||||
@@ -270,7 +269,7 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
||||
string* name = new string(topicName);
|
||||
topic->_topicName = name;
|
||||
|
||||
if ( id == 0 )
|
||||
if (id == 0)
|
||||
{
|
||||
topic->_type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topic->_topicId = getNextTopicId();
|
||||
@@ -278,12 +277,12 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
||||
else
|
||||
{
|
||||
topic->_type = MQTTSN_TOPIC_TYPE_PREDEFINED;
|
||||
topic->_topicId = id;
|
||||
topic->_topicId = id;
|
||||
}
|
||||
|
||||
_cnt++;
|
||||
|
||||
if ( _first == nullptr)
|
||||
if (_first == nullptr)
|
||||
{
|
||||
_first = topic;
|
||||
}
|
||||
@@ -331,7 +330,6 @@ Topic* Topics::match(const MQTTSN_topicid* topicid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Topics::eraseNormal(void)
|
||||
{
|
||||
Topic* topic = _first;
|
||||
@@ -340,14 +338,14 @@ void Topics::eraseNormal(void)
|
||||
|
||||
while (topic)
|
||||
{
|
||||
if ( topic->_type == MQTTSN_TOPIC_TYPE_NORMAL )
|
||||
if (topic->_type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
next = topic->_next;
|
||||
if ( _first == topic )
|
||||
if (_first == topic)
|
||||
{
|
||||
_first = next;
|
||||
}
|
||||
if ( prev )
|
||||
if (prev)
|
||||
{
|
||||
prev->_next = next;
|
||||
}
|
||||
@@ -365,18 +363,18 @@ void Topics::eraseNormal(void)
|
||||
|
||||
Topic* Topics::getFirstTopic(void)
|
||||
{
|
||||
return _first;
|
||||
return _first;
|
||||
}
|
||||
|
||||
Topic* Topics::getNextTopic(Topic* topic)
|
||||
{
|
||||
return topic->_next;
|
||||
return topic->_next;
|
||||
}
|
||||
|
||||
void Topics::print(void)
|
||||
{
|
||||
Topic* topic = _first;
|
||||
if (topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("No Topic.\n");
|
||||
}
|
||||
@@ -398,13 +396,22 @@ uint8_t Topics::getCount(void)
|
||||
/*=====================================
|
||||
Class TopicIdMap
|
||||
=====================================*/
|
||||
TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_msgId = msgId;
|
||||
_topicId = topicId;
|
||||
_type = type;
|
||||
_type = topic->type;
|
||||
_wildcard = 0;
|
||||
_next = nullptr;
|
||||
_prev = nullptr;
|
||||
|
||||
if (_type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
if (strchr(topic->data.long_.name, '#') != 0 || strchr(topic->data.long_.name, '+') != 0)
|
||||
{
|
||||
_wildcard = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMapElement::~TopicIdMapElement()
|
||||
@@ -419,7 +426,14 @@ MQTTSN_topicTypes TopicIdMapElement::getTopicType(void)
|
||||
|
||||
uint16_t TopicIdMapElement::getTopicId(void)
|
||||
{
|
||||
return _topicId;
|
||||
if (_wildcard > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _topicId;
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMap::TopicIdMap()
|
||||
@@ -434,7 +448,7 @@ TopicIdMap::TopicIdMap()
|
||||
TopicIdMap::~TopicIdMap()
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
TopicIdMapElement* q = p->_next;
|
||||
delete p;
|
||||
@@ -445,9 +459,9 @@ TopicIdMap::~TopicIdMap()
|
||||
TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_msgId == msgId )
|
||||
if (p->_msgId == msgId)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
@@ -456,23 +470,23 @@ TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
if ( _cnt > _maxInflight * 2 || ( topicId == 0 && type != MQTTSN_TOPIC_TYPE_SHORT ) )
|
||||
if (_cnt > _maxInflight * 2 || (topicId == 0 && topic->type != MQTTSN_TOPIC_TYPE_SHORT))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( getElement(msgId) )
|
||||
if (getElement(msgId))
|
||||
{
|
||||
erase(msgId);
|
||||
}
|
||||
|
||||
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, type);
|
||||
if ( elm == 0 )
|
||||
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, topic);
|
||||
if (elm == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( _first == nullptr )
|
||||
if (_first == nullptr)
|
||||
{
|
||||
_first = elm;
|
||||
_end = elm;
|
||||
@@ -490,11 +504,11 @@ TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topi
|
||||
void TopicIdMap::erase(uint16_t msgId)
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_msgId == msgId )
|
||||
if (p->_msgId == msgId)
|
||||
{
|
||||
if ( p->_prev == nullptr )
|
||||
if (p->_prev == nullptr)
|
||||
{
|
||||
_first = p->_next;
|
||||
}
|
||||
@@ -503,7 +517,7 @@ void TopicIdMap::erase(uint16_t msgId)
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
|
||||
if ( p->_next == nullptr )
|
||||
if (p->_next == nullptr)
|
||||
{
|
||||
_end = p->_prev;
|
||||
}
|
||||
@@ -523,7 +537,7 @@ void TopicIdMap::erase(uint16_t msgId)
|
||||
void TopicIdMap::clear(void)
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
TopicIdMapElement* q = p->_next;
|
||||
delete p;
|
||||
@@ -534,5 +548,3 @@ void TopicIdMap::clear(void)
|
||||
_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Topic
|
||||
======================================*/
|
||||
@@ -46,7 +45,7 @@ public:
|
||||
private:
|
||||
MQTTSN_topicTypes _type;
|
||||
uint16_t _topicId;
|
||||
string* _topicName;
|
||||
string* _topicName;
|
||||
Topic* _next;
|
||||
};
|
||||
|
||||
@@ -72,7 +71,7 @@ public:
|
||||
private:
|
||||
uint16_t _nextTopicId;
|
||||
Topic* _first;
|
||||
uint8_t _cnt;
|
||||
uint8_t _cnt;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
@@ -82,7 +81,7 @@ class TopicIdMapElement
|
||||
{
|
||||
friend class TopicIdMap;
|
||||
public:
|
||||
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
~TopicIdMapElement();
|
||||
MQTTSN_topicTypes getTopicType(void);
|
||||
uint16_t getTopicId(void);
|
||||
@@ -90,6 +89,7 @@ public:
|
||||
private:
|
||||
uint16_t _msgId;
|
||||
uint16_t _topicId;
|
||||
uint8_t _wildcard;
|
||||
MQTTSN_topicTypes _type;
|
||||
TopicIdMapElement* _next;
|
||||
TopicIdMapElement* _prev;
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
TopicIdMap();
|
||||
~TopicIdMap();
|
||||
TopicIdMapElement* getElement(uint16_t msgId);
|
||||
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
void erase(uint16_t msgId);
|
||||
void clear(void);
|
||||
private:
|
||||
@@ -112,9 +112,6 @@ private:
|
||||
int _maxInflight;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWTOPIC_H_ */
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#ifndef MQTTSNGWVERSION_H_IN_
|
||||
#define MQTTSNGWVERSION_H_IN_
|
||||
|
||||
#define PAHO_GATEWAY_VERSION "1.4.0"
|
||||
#define PAHO_GATEWAY_VERSION "1.6.0"
|
||||
|
||||
#endif /* MQTTSNGWVERSION_H_IN_ */
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#ifndef MQTTSNGWVERSION_H_IN_
|
||||
#define MQTTSNGWVERSION_H_IN_
|
||||
|
||||
#define PAHO_GATEWAY_VERSION "@GATEWAY_VERSION@"
|
||||
#define PAHO_GATEWAY_VERSION "@GATEWAY_VERSION@"
|
||||
|
||||
#endif /* MQTTSNGWVERSION_H_IN_ */
|
||||
@@ -32,10 +32,10 @@ MQTTSNGW::Gateway* theGateway = nullptr;
|
||||
|
||||
Gateway::Gateway(void)
|
||||
{
|
||||
theGateway = this;
|
||||
theMultiTaskProcess = this;
|
||||
theProcess = this;
|
||||
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
|
||||
_clientList = new ClientList();
|
||||
_clientList = new ClientList(this);
|
||||
_adapterManager = new AdapterManager(this);
|
||||
_topics = new Topics();
|
||||
_stopFlg = false;
|
||||
@@ -43,78 +43,87 @@ Gateway::Gateway(void)
|
||||
|
||||
Gateway::~Gateway()
|
||||
{
|
||||
if ( _params.loginId )
|
||||
{
|
||||
free(_params.loginId);
|
||||
}
|
||||
if ( _params.password )
|
||||
{
|
||||
free(_params.password);
|
||||
}
|
||||
if ( _params.gatewayName )
|
||||
{
|
||||
free(_params.gatewayName);
|
||||
}
|
||||
if ( _params.brokerName )
|
||||
{
|
||||
free(_params.brokerName);
|
||||
}
|
||||
if ( _params.port )
|
||||
{
|
||||
free(_params.port);
|
||||
}
|
||||
if ( _params.portSecure )
|
||||
{
|
||||
free(_params.portSecure);
|
||||
}
|
||||
if ( _params.certKey )
|
||||
{
|
||||
free(_params.certKey);
|
||||
}
|
||||
if ( _params.privateKey )
|
||||
{
|
||||
free(_params.privateKey);
|
||||
}
|
||||
if ( _params.rootCApath )
|
||||
{
|
||||
free(_params.rootCApath);
|
||||
}
|
||||
if ( _params.rootCAfile )
|
||||
{
|
||||
free(_params.rootCAfile);
|
||||
}
|
||||
if ( _params.clientListName )
|
||||
{
|
||||
free(_params.clientListName);
|
||||
}
|
||||
if ( _params.predefinedTopicFileName )
|
||||
{
|
||||
free( _params.predefinedTopicFileName);
|
||||
}
|
||||
if ( _params.configName )
|
||||
{
|
||||
free(_params.configName);
|
||||
}
|
||||
|
||||
if ( _params.qosMinusClientListName )
|
||||
if (_params.loginId)
|
||||
{
|
||||
free(_params.loginId);
|
||||
}
|
||||
if (_params.password)
|
||||
{
|
||||
free(_params.password);
|
||||
}
|
||||
if (_params.gatewayName)
|
||||
{
|
||||
free(_params.gatewayName);
|
||||
}
|
||||
if (_params.brokerName)
|
||||
{
|
||||
free(_params.brokerName);
|
||||
}
|
||||
if (_params.port)
|
||||
{
|
||||
free(_params.port);
|
||||
}
|
||||
if (_params.portSecure)
|
||||
{
|
||||
free(_params.portSecure);
|
||||
}
|
||||
if (_params.certKey)
|
||||
{
|
||||
free(_params.certKey);
|
||||
}
|
||||
if (_params.privateKey)
|
||||
{
|
||||
free(_params.privateKey);
|
||||
}
|
||||
if (_params.rootCApath)
|
||||
{
|
||||
free(_params.rootCApath);
|
||||
}
|
||||
if (_params.rootCAfile)
|
||||
{
|
||||
free(_params.rootCAfile);
|
||||
}
|
||||
if (_params.clientListName)
|
||||
{
|
||||
free(_params.clientListName);
|
||||
}
|
||||
if (_params.predefinedTopicFileName)
|
||||
{
|
||||
free(_params.predefinedTopicFileName);
|
||||
}
|
||||
if (_params.configName)
|
||||
{
|
||||
free(_params.configName);
|
||||
}
|
||||
if (_params.qosMinusClientListName)
|
||||
{
|
||||
free(_params.qosMinusClientListName);
|
||||
}
|
||||
if (_params.rfcommAddr)
|
||||
{
|
||||
free(_params.rfcommAddr);
|
||||
}
|
||||
if (_params.gwCertskey)
|
||||
{
|
||||
free(_params.gwCertskey);
|
||||
}
|
||||
if (_params.gwPrivatekey)
|
||||
{
|
||||
free(_params.gwPrivatekey);
|
||||
}
|
||||
|
||||
if ( _adapterManager )
|
||||
if (_adapterManager)
|
||||
{
|
||||
delete _adapterManager;
|
||||
}
|
||||
if ( _clientList )
|
||||
if (_clientList)
|
||||
{
|
||||
delete _clientList;
|
||||
}
|
||||
|
||||
if ( _topics )
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
// WRITELOG("Gateway is deleted normally.\r\n");
|
||||
if (_topics)
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
}
|
||||
|
||||
int Gateway::getParam(const char* parameter, char* value)
|
||||
@@ -124,256 +133,285 @@ int Gateway::getParam(const char* parameter, char* value)
|
||||
|
||||
char* Gateway::getClientListFileName(void)
|
||||
{
|
||||
return _params.clientListName;
|
||||
return _params.clientListName;
|
||||
}
|
||||
|
||||
char* Gateway::getPredefinedTopicFileName(void)
|
||||
{
|
||||
return _params.predefinedTopicFileName;
|
||||
return _params.predefinedTopicFileName;
|
||||
}
|
||||
|
||||
void Gateway::initialize(int argc, char** argv)
|
||||
{
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
string fileName;
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
string fileName;
|
||||
theGateway = this;
|
||||
|
||||
MultiTaskProcess::initialize(argc, argv);
|
||||
resetRingBuffer();
|
||||
MultiTaskProcess::initialize(argc, argv);
|
||||
resetRingBuffer();
|
||||
|
||||
_params.configDir = *getConfigDirName();
|
||||
_params.configDir = *getConfigDirName();
|
||||
fileName = _params.configDir + *getConfigFileName();
|
||||
_params.configName = strdup(fileName.c_str());
|
||||
|
||||
if (getParam("BrokerName", param) == 0)
|
||||
{
|
||||
_params.brokerName = strdup(param);
|
||||
}
|
||||
if (getParam("BrokerPortNo", param) == 0)
|
||||
{
|
||||
_params.port = strdup(param);
|
||||
}
|
||||
if (getParam("BrokerSecurePortNo", param) == 0)
|
||||
{
|
||||
_params.portSecure = strdup(param);
|
||||
}
|
||||
if (getParam("BrokerName", param) == 0)
|
||||
{
|
||||
_params.brokerName = strdup(param);
|
||||
}
|
||||
if (getParam("BrokerPortNo", param) == 0)
|
||||
{
|
||||
_params.port = strdup(param);
|
||||
}
|
||||
if (getParam("BrokerSecurePortNo", param) == 0)
|
||||
{
|
||||
_params.portSecure = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("CertKey", param) == 0)
|
||||
{
|
||||
_params.certKey = strdup(param);
|
||||
}
|
||||
if (getParam("PrivateKey", param) == 0)
|
||||
{
|
||||
_params.privateKey = strdup(param);
|
||||
}
|
||||
if (getParam("RootCApath", param) == 0)
|
||||
{
|
||||
_params.rootCApath = strdup(param);
|
||||
}
|
||||
if (getParam("RootCAfile", param) == 0)
|
||||
{
|
||||
_params.rootCAfile = strdup(param);
|
||||
}
|
||||
if (getParam("CertKey", param) == 0)
|
||||
{
|
||||
_params.certKey = strdup(param);
|
||||
}
|
||||
if (getParam("PrivateKey", param) == 0)
|
||||
{
|
||||
_params.privateKey = strdup(param);
|
||||
}
|
||||
if (getParam("RootCApath", param) == 0)
|
||||
{
|
||||
_params.rootCApath = strdup(param);
|
||||
}
|
||||
if (getParam("RootCAfile", param) == 0)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
_params.gatewayId = atoi(param);
|
||||
}
|
||||
if (getParam("GatewayID", param) == 0)
|
||||
{
|
||||
_params.gatewayId = atoi(param);
|
||||
}
|
||||
|
||||
if (_params.gatewayId == 0 || _params.gatewayId > 255)
|
||||
{
|
||||
throw Exception( "Gateway::initialize: invalid Gateway Id");
|
||||
}
|
||||
if (_params.gatewayId == 0 || _params.gatewayId > 255)
|
||||
{
|
||||
throw Exception("Gateway::initialize: invalid Gateway Id", 0);
|
||||
}
|
||||
|
||||
if (getParam("GatewayName", param) == 0)
|
||||
{
|
||||
_params.gatewayName = strdup(param);
|
||||
}
|
||||
if (getParam("GatewayName", param) == 0)
|
||||
{
|
||||
_params.gatewayName = strdup(param);
|
||||
}
|
||||
|
||||
if (_params.gatewayName == 0 )
|
||||
{
|
||||
throw Exception( "Gateway::initialize: Gateway Name is missing.");
|
||||
}
|
||||
if (_params.gatewayName == 0)
|
||||
{
|
||||
throw Exception("Gateway::initialize: Gateway Name is missing.", 0);
|
||||
}
|
||||
|
||||
_params.mqttVersion = DEFAULT_MQTT_VERSION;
|
||||
if (getParam("MQTTVersion", param) == 0)
|
||||
{
|
||||
_params.mqttVersion = atoi(param);
|
||||
}
|
||||
_params.mqttVersion = DEFAULT_MQTT_VERSION;
|
||||
if (getParam("MQTTVersion", param) == 0)
|
||||
{
|
||||
_params.mqttVersion = atoi(param);
|
||||
}
|
||||
|
||||
_params.maxInflightMsgs = DEFAULT_MQTT_VERSION;
|
||||
if (getParam("MaxInflightMsgs", param) == 0)
|
||||
{
|
||||
_params.maxInflightMsgs = atoi(param);
|
||||
}
|
||||
_params.maxInflightMsgs = MAX_INFLIGHTMESSAGES;
|
||||
if (getParam("MaxInflightMsgs", param) == 0)
|
||||
{
|
||||
_params.maxInflightMsgs = atoi(param);
|
||||
}
|
||||
|
||||
_params.keepAlive = DEFAULT_KEEP_ALIVE_TIME;
|
||||
if (getParam("KeepAlive", param) == 0)
|
||||
{
|
||||
_params.keepAlive = atoi(param);
|
||||
}
|
||||
_params.keepAlive = DEFAULT_KEEP_ALIVE_TIME;
|
||||
if (getParam("KeepAlive", param) == 0)
|
||||
{
|
||||
_params.keepAlive = atoi(param);
|
||||
}
|
||||
|
||||
if (getParam("LoginID", param) == 0)
|
||||
{
|
||||
_params.loginId = strdup(param);
|
||||
}
|
||||
if (getParam("LoginID", param) == 0)
|
||||
{
|
||||
_params.loginId = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("Password", param) == 0)
|
||||
{
|
||||
_params.password = strdup(param);
|
||||
}
|
||||
if (getParam("Password", param) == 0)
|
||||
{
|
||||
_params.password = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("ClientAuthentication", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.clientAuthentication = true;
|
||||
}
|
||||
}
|
||||
if (getParam("ClientAuthentication", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.clientAuthentication = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (getParam("ClientsList", param) == 0)
|
||||
{
|
||||
_params.clientListName = strdup(param);
|
||||
}
|
||||
if (getParam("ClientsList", param) == 0)
|
||||
{
|
||||
_params.clientListName = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("PredefinedTopic", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
{
|
||||
_params.predefinedTopic = true;
|
||||
if (getParam("PredefinedTopicList", param) == 0)
|
||||
{
|
||||
_params.predefinedTopicFileName = strdup(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getParam("PredefinedTopic", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.predefinedTopic = true;
|
||||
if (getParam("PredefinedTopicList", param) == 0)
|
||||
{
|
||||
_params.predefinedTopicFileName = strdup(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getParam("AggregatingGateway", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
{
|
||||
_params.aggregatingGw = true;
|
||||
}
|
||||
}
|
||||
if (getParam("AggregatingGateway", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.aggregatingGw = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (getParam("Forwarder", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
{
|
||||
_params.forwarder = true;
|
||||
}
|
||||
}
|
||||
if (getParam("Forwarder", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.forwarder = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (getParam("QoS-1", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
{
|
||||
_params.qosMinus1 = true;
|
||||
}
|
||||
}
|
||||
if (getParam("QoS-1", param) == 0)
|
||||
{
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.qosMinus1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
_params.maxClients = MAX_CLIENTS;
|
||||
if (getParam("MaxNumberOfClients", param) == 0)
|
||||
{
|
||||
_params.maxClients = atoi(param);
|
||||
}
|
||||
|
||||
/* Initialize adapters */
|
||||
_adapterManager->initialize( _params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||
if (getParam("RFCOMMAddress", param) == 0)
|
||||
{
|
||||
_params.rfcommAddr = strdup(param);
|
||||
}
|
||||
|
||||
/* Setup ClientList and Predefined topics */
|
||||
_clientList->initialize(_params.aggregatingGw);
|
||||
/* Setup max PacketEventQue size */
|
||||
_packetEventQue.setMaxSize(_params.maxInflightMsgs * _params.maxClients);
|
||||
|
||||
/* Initialize adapters */
|
||||
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||
|
||||
/* Setup ClientList and Predefined topics */
|
||||
_clientList->initialize(_params.aggregatingGw);
|
||||
|
||||
/* SensorNetwork initialize */
|
||||
_sensorNetwork.initialize();
|
||||
}
|
||||
|
||||
void Gateway::run(void)
|
||||
{
|
||||
/* write prompts */
|
||||
_lightIndicator.redLight(true);
|
||||
WRITELOG("\n%s", PAHO_COPYRIGHT4);
|
||||
WRITELOG("\n%s\n", PAHO_COPYRIGHT0);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT1);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT2);
|
||||
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);
|
||||
_lightIndicator.redLight(true);
|
||||
WRITELOG("\n%s", PAHO_COPYRIGHT4);
|
||||
WRITELOG("\n%s\n", PAHO_COPYRIGHT0);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT1);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT2);
|
||||
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT4);
|
||||
WRITELOG(" ConfigFile : %s\n", _params.configName);
|
||||
|
||||
if ( _params.clientListName )
|
||||
{
|
||||
WRITELOG(" ClientList: %s\n", _params.clientListName);
|
||||
}
|
||||
|
||||
if ( _params.predefinedTopicFileName )
|
||||
if (_params.clientListName)
|
||||
{
|
||||
WRITELOG(" PreDefFile: %s\n", _params.predefinedTopicFileName);
|
||||
WRITELOG(" ClientList : %s\n", _params.clientListName);
|
||||
}
|
||||
|
||||
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
|
||||
WRITELOG(" Broker: %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" RootCApath: %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile: %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey: %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey);
|
||||
if (_params.predefinedTopicFileName)
|
||||
{
|
||||
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
|
||||
}
|
||||
|
||||
_stopFlg = false;
|
||||
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" RootCApath : %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey : %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey : %s\n", _params.privateKey);
|
||||
WRITELOG(" SensorN/W : %s\n", _sensorNetwork.getDescription());
|
||||
#ifdef DTLS
|
||||
WRITELOG(" DtlsCertsKey: %s\n", _params.gwCertskey);
|
||||
WRITELOG(" DtlsPrivKey : %s\n", _params.gwPrivatekey);
|
||||
#endif
|
||||
WRITELOG(" Max Clients : %d\n\n", _params.maxClients);
|
||||
WRITELOG("%s %s starts running.\n\n", currentDateTime(), _params.gatewayName);
|
||||
|
||||
/* Run Tasks until CTRL+C entred */
|
||||
MultiTaskProcess::run();
|
||||
_stopFlg = false;
|
||||
|
||||
_stopFlg = true;
|
||||
/* Run Tasks until CTRL+C entered or Exception occurred */
|
||||
MultiTaskProcess::run();
|
||||
WRITELOG("\n");
|
||||
_stopFlg = true;
|
||||
|
||||
/* stop Tasks */
|
||||
Event* ev = new Event();
|
||||
ev->setStop();
|
||||
_packetEventQue.post(ev);
|
||||
ev = new Event();
|
||||
ev->setStop();
|
||||
_brokerSendQue.post(ev);
|
||||
ev = new Event();
|
||||
ev->setStop();
|
||||
_clientSendQue.post(ev);
|
||||
/* stop Tasks */
|
||||
Event* ev = new Event();
|
||||
ev->setStop();
|
||||
_packetEventQue.post(ev);
|
||||
ev = new Event();
|
||||
ev->setStop();
|
||||
_brokerSendQue.post(ev);
|
||||
ev = new Event();
|
||||
ev->setStop();
|
||||
_clientSendQue.post(ev);
|
||||
|
||||
/* wait until all Task stop */
|
||||
MultiTaskProcess::waitStop();
|
||||
/* wait until all Task stop */
|
||||
MultiTaskProcess::waitStop();
|
||||
|
||||
WRITELOG("\n\n%s MQTT-SN Gateway stopped.\n\n", currentDateTime());
|
||||
_lightIndicator.allLightOff();
|
||||
WRITELOG("\n%s MQTT-SN Gateway stopped.\n\n", currentDateTime());
|
||||
_lightIndicator.allLightOff();
|
||||
}
|
||||
|
||||
bool Gateway::IsStopping(void)
|
||||
{
|
||||
return _stopFlg;
|
||||
return _stopFlg;
|
||||
}
|
||||
|
||||
EventQue* Gateway::getPacketEventQue()
|
||||
{
|
||||
return &_packetEventQue;
|
||||
return &_packetEventQue;
|
||||
}
|
||||
|
||||
EventQue* Gateway::getClientSendQue()
|
||||
{
|
||||
return &_clientSendQue;
|
||||
return &_clientSendQue;
|
||||
}
|
||||
|
||||
EventQue* Gateway::getBrokerSendQue()
|
||||
{
|
||||
return &_brokerSendQue;
|
||||
return &_brokerSendQue;
|
||||
}
|
||||
|
||||
ClientList* Gateway::getClientList()
|
||||
{
|
||||
return _clientList;
|
||||
return _clientList;
|
||||
}
|
||||
|
||||
SensorNetwork* Gateway::getSensorNetwork()
|
||||
{
|
||||
return &_sensorNetwork;
|
||||
return &_sensorNetwork;
|
||||
}
|
||||
|
||||
LightIndicator* Gateway::getLightIndicator()
|
||||
{
|
||||
return &_lightIndicator;
|
||||
return &_lightIndicator;
|
||||
}
|
||||
|
||||
GatewayParams* Gateway::getGWParams(void)
|
||||
{
|
||||
return &_params;
|
||||
return &_params;
|
||||
}
|
||||
|
||||
AdapterManager* Gateway::getAdapterManager(void)
|
||||
@@ -388,102 +426,98 @@ Topics* Gateway::getTopics(void)
|
||||
|
||||
bool Gateway::hasSecureConnection(void)
|
||||
{
|
||||
return ( _params.certKey
|
||||
&& _params.privateKey
|
||||
&& _params.rootCApath
|
||||
&& _params.rootCAfile );
|
||||
return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class EventQue
|
||||
=====================================*/
|
||||
EventQue::EventQue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EventQue::~EventQue()
|
||||
{
|
||||
_mutex.lock();
|
||||
while (_que.size() > 0)
|
||||
{
|
||||
delete _que.front();
|
||||
_que.pop();
|
||||
}
|
||||
_mutex.unlock();
|
||||
_mutex.lock();
|
||||
while (_que.size() > 0)
|
||||
{
|
||||
delete _que.front();
|
||||
_que.pop();
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void EventQue::setMaxSize(uint16_t maxSize)
|
||||
void EventQue::setMaxSize(uint16_t maxSize)
|
||||
{
|
||||
_que.setMaxSize((int)maxSize);
|
||||
_que.setMaxSize((int) maxSize);
|
||||
}
|
||||
|
||||
Event* EventQue::wait(void)
|
||||
{
|
||||
Event* ev = nullptr;
|
||||
Event* ev = nullptr;
|
||||
|
||||
while(ev == nullptr)
|
||||
{
|
||||
if ( _que.size() == 0 )
|
||||
{
|
||||
_sem.wait();
|
||||
}
|
||||
_mutex.lock();
|
||||
ev = _que.front();
|
||||
_que.pop();
|
||||
_mutex.unlock();
|
||||
}
|
||||
return ev;
|
||||
while (ev == nullptr)
|
||||
{
|
||||
if (_que.size() == 0)
|
||||
{
|
||||
_sem.wait();
|
||||
}
|
||||
_mutex.lock();
|
||||
ev = _que.front();
|
||||
_que.pop();
|
||||
_mutex.unlock();
|
||||
}
|
||||
return ev;
|
||||
}
|
||||
|
||||
Event* EventQue::timedwait(uint16_t millsec)
|
||||
{
|
||||
Event* ev;
|
||||
if ( _que.size() == 0 )
|
||||
{
|
||||
_sem.timedwait(millsec);
|
||||
}
|
||||
_mutex.lock();
|
||||
Event* ev;
|
||||
if (_que.size() == 0)
|
||||
{
|
||||
_sem.timedwait(millsec);
|
||||
}
|
||||
_mutex.lock();
|
||||
|
||||
if (_que.size() == 0)
|
||||
{
|
||||
ev = new Event();
|
||||
ev->setTimeout();
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = _que.front();
|
||||
_que.pop();
|
||||
}
|
||||
_mutex.unlock();
|
||||
return ev;
|
||||
if (_que.size() == 0)
|
||||
{
|
||||
ev = new Event();
|
||||
ev->setTimeout();
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = _que.front();
|
||||
_que.pop();
|
||||
}
|
||||
_mutex.unlock();
|
||||
return ev;
|
||||
}
|
||||
|
||||
void EventQue::post(Event* ev)
|
||||
{
|
||||
if ( ev )
|
||||
{
|
||||
_mutex.lock();
|
||||
if ( _que.post(ev) )
|
||||
{
|
||||
_sem.post();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ev;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
if (ev)
|
||||
{
|
||||
_mutex.lock();
|
||||
if (_que.post(ev))
|
||||
{
|
||||
_sem.post();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ev;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
int EventQue::size()
|
||||
{
|
||||
_mutex.lock();
|
||||
int sz = _que.size();
|
||||
_mutex.unlock();
|
||||
return sz;
|
||||
_mutex.lock();
|
||||
int sz = _que.size();
|
||||
_mutex.unlock();
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Event
|
||||
=====================================*/
|
||||
@@ -494,96 +528,95 @@ Event::Event()
|
||||
|
||||
Event::~Event()
|
||||
{
|
||||
if (_sensorNetAddr)
|
||||
{
|
||||
delete _sensorNetAddr;
|
||||
}
|
||||
if (_sensorNetAddr)
|
||||
{
|
||||
delete _sensorNetAddr;
|
||||
}
|
||||
|
||||
if (_mqttSNPacket)
|
||||
{
|
||||
delete _mqttSNPacket;
|
||||
}
|
||||
if (_mqttSNPacket)
|
||||
{
|
||||
delete _mqttSNPacket;
|
||||
}
|
||||
|
||||
if (_mqttGWPacket)
|
||||
{
|
||||
delete _mqttGWPacket;
|
||||
}
|
||||
if (_mqttGWPacket)
|
||||
{
|
||||
delete _mqttGWPacket;
|
||||
}
|
||||
}
|
||||
|
||||
EventType Event::getEventType()
|
||||
{
|
||||
return _eventType;
|
||||
return _eventType;
|
||||
}
|
||||
|
||||
void Event::setClientSendEvent(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
_client = client;
|
||||
_eventType = EtClientSend;
|
||||
_mqttSNPacket = packet;
|
||||
_client = client;
|
||||
_eventType = EtClientSend;
|
||||
_mqttSNPacket = packet;
|
||||
}
|
||||
|
||||
void Event::setBrokerSendEvent(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
_client = client;
|
||||
_eventType = EtBrokerSend;
|
||||
_mqttGWPacket = packet;
|
||||
_client = client;
|
||||
_eventType = EtBrokerSend;
|
||||
_mqttGWPacket = packet;
|
||||
}
|
||||
|
||||
void Event::setClientRecvEvent(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
_client = client;
|
||||
_eventType = EtClientRecv;
|
||||
_mqttSNPacket = packet;
|
||||
_client = client;
|
||||
_eventType = EtClientRecv;
|
||||
_mqttSNPacket = packet;
|
||||
}
|
||||
|
||||
void Event::setBrokerRecvEvent(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
_client = client;
|
||||
_eventType = EtBrokerRecv;
|
||||
_mqttGWPacket = packet;
|
||||
_client = client;
|
||||
_eventType = EtBrokerRecv;
|
||||
_mqttGWPacket = packet;
|
||||
}
|
||||
|
||||
void Event::setTimeout(void)
|
||||
{
|
||||
_eventType = EtTimeout;
|
||||
_eventType = EtTimeout;
|
||||
}
|
||||
|
||||
void Event::setStop(void)
|
||||
{
|
||||
_eventType = EtStop;
|
||||
_eventType = EtStop;
|
||||
}
|
||||
|
||||
void Event::setBrodcastEvent(MQTTSNPacket* msg)
|
||||
{
|
||||
_mqttSNPacket = msg;
|
||||
_eventType = EtBroadcast;
|
||||
_mqttSNPacket = msg;
|
||||
_eventType = EtBroadcast;
|
||||
}
|
||||
|
||||
void Event::setClientSendEvent(SensorNetAddress* addr, MQTTSNPacket* msg)
|
||||
{
|
||||
_eventType = EtSensornetSend;
|
||||
_sensorNetAddr = addr;
|
||||
_mqttSNPacket = msg;
|
||||
_eventType = EtSensornetSend;
|
||||
_sensorNetAddr = addr;
|
||||
_mqttSNPacket = msg;
|
||||
}
|
||||
|
||||
Client* Event::getClient(void)
|
||||
{
|
||||
return _client;
|
||||
return _client;
|
||||
}
|
||||
|
||||
SensorNetAddress* Event::getSensorNetAddress(void)
|
||||
{
|
||||
return _sensorNetAddr;
|
||||
return _sensorNetAddr;
|
||||
}
|
||||
|
||||
MQTTSNPacket* Event::getMQTTSNPacket()
|
||||
{
|
||||
return _mqttSNPacket;
|
||||
return _mqttSNPacket;
|
||||
}
|
||||
|
||||
MQTTGWPacket* Event::getMQTTGWPacket(void)
|
||||
{
|
||||
return _mqttGWPacket;
|
||||
return _mqttGWPacket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user