[zb4osgi-changeset] [scm] ZigBee 4 OSGi repository change: r407 - in /projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl: ./ src/ src/main/ src/main/assembly/ src/main/java/ src/main/java/es/ src/main/java/es/unizar/ src/main/java/es/unizar/howlab/ src/main/java/es/unizar/howlab/core/ src/main/java/es/unizar/howlab/core/zigbee/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/ src/main/resources/ src/main/resources/es/ src/main/resources/es/unizar/ src/main/resources/es/unizar/howlab/ src/main/resources/es/unizar/howlab/core/ src/main/resources/es/unizar/howlab/core/zigbee/ src/main/resources/es/unizar/howlab/core/zigbee/telegesis/ src/main/resources/es/unizar/howlab/core/zigbee/telegesis/gateway/ src/test/ src/test/java/ src/test/java/es/ src/test/java/es/unizar/ src/test/java/es/unizar/howlab/ src/test/java/es/unizar/howlab/core/ src/test/java/es/unizar/howlab/core/zigbee/ src/test/java/es/unizar/howlab/core/zigbee/telegesis/ src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/ src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/
scm-notify at zb4osgi.aaloa.org
scm-notify at zb4osgi.aaloa.org
Thu Feb 2 13:18:52 CET 2012
Author: alvaro.marco
Date: Thu Feb 2 13:18:52 2012
New Revision: 407
Log:
howlab import
Added:
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/LICENSE
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/nbactions.xml
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/pom.xml
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/assembly/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/assembly/felix.xml
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/AbstractGateway.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/GatewayFactoryImpl.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/SerialListener.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/Activator.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/SerialConnectionServiceTracker.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Command305.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/ErrorCode305.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Prompt305.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/SpecialSequence305.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/LICENSE
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/unizar/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/unizar/howlab/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/unizar/howlab/core/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/unizar/howlab/core/zigbee/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/gateway/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/CnxListenerTest.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeGatewayListener.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeSerialPort.java
projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305Test.java
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/LICENSE
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/LICENSE (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/LICENSE Thu Feb 2 13:18:52 2012
@@ -1,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/nbactions.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/nbactions.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/nbactions.xml Thu Feb 2 13:18:52 2012
@@ -1,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<actions>
+ <action>
+ <actionName>run</actionName>
+ <goals>
+ <goal>package</goal>
+ <goal>antrun:run</goal>
+ </goals>
+ <activatedProfiles>
+ <activatedProfile>run-on-felix</activatedProfile>
+ </activatedProfiles>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </action>
+ <action>
+ <actionName>debug</actionName>
+ <goals>
+ <goal>package</goal>
+ <goal>antrun:run</goal>
+ </goals>
+ <properties>
+ <vm.args>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address}</vm.args>
+ <jpda.listen>true</jpda.listen>
+ </properties>
+ <activatedProfiles>
+ <activatedProfile>run-on-felix</activatedProfile>
+ </activatedProfiles>
+ </action>
+ <action>
+ <actionName>profile</actionName>
+ <goals>
+ <goal>package</goal>
+ <goal>antrun:run</goal>
+ </goals>
+ <properties>
+ <vm.args>${profiler.args}</vm.args>
+ <!-- XXX <java jvm="${profiler.java}" ...> -->
+ <profiler.action>profile</profiler.action>
+ </properties>
+ <activatedProfiles>
+ <activatedProfile>run-on-felix</activatedProfile>
+ </activatedProfiles>
+ </action>
+ <action>
+ <actionName>build</actionName>
+ <goals>
+ <goal>install</goal>
+ </goals>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </action>
+ <action>
+ <actionName>rebuild</actionName>
+ <goals>
+ <goal>clean</goal>
+ <goal>install</goal>
+ </goals>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </action>
+ <action>
+ <actionName>build-with-dependencies</actionName>
+ <reactor>also-make</reactor>
+ <goals>
+ <goal>install</goal>
+ </goals>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </action>
+ <action>
+ <actionName>CUSTOM-Prepare a Release</actionName>
+ <displayName>Prepare a Release</displayName>
+ <goals>
+ <goal>release:prepare</goal>
+ </goals>
+ </action>
+ <action>
+ <actionName>CUSTOM-Perform a Release</actionName>
+ <displayName>Perform a Release</displayName>
+ <goals>
+ <goal>release:perform</goal>
+ </goals>
+ </action>
+</actions>
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/pom.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/pom.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/pom.xml Thu Feb 2 13:18:52 2012
@@ -1,0 +1,266 @@
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>es.unizar.howlab.core.zigbee.telegesis</groupId>
+ <artifactId>telegesis-gateway-impl</artifactId>
+ <version>1.5-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>telegesis-gateway-impl OSGi Bundle</name>
+
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0, January 2004</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+
+ <!-- Añadir ruta developer, estableciendo la ruta al trunk: -->
+ <scm>
+ <developerConnection>scm:svn:https://web.hermes.cps.unizar.es/repos/howlab/Software/core/zigbee/telegesis/gateway-impl/trunk</developerConnection>
+ </scm>
+
+<!-- Añadir distribution management (en el settings.xml tenemos que tener el usuario y contraseña para el id en el server: -->
+ <distributionManagement>
+ <repository>
+ <uniqueVersion>false</uniqueVersion>
+ <id>repo_nas_rel</id>
+ <url>ftp://howlab.dyndns.org/repo/software/releases/</url>
+ <layout>default</layout>
+ </repository>
+ <snapshotRepository>
+ <uniqueVersion>false</uniqueVersion>
+ <id>repo_nas_snap</id>
+ <url>ftp://howlab.dyndns.org/repo/software/snapshots</url>
+ <layout>default</layout>
+ </snapshotRepository>
+ </distributionManagement>
+ <!-- Añadir los repositorios para poder localizar otros proyectos generados: -->
+ <repositories>
+ <repository>
+ <id>repo_nas_rel</id>
+ <url>ftp://howlab.dyndns.org/repo/software/releases/</url>
+ </repository>
+ <repository>
+ <id>repo_nas_snap</id>
+ <url>ftp://howlab.dyndns.org/repo/software/snapshots</url>
+ </repository>
+ </repositories>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>1.4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>4.2.0</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1.1</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>es.unizar.howlab.core</groupId>
+ <artifactId>easyJavaLib</artifactId>
+ <version>1.6</version>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>es.unizar.howlab.core.zigbee.telegesis</groupId>
+ <artifactId>telegesis-gateway-api</artifactId>
+ <version>1.3</version>
+ <type>bundle</type>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.2.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>es.unizar.howlab.core.zigbee.telegesis.gateway.impl.osgi.Activator</Bundle-Activator>
+ <Export-Package>es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol</Export-Package>
+ <Private-Package>es.unizar.howlab.core.zigbee.telegesis.gateway.impl.*</Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+<!-- Añadir pluggin maven-release-plugin -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.2.1</version>
+ </plugin>
+ </plugins>
+
+ <!-- Añadir extensiones wagon para que se pueda acceder al respositorio de distribucion por ftp -->
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ftp</artifactId>
+ <version>1.0</version>
+ </extension>
+ </extensions>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>build-for-felix</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.main</artifactId>
+ <version>3.0.7</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- To include a shell:
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.gogo.shell</artifactId>
+ <version>0.6.1</version>
+ </dependency>
+ -->
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <id>compile</id>
+ <phase>package</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <pathconvert property="plugins.jars" pathsep="${path.separator}">
+ <path refid="maven.runtime.classpath" />
+ <map from="${project.build.directory}${file.separator}classes" to="" />
+ </pathconvert>
+ <pathconvert pathsep=" " property="bundles">
+ <path path="${plugins.jars}" />
+ <mapper>
+ <chainedmapper>
+ <flattenmapper />
+ <globmapper from="*" to="file:modules/*" casesensitive="no" />
+ </chainedmapper>
+ </mapper>
+ </pathconvert>
+ <propertyfile file="${project.build.directory}/config.properties">
+ <entry key="felix.auto.start" value="${bundles} file:modules/${project.build.finalName}.jar" />
+ <entry key="org.osgi.framework.bootdelegation" value="*" />
+ </propertyfile>
+ <copy file="${maven.dependency.org.apache.felix.org.apache.felix.main.jar.path}" tofile="${project.build.directory}/felix.jar" />
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <id>create-executable-jar</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>${basedir}/src/main/assembly/felix.xml</descriptor>
+ </descriptors>
+ <finalName>${project.build.finalName}</finalName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>run-on-felix</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.main</artifactId>
+ <version>3.0.7</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- esto habilita el uso de common-loggings -->
+ <dependency>
+ <groupId>org.ops4j.pax.logging</groupId>
+ <artifactId>pax-logging-api</artifactId>
+ <version>1.6.3</version>
+ </dependency>
+ <!-- org.apache.felix:org.apache.felix.gogo.shell:0.6.1 useless from Maven since stdin is swallowed -->
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.6</version>
+ <configuration>
+ <target>
+ <property name="vm.args" value="" />
+ <pathconvert property="plugins.jars" pathsep="${path.separator}">
+ <path refid="maven.runtime.classpath" />
+ <map from="${project.build.directory}${file.separator}classes" to="" />
+ </pathconvert>
+ <makeurl property="urls" separator=" ">
+ <path path="${plugins.jars}" />
+ <path location="${project.build.directory}/${project.build.finalName}.jar" />
+ </makeurl>
+ <propertyfile file="${project.build.directory}/run.properties">
+ <entry key="felix.auto.start" value="${urls}" />
+ <entry key="felix.auto.deploy.action" value="uninstall,install,update,start" />
+ <entry key="org.osgi.framework.storage" value="${project.build.directory}${file.separator}felix-cache" />
+ <entry key="org.osgi.framework.bootdelegation" value="*" />
+ </propertyfile>
+ <makeurl property="run.properties.url" file="${project.build.directory}/run.properties" />
+ <java fork="true" jar="${maven.dependency.org.apache.felix.org.apache.felix.main.jar.path}">
+ <sysproperty key="felix.config.properties" value="${run.properties.url}" />
+ <jvmarg line="${vm.args}" />
+ </java>
+ </target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/assembly/felix.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/assembly/felix.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/assembly/felix.xml Thu Feb 2 13:18:52 2012
@@ -1,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assembly>
+ <id>all</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>false</useProjectArtifact>
+ <outputDirectory>modules</outputDirectory>
+ <excludes>
+ <exclude>org.apache.felix:org.apache.felix.main</exclude>
+ </excludes>
+ </dependencySet>
+ </dependencySets>
+ <files>
+ <file>
+ <source>${project.build.directory}/${project.build.finalName}.jar</source>
+ <outputDirectory>modules</outputDirectory>
+ </file>
+ <file>
+ <source>${project.build.directory}/felix.jar</source>
+ <outputDirectory>bin</outputDirectory>
+ </file>
+ <file>
+ <source>${project.build.directory}/config.properties</source>
+ <outputDirectory>conf</outputDirectory>
+ </file>
+ </files>
+</assembly>
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/AbstractGateway.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/AbstractGateway.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/AbstractGateway.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,855 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import es.unizar.howlab.core.io.serial.SerialConnection;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.GatewayListener;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.TelegesisErrorException;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.ZigbeeDeviceType;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.*;
+import es.unizar.howlab.easyjavalib.threading.Locker;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Abstract implementation of class Gateway
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public abstract class AbstractGateway implements Gateway {
+ // Logger
+
+ private Log logger = LogFactory.getLog(this.getClass().getName());
+ // ProductID
+ protected String deviceName = "";
+ protected String firmwareRevision = "";
+ protected String dongleAddress = "";
+
+ @Override
+ abstract public String[] getProductId();
+
+ @Override
+ abstract public void reset();
+
+ @Override
+ abstract public void restoreFactoryDefaults();
+
+ @Override
+ abstract public String readRegister(short regAddress) throws TelegesisErrorException;
+
+ @Override
+ abstract public boolean readRegisterBit(short regAddress, short bitNumber) throws TelegesisErrorException;
+
+ @Override
+ abstract public void writeRegister(short regAddress, String regData) throws TelegesisErrorException;
+
+ @Override
+ abstract public void writeRegisterBit(short regAddress, short bitNumber, boolean bitData) throws TelegesisErrorException;
+
+ @Override
+ abstract public void writeRegister(short regAddress, String regData, String password) throws TelegesisErrorException;
+
+ @Override
+ abstract public void writeRegisterBit(short regAddress, short bitNumber, boolean bitData, String password) throws TelegesisErrorException;
+
+ @Override
+ abstract public short readRemoteRegisterRequest(String EUI64Addr, short regAddress) throws TelegesisErrorException;
+
+ @Override
+ abstract public short readRemoteRegisterBitRequest(String EUI64Addr, short regAddress, short bitNumber) throws TelegesisErrorException;
+
+ @Override
+ abstract public short writeRemoteRegisterRequest(String EUI64Addr, short regAddress, String regData) throws TelegesisErrorException;
+
+ @Override
+ abstract public short writeRemoteRegisterBitRequest(String EUI64Addr, short regAddress, short bitNumber, boolean bitData) throws TelegesisErrorException;
+
+ @Override
+ abstract public short writeRemoteRegisterRequest(String EUI64Addr, short regAddress, String regData, String password) throws TelegesisErrorException;
+
+ @Override
+ abstract public short writeRemoteRegisterBitRequest(String EUI64Addr, short regAddress, short bitNumber, boolean bitData, String password) throws TelegesisErrorException;
+
+ @Override
+ abstract public short[] scanEnergy() throws TelegesisErrorException;
+
+ @Override
+ abstract public PANScanResult[] scanForActivePANs() throws TelegesisErrorException;
+
+ @Override
+ abstract public NetworkJoinedInfo createNetwork() throws TelegesisErrorException;
+
+ @Override
+ abstract public NetworkJoinedInfo joinNetwork() throws TelegesisErrorException;
+
+ @Override
+ abstract public NetworkJoinedInfo joinNetwork(int channel, String PID) throws TelegesisErrorException;
+
+ @Override
+ abstract public void leaveNetwork() throws TelegesisErrorException;
+
+ @Override
+ abstract public short leaveNetworkRequest(String address) throws TelegesisErrorException;
+
+ @Override
+ abstract public NetworkInformation getNetworkInformation();
+
+ @Override
+ abstract public short requestNeighbourTable(short index, String address) throws TelegesisErrorException;
+
+ @Override
+ abstract public void requestNodeId(String address) throws TelegesisErrorException;
+
+ @Override
+ abstract public short requestNodeEUI64Addr(String address, String nodeId) throws TelegesisErrorException;
+
+ @Override
+ abstract public short requestNodeDescriptor(String address, String nodeId) throws TelegesisErrorException;
+
+ @Override
+ abstract public short requestNodePowerDescriptor(String address, String nodeId) throws TelegesisErrorException;
+
+ @Override
+ abstract public short requestNodeActiveEndPoints(String address, String nodeId) throws TelegesisErrorException;
+
+ @Override
+ abstract public short requestNodeEndPointSimpleDescriptor(String address, String nodeId, short EP) throws TelegesisErrorException;
+
+ @Override
+ abstract public void findNodesMatchingDescriptor(String profileId, String[] inClusterList, String[] outClusterList) throws TelegesisErrorException;
+
+ @Override
+ abstract public void annouceLocalNode() throws TelegesisErrorException;
+
+ @Override
+ abstract public void setSourceRoute(String destNode, String[] route) throws TelegesisErrorException;
+
+ @Override
+ abstract public void findRoute(String address) throws TelegesisErrorException;
+
+ @Override
+ abstract public void scanNetwork(int numHops) throws TelegesisErrorException;
+
+ @Override
+ abstract public void updateNetworkKey() throws TelegesisErrorException;
+
+ @Override
+ abstract public void becomeTrustCenter() throws TelegesisErrorException;
+
+ @Override
+ abstract public void becomeNetworkManager() throws TelegesisErrorException;
+
+ @Override
+ abstract public void changeNetworkChannel() throws TelegesisErrorException;
+
+ @Override
+ abstract public void changeNetworkChannel(int channel) throws TelegesisErrorException;
+
+ @Override
+ abstract public AddressTableEntry[] getAddressTable();
+
+ @Override
+ abstract public void setAddressTableEntry(short index, String nodeID, String EUI64Addr) throws TelegesisErrorException;
+
+ @Override
+ abstract public MulticastTableEntry[] getMulticastTable();
+
+ @Override
+ abstract public void setMulticastTableEntry(short index, String ID, short EP) throws TelegesisErrorException;
+
+ @Override
+ abstract public void sendBroadcast(int numHops, String data) throws TelegesisErrorException;
+
+ @Override
+ abstract public void sendBroadcast(int numHops, byte[] data) throws TelegesisErrorException;
+
+ @Override
+ abstract public short sendMessageRequest(String address, String data) throws TelegesisErrorException;
+
+ @Override
+ abstract public short sendMessageRequest(String address, byte[] data) throws TelegesisErrorException;
+
+ @Override
+ abstract public void sendMulticastBroadcast(int numHops, String ID, String data) throws TelegesisErrorException;
+
+ @Override
+ abstract public void sendMulticastBroadcast(int numHops, String ID, byte[] data) throws TelegesisErrorException;
+
+ @Override
+ abstract public String writeCommand(String cmd, boolean expectResponse) throws TelegesisErrorException;
+
+ @Override
+ abstract public boolean open();
+
+ @Override
+ abstract public boolean close();
+
+ @Override
+ abstract public boolean isOpen();
+
+ @Override
+ abstract public SerialConnection getConnection();
+
+ @Override
+ public String getDeviceName() {
+ return deviceName;
+ }
+
+ @Override
+ public String getFirmwareRevision() {
+ return firmwareRevision;
+ }
+
+ @Override
+ public String getDongleAddress() {
+ return dongleAddress;
+ }
+ // <editor-fold defaultstate="collapsed" desc="GESTION BLOQUEO">
+ private Locker locker = new Locker(this.getClass().getSimpleName());
+
+ @Override
+ public boolean tryLock(int milliseconds) {
+ logger.trace("Gateway305::tryLock(milliseconds=" + milliseconds + ")");
+ return locker.tryLock(milliseconds);
+
+ }
+
+ @Override
+ public void lock(int milliseconds) {
+ logger.trace("Gateway305::lock(milliseconds=" + milliseconds + ")");
+ locker.lock(milliseconds);
+
+ }
+
+ @Override
+ public boolean unlock() {
+ logger.trace("Gateway305::unlock()");
+ return locker.unlock();
+
+ }
+
+ /**
+ * Función para ejecutar control de bloqueo (bloquea la ejecucion)
+ */
+ protected void checkLock() {
+ locker.checkLock();
+ }
+ // </editor-fold>
+ // <editor-fold defaultstate="collapsed" desc="GESTION LISTENERS">
+ protected final ArrayList<GatewayListener> gtwyListeners = new ArrayList<GatewayListener>();
+ protected final HashMap<GatewayListener, Executor> gtwyExecutors = new HashMap<GatewayListener, Executor>();
+
+ @Override
+ public void registerListener(GatewayListener lstnr) {
+ logger.trace("AbstractGateway::registerListener(lstnr=" + lstnr + ")");
+ synchronized (gtwyListeners) {
+ if (gtwyListeners.add(lstnr)) {
+ Executor ex = Executors.newSingleThreadExecutor();
+ gtwyExecutors.put(lstnr, ex);
+ }
+
+ }
+ }
+
+ @Override
+ public void unregisterListener(GatewayListener lstnr) {
+ logger.trace("AbstractGateway::unregisterListener(lstnr=" + lstnr + ")");
+ synchronized (gtwyListeners) {
+ if (gtwyListeners.remove(lstnr)) {
+ gtwyExecutors.remove(lstnr);
+ }
+ }
+ }
+
+ /**
+ * Notifies about acknowledgement of a node communication operation,
+ * providing SEQ number and acknowledge result (ACK/NACK)
+ * @param seqNumber SEQ number
+ * @param wasOK True for ACK, false for NACK
+ */
+ protected void fireAcknowledgement(final short seqNumber, final boolean wasACK) {
+ logger.trace("AbstractGateway::fireAcknowledgement(seqNumber=" + seqNumber + ", wasACK=" + wasACK + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.acknowledgement(seqNumber, wasACK, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+
+ }
+
+ /**
+ * Notifies about a route to a remote device found
+ * @param EUI64Addr Remote node address
+ * @param numHops Number of hops
+ * @param route Array containing network addresses of intermediate nodes up
+ * to remote node, excluding local node
+ */
+ protected void fireRouteRecordReceived(final String EUI64Addr, final int numHops, final String[] route) {
+ logger.trace("AbstractGateway::fireRouteRecordReceived(EUI64Addr=" + EUI64Addr + ", numHops=" + numHops + ", route=" + route + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.routeRecordReceived(EUI64Addr, numHops, route, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about reception of a broadcast message
+ * @param EUI64Addr Sender address
+ * @param message Message received
+ */
+ protected void fireBroadcastMessageReceived(final String EUI64Addr, final byte[] message) {
+ logger.trace("AbstractGateway::fireBroadcastMessageReceived(EUI64Addr=" + EUI64Addr + ", message=" + message + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.broadcastMessageReceived(EUI64Addr, message, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about reception of a message, whether it was a broadcast message
+ * multicast or unicast
+ * @param EUI64Addr Sender address
+ * @param message Message received
+ * @param type Message type
+ */
+ protected void fireMessageReceived(final String EUI64Addr, final byte[] message, final String type) {
+ logger.trace("AbstractGateway::fireMessageReceived(EUI64Addr=" + EUI64Addr + ", message=" + message + ", type=" + type + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.messageReceived(EUI64Addr, message, type, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about reception of a message not handled by Telegesis dongle,
+ * providing whole APS frame
+ * @param EUI64Addr Sender address
+ * @param nodeID Sender network address
+ * @param sourceEP Sender EndPoint id
+ * @param destEP Receiver EndPoint id
+ * @param profileID ProfileID
+ * @param clusterID ClusterID
+ * @param payload Message received
+ */
+ protected void fireMessageReceived(final String EUI64Addr, final String nodeID, final short sourceEP, final short destEP, final String profileID, final String clusterID, final byte[] payload) {
+ logger.trace("AbstractGateway::fireMessageReceived(EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", sourceEP=" + sourceEP + ", destEP=" + destEP + ", profileID=" + profileID + ", clusterID=" + clusterID + ", payload=" + payload + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.endpointMessageReceived(EUI64Addr, nodeID, sourceEP, destEP, profileID, clusterID, payload, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node announce
+ * @param type DeviceType (COO, FFD...)
+ * @param EUI64Addr Node's address
+ * @param nodeID Node's network address
+ * @param RSSI RSSI level (dBm) of the last hop
+ * @param LQI LQI indicator of the last hop
+ * @param parentID Parent's network address or null
+ */
+ protected void fireNodeAnnounce(final ZigbeeDeviceType type, final String EUI64Addr, final String nodeID, final int RSSI, final short LQI) {
+ logger.trace("AbstractGateway::fireNodeAnnounce(type=" + type + ", EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", RSSI=" + RSSI + "LQI=" + LQI + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.nodeAnnounce(type, EUI64Addr, nodeID, RSSI, LQI, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a new node announce
+ * @param EUI64Addr Node's address
+ * @param nodeID Node's network address
+ * @param parentID Parent's network address
+ */
+ protected void fireNewNode(final String EUI64Addr, final String nodeID, final String parentID) {
+ logger.trace("AbstractGateway::fireNewNode(EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", parentID=" + parentID + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.newNode(EUI64Addr, nodeID, parentID, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about local node left PAN
+ * Note: also notifies about end device losing parent
+ */
+ protected void fireLeftPAN() {
+ logger.trace("AbstractGateway::fireLeftPAN()");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.leftPAN(gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about local node joining PAN
+ * @param channel Network channel (ranging from 0x0B to 0x1A)
+ * @param PID Network PID
+ * @param EPID Network EPID
+ */
+ protected void fireJoinedPan(final int channel, final String PID, final String EPID) {
+ logger.trace("AbstractGateway::fireJoinedPan(channel=" + channel + ", PID=" + PID + ", EPID=" + EPID + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.joinedPan(channel, PID, EPID, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about operation result of writing on a register
+ * @param nodeID Node's network address
+ * @param EUI64Addr Node's address
+ * @param errorCode Operation result
+ */
+ protected void fireRegisterWrited(final String nodeID, final String EUI64Addr, final short errorCode) {
+ logger.trace("AbstractGateway::fireRegisterWrited(nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + ", errorCode=" + errorCode + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.registerWrited(nodeID, EUI64Addr, errorCode, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about reading of a register
+ * @param nodeID Node's network address
+ * @param EUI64Addr Node's address
+ * @param register Register readed
+ * @param errorCode Operation result
+ * @param data Register contents
+ */
+ protected void fireRegisterReaded(final String nodeID, final String EUI64Addr, final short register, final short errorCode, final String data) {
+ logger.trace("AbstractGateway::fireRegisterReaded(nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + ", register=" + register + ", errorCode=" + errorCode + ", data=" + data + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.registerReaded(nodeID, EUI64Addr, register, errorCode, data, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies response abour an address request to a node
+ * @param errorCode request result
+ * @param nodeID Node's network address
+ * @param EUI64Addr Node's address
+ */
+ protected void fireAddrResponse(final short errorCode, final String nodeID, final String EUI64Addr) {
+ logger.trace("AbstractGateway::fireAddrResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", EUI64Addr=" + EUI64Addr + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.addrResponse(errorCode, nodeID, EUI64Addr, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a Neighbour table request response.
+ * Note: tableLength != table.length() means there are records pending to
+ * receive (if requested)
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param tableLength Total neighbour table
+ * @param table received records
+ */
+ protected void fireNeighbourTableResponse(final String nodeID, final short errorCode, final int tableLength, final NeighbourTableEntry[] table) {
+ logger.trace("AbstractGateway::fireNeighbourTableResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", tableLength=" + tableLength + ", table=" + table + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.neighbourTableResponse(nodeID, errorCode, tableLength, table, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param descriptor Map containig pairs <key,value> of related descriptor
+ */
+ protected void fireNodeDescriptorResponse(final String nodeID, final short errorCode, final Map descriptor) {
+ logger.trace("AbstractGateway::fireNodeDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", descriptor=" + descriptor + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.nodeDescriptorResponse(nodeID, errorCode, descriptor, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param descriptor power descriptor
+ */
+ protected void firePowerDescriptorResponse(final String nodeID, final short errorCode, final String descriptor) {
+ logger.trace("AbstractGateway::firePowerDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", descriptor=" + descriptor + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.powerDescriptorResponse(nodeID, errorCode, descriptor, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param EPList EndPoint list
+ * @param gtwy Gateway launching notification
+ */
+ protected void fireNodeActiveEPResponse(final String nodeID, final short errorCode, final short[] EPList) {
+ logger.trace("AbstractGateway::fireNodeActiveEPResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", EPList=" + EPList + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.nodeActiveEPResponse(nodeID, errorCode, EPList, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node simple descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param EP EndPoint requested
+ * @param ProfileID
+ * @param DeviceID
+ * @param inClusterList String array containing supported in cluster
+ * @param outClusterList String array containing supported out cluster
+ */
+ protected void fireNodeEndPointSimpleDescriptorResponse(final String nodeID, final short errorCode,
+ final short EP, final String ProfileID, final String DeviceID, final String[] inClusterList, final String[] outClusterList) {
+ logger.trace("AbstractGateway::fireNodeEndPointSimpleDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode
+ + ", EP=" + EP + ", ProfileID=" + ProfileID + ", DeviceID=" + DeviceID + ", inClusterList=" + inClusterList + ", outClusterList=" + outClusterList + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.nodeEndPointSimpleDescriptorResponse(nodeID, errorCode, EP, ProfileID, DeviceID, inClusterList, outClusterList, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node matching a previous descriptor request response
+ * NOTE: profile
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param EPList EndPoint list
+ */
+ protected void fireNodeMatchingDescriptorResponse(final String nodeID, final short errorCode, final short[] EPList) {
+ logger.trace("AbstractGateway::fireNodeMatchingDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", EPList=" + EPList + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.nodeMatchingDescriptorResponse(nodeID, errorCode, EPList, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about and unhandled telegesis command:
+ * - SDATA
+ * - FN0130
+ * - SINK
+ * - ADSK
+ * - dataMODE
+ * - OPEN
+ * - CLOSED
+ * - TRACK
+ * - TRACK2
+ * - PWRCHANGE
+ * - RX
+ * - NM
+ * - ENTERING BLOAD
+ * @param command not handled command
+ * @param parameters command parameters list
+ */
+ protected void fireUnhandledCommand(final String command, final String[] parameters) {
+ logger.trace("AbstractGateway::fireUnhandledCommand(command=" + command + ", parameters=" + parameters + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.unhandledCommand(command, parameters, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about unknonwn incomming messages
+ * @param message
+ */
+ protected void fireUnknownMessage(final String message) {
+ logger.trace("AbstractGateway::fireUnknownMessage(message=" + message + ")");
+ synchronized (gtwyListeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = gtwyListeners.iterator();
+ final Gateway gtwy = this;
+ while (it.hasNext()) {
+ final GatewayListener lstnr = (GatewayListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.unknownMessage(message, gtwy);
+ }
+ };
+ Executor ex = gtwyExecutors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+ // </editor-fold>
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,2305 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.TelegesisErrorException;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.ZigbeeDeviceType;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.*;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.Command305;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.ErrorCode305;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.Prompt305;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.SpecialSequence305;
+import es.unizar.howlab.core.io.serial.SerialConnection;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Class mplementation for a Telegesis Gateway version 305
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class Gateway305 extends AbstractGateway implements Gateway, SerialListener.MessageParser {
+
+ private static final String FIRMWARE_REVISION = "R305";
+ private static final String[] COMPATIBLE_FIRMWARE = new String[]{"R302X", "R303X", "R304X"};
+ private static final int COMMAND_RESPONSE_TIMEOUT = 1000;
+ private static final int RESET_RESPONSE_TIMEOUT = 2000;
+ private static final int FACTORY_RESPONSE_TIMEOUT = 2000;
+ //
+ // Tiempos de bloqueo
+ private static final int SERIAL_PORT_BLOCKING_4_SEC = 4000;
+ private static final int SERIAL_PORT_BLOCKING_10_SEC = 10000;
+ private static final int SERIAL_PORT_BLOCKING_16_SEC = 16000;
+ //
+ // configuraciones por defecto de registros para tráfico de mensajes
+ private static final short S_REG_ADDR_PROMPT_ENABLE_1 = 0x0E;
+ private static final short S_REG_ADDR_PROMPT_ENABLE_2 = 0x0F;
+ private static final short S_REG_ADDR_UART_SETUP = 0x12;
+ private static final short S_REG_BIT_NO_COMMAND_ECHO = 4;
+ private static final String DEFAULT_PROMPT_ENABLE_1 = "8000";
+ private static final String DEFAULT_PROMPT_ENABLE_2 = "0106";
+ //
+ // puerto para comunicar con el gateway
+ private SerialConnection serialPort;
+ private SerialListener spLstnr;
+ private boolean gtwyIsOpen = false;
+ private final String SYNC_COMMAND = "SYNC_COMMAND"; // objeto referencia para exclusión mutua entre operaciones (synchronized(SYNC_COMMAND) { ... })
+ // Logger
+ Log logger = LogFactory.getLog(Gateway305.class.getName());
+
+ public Gateway305(SerialConnection cnx) {
+ logger.trace("Gateway305::Gateway305(cnx=" + cnx + ")");
+ // Guardamos el puerto
+ serialPort = cnx;
+
+ // creamos el listener, pero el registro se debe hacer en el OPEN
+ spLstnr = new SerialListener(this);
+
+ }
+
+ @Override
+ public String toString() {
+ if (serialPort != null) {
+ return String.format("Gateway %s at %s", deviceName, serialPort);
+ } else {
+ return "Uninitialized gateway";
+ }
+ }
+ // <editor-fold defaultstate="collapsed" desc="utilidades de parseo de respuestas">
+
+ @Override
+ public void serialPortError() {
+ logger.trace("Gateway305::serialPortError()");
+ logger.warn("Error accesing physical dongle, closing Gateway");
+ this.close();
+ //TODO: despublicar gateway?
+
+ }
+
+ @Override
+ public void hasNewPromps() {
+ logger.trace("Gateway305::hasNewPromps()");
+ // recuperamos el mensaje
+ String prompt = spLstnr.getNextPrompt();
+ while (prompt != null) {
+ logger.info("Prompt received by gateway: " + prompt);
+ /*
+ * Comprobamos el mensaje recibido, a la vez que lo procesamos. La
+ * función que lo comprueba devuelve true si era un mensaje de ese
+ * tipo, con lo que la utilizamos para procesar y discriminar a la
+ * vez. La estructura de if's anidados procesa los tipos de mensajes
+ * de forma secuencial, por lo que el orden está establecido (o debe
+ * establecerse) para procesar en primer lugar los mensajes más
+ * frecuentes
+ */
+ if (parseACKPrompt(prompt)) { // comprobamos si es un ACK
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseMessageReceivedPrompt(prompt)) { // comprobamos si se trata de un mensaje
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseAddrResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje de ruta
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseEndPointMessagePrompt(prompt)) { // comprobamos si se trata de un mensaje
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseRegisterReadPrompt(prompt)) { // comprobamos si se trata de un registro leido
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseRegisterWritePrompt(prompt)) { // comprobamos si se trata de un registro escrito
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseNodeAnnouncePrompt(prompt)) { // comprobamos si se trata de un anuncio de nodo
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseRouteRecordPrompt(prompt)) { // comprobamos si se trata de un mensaje de ruta
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseNewNodePrompt(prompt)) { // comprobamos si se trata de un nuevo nodo
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseJoinedPanPrompt(prompt)) { // comprobamos si se trata de un mensaje de incorporación a PAN
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseLeftPanPrompt(prompt)) { // comprobamos si se trata de un mensaje de abandono de PAN
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseUnhandledMessagePrompt(prompt)) { // comprobamos si se trata de un mensaje no implementado
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseNeighbourTableResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje de tabla de vecinos
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseNodeDescriptorResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje Node Descriptor
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseNodeEndPointSimpleDescriptorResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje EndPoint Simple Descriptor
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parsePowerDescriptorResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje Power Descriptor
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseNodeMatchingDescriptorResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje Node Matching Descioptor
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else if (parseActiveEndPointsResponsePrompt(prompt)) { // comprobamos si se trata de un mensaje Active End Points
+ // si devuelve TRUE, ha procesado el mensaje, no hay que hacer nada más
+ } else { // se trata de un mensaje desconocido
+ fireUnknownMessage(prompt);
+ }
+
+ // comprobamos si hay mas prompts
+ prompt = spLstnr.getNextPrompt();
+ }
+ }
+
+ /**
+ * Bloquea el puerto contra escritura para recibir respuestas
+ * NOTA: esto se ha definido en una función para asegurar que se ejecuta
+ * siempre de la misma forma
+ * @param milliseconds tiempo máximo de bloqueo del puerto
+ */
+ private void lockPortForResponses(int milliseconds) {
+ logger.trace("Gateway305::lockPortForResponses(milliseconds=" + milliseconds + ")");
+ // bloqueamos el acceso al puerto
+ serialPort.blockWriting(milliseconds);
+ // Marcamos que podemos esperar una respuesta
+ spLstnr.setExpectResponse();
+ }
+
+ /**
+ * Libera el puerto contra escritura, y borra la marca de respuestas
+ */
+ private void unlockPortForResponses() {
+ logger.trace("Gateway305::unlockPortForResponses()");
+ // liberamos el acceso al puerto
+ serialPort.unblockWriting();
+ // Marcamos que ya no esperamos respuesta
+ spLstnr.clearExpectResponse();
+ }
+
+ /**
+ * Comprueba la respuesta recibida, generando excepciones si es null o
+ * ERROR:XX
+ * NOTA: esta función YA es llamada dentro de writeCommand
+ * @param response frame a analizar
+ * @throws TelegesisErrorException
+ */
+ private void checkResponseNullOrErrorAndThrowException(String response) throws TelegesisErrorException {
+ logger.trace("Gateway305::checkResponseNullOrErrorAndThrowException(response=" + response + ")");
+ if (response == null) {
+ unlockPortForResponses();
+ ErrorCode305 errorCode = ErrorCode305.COMMUNICATION_ERROR;
+ throw new TelegesisErrorException(errorCode.toString(), errorCode.getMessage());
+ } else if (response.startsWith(SpecialSequence305.COMMAND_ERROR.getText())) {
+ unlockPortForResponses();
+ String strErrorCode = response.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1];
+ ErrorCode305 errorCode = ErrorCode305.valueOf(ErrorCode305.class, "TELEGESIS_ERROR_" + strErrorCode);
+ throw new TelegesisErrorException(errorCode.name(), errorCode.getMessage());
+ }
+ }
+
+ /**
+ * Obtiene el SEQ Number de una respuesta recibida, o genera la excepcion
+ * correspondiente
+ * @param frame respuesta a analizar
+ * @return numero de secuencia
+ * @throws TelegesisErrorException
+ */
+ private short getSeqNumber(String frame) throws TelegesisErrorException {
+ logger.trace("Gateway305::getSeqNumber(frame=" + frame + ")");
+ // comprobamos SEQ:XX
+ if (frame.startsWith(SpecialSequence305.SEQUENCE_NUMBER.getText())) {
+ String seqNumber = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1];
+ return (short) Integer.parseInt(seqNumber, 16);
+ } else {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), ErrorCode305.BAD_RESPONSE.getMessage());
+ }
+ }
+
+ /**
+ * Procesa un mensaje ACK, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseACKPrompt(String frame) {
+ logger.trace("Gateway305::parseACKPrompt(frame=" + frame + ")");
+ // comprobamos ACK:XX
+ // comprobamos NACK:XX
+ if (frame.startsWith(Prompt305.ACK.getText())
+ || frame.startsWith(Prompt305.NACK.getText())) {
+ String command = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[0];
+ String parameter = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1];
+ short seqNumber = (short) Integer.parseInt(parameter, 16);
+ boolean wasACK = command.equals(Prompt305.ACK.getText());
+ fireAcknowledgement(seqNumber, wasACK);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje ROUTE_RECORD, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseRouteRecordPrompt(String frame) {
+ logger.trace("Gateway305::parseRouteRecordPrompt(frame=" + frame + ")");
+ // comprobamos SR:XX,<EUI64>,<NodeID>,...
+ if (frame.startsWith(Prompt305.ROUTE_RECORD.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ int numHops = Integer.parseInt(parameters[0], 16);
+ String EUI64Addr = parameters[1];
+ String[] route = new String[parameters.length - 2];
+ System.arraycopy(parameters, 2, route, 0, route.length);
+ fireRouteRecordReceived(EUI64Addr, numHops, route);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje broadcast, multicast o unicast, lanzando las
+ * notificaciones correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseMessageReceivedPrompt(String frame) {
+ logger.trace("Gateway305::parseMessageReceivedPrompt(frame=" + frame + ")");
+ // comprobamos BCAST:[<EUI64>,]XX=Data
+ // comprobamos MCAST:[<EUI64>,]XX=Data
+ // comprobamos UCAST:[<EUI64>,]XX=Data
+ if ((frame.startsWith(Prompt305.BROADCAST_RECEIVED.getText()))
+ || frame.startsWith(Prompt305.MULTICAST_RECEIVED.getText())
+ || frame.startsWith(Prompt305.UNICAST_RECEIVED.getText())) {
+ String[] message = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText(), 2);// limitamos el split a 2 para asegurarnos de que no pille un caracter en los datos
+ String command = message[0];
+ String strParam = message[1];
+ // Obtenemos los parámetros y comprobamos para determinar el formato
+ String[] parameters = strParam.split(SpecialSequence305.PARAMETER_SEPARATOR.getText(), 2); // limitamos el split a 2 para asegurarnos de que no pille un caracter en los datos
+ String EUI64Addr;
+ String dataParam;
+ // no podemos basarnos en la longitud para comprobar, ya que podrÃa haber una coma en la posicion 13 de los datos
+ // comprobamos que el parámetro es una cadena hexadecimal válida, ya que en otro caso tendrÃamos por medio un "="
+ if (parameters[0].contains("=")) { // la EUI64Addr no viene en el mensaje
+ EUI64Addr = null;
+ dataParam = strParam;
+ } else {
+ EUI64Addr = parameters[0];
+ dataParam = parameters[1];
+ }
+ String[] dataParams = dataParam.split(SpecialSequence305.DATA_SEPARATOR.getText(), 2); // limitamos el split a 2 para asegurarnos de que no pille un caracter en los datos
+ int dataLengh = Integer.parseInt(dataParams[0], 16); // no se utiliza
+ byte[] data = dataParams[1].getBytes(Charset.forName("ISO-8859-1"));
+ // utilizaremos el comando como tipo de mensaje
+ if (command.equals("BCAST")) {
+ fireBroadcastMessageReceived(EUI64Addr, data);
+ } else {
+ fireMessageReceived(EUI64Addr, data, command);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje RX, lanzando las notificaciones correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseEndPointMessagePrompt(String frame) {
+ logger.trace("Gateway305::parseEndPointMessagePrompt(frame=" + frame + ")");
+ // comprobamos RX:<EUI64>,<NodeID>,<profileID>, <destinationEndpoint>,<SourceEndpoint>,<clusterID>,<length>:<payload>
+ // comprobamos RX:<NodeID>,<profileID>, <destinationEndpoint>,<SourceEndpoint>,<clusterID>,<length>:<payload>
+ if (frame.startsWith(Prompt305.END_POINT_MESSAGE.getText())) {
+ String[] message = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText(), 2);
+ String strParam = message[1];
+ // comprobamos el formato del mensaje, recuperando el primer parámetro
+ String[] parameters;
+ int offset = 0;
+ String EUI64Addr;
+ String firstParam = strParam.split(SpecialSequence305.PARAMETER_SEPARATOR.getText())[0];
+ if (firstParam.length() == 4) { // se trata del NodeID, hay 6 parámetros
+ parameters = strParam.split(SpecialSequence305.PARAMETER_SEPARATOR.getText(), 6);
+ EUI64Addr = null;
+ } else { // se trata de la EUI64Addr, hay 7 parámetros
+ parameters = strParam.split(SpecialSequence305.PARAMETER_SEPARATOR.getText(), 7);
+ EUI64Addr = parameters[0];
+ offset = 1;
+ }
+ String nodeID = parameters[offset];
+ String profileID = parameters[offset + 1];
+ short destEP = (short) Integer.parseInt(parameters[offset + 2], 16);
+ short sourceEP = (short) Integer.parseInt(parameters[offset + 3], 16);
+ String clusterID = parameters[offset + 4];
+ String[] payload = parameters[offset + 5].split(SpecialSequence305.COMMAND_SEPARATOR.getText(), 2);
+ int dataLengh = Integer.parseInt(payload[0], 16); // no se utiliza
+ byte[] data = payload[1].getBytes(Charset.forName("ISO-8859-1"));
+ fireMessageReceived(EUI64Addr, nodeID, sourceEP, destEP, profileID, clusterID, data);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de anuncio de nodo, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseNodeAnnouncePrompt(String frame) {
+ logger.trace("Gateway305::parseNodeAnnouncePrompt(frame=" + frame + ")");
+ // comprobamos COO:<EUI64>,<NodeID>
+ // comprobamos FFD:<EUI64>,<NodeID>
+ // comprobamos ZED:<EUI64>,<NodeID>
+ // comprobamos MED:<EUI64>,<NodeID>
+ // comprobamos SED:<EUI64>,<NodeID>
+ if ((frame.startsWith(Prompt305.COO_ANNOUNCE.getText()))
+ || frame.startsWith(Prompt305.FFD_ANNOUNCE.getText())
+ || frame.startsWith(Prompt305.ZED_ANNOUNCE.getText())
+ || frame.startsWith(Prompt305.MED_ANNOUNCE.getText())
+ || frame.startsWith(Prompt305.SED_ANNOUNCE.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String EUI64Addr = parameters[0];
+ String nodeID = parameters[1];
+ int RSSI = 0;
+ short LQI = 0;
+ if (parameters.length == 4) {
+ RSSI = Integer.parseInt(parameters[2]);
+ LQI = (short) Integer.parseInt(parameters[3], 16);
+ }
+ ZigbeeDeviceType type = getTypeFromPrompt(frame);
+ fireNodeAnnounce(type, EUI64Addr, nodeID, RSSI, LQI);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de anuncio de nodo, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseNewNodePrompt(String frame) {
+ logger.trace("Gateway305::parseNewNodePrompt(frame=" + frame + ")");
+ // comprobamos NEWNODE:<NodeID>,<EUI64>,<Parent NodeId>,
+ if (frame.startsWith(Prompt305.NEWNODE_ANNOUNCE.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeID = parameters[0];
+ String EUI64Addr = parameters[1];
+ String parentID = parameters[2];
+ fireNewNode(EUI64Addr, nodeID, parentID);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de abandono de PAN, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseLeftPanPrompt(String frame) {
+ logger.trace("Gateway305::parseLeftPanPrompt(frame=" + frame + ")");
+ // comprobamos LeftJPAN
+ // comprobamos LostJPAN
+ if (frame.startsWith(Prompt305.LEFT_PAN.getText())
+ || frame.startsWith(Prompt305.LOST_PAN.getText())) {
+ fireLeftPAN();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de incorporación a PAN, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseJoinedPanPrompt(String frame) {
+ logger.trace("Gateway305::parseJoinedPanPrompt(frame=" + frame + ")");
+ // comprobamos JPAN:<channel>,<PID>,<EPID>
+ if (frame.startsWith(Prompt305.JOIN_PAN.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ int channel = Integer.parseInt(parameters[0]);
+ String PID = parameters[1];
+ String EPID = parameters[2];
+ fireJoinedPan(channel, PID, EPID);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de lectura de registro, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseRegisterReadPrompt(String frame) {
+ logger.trace("Gateway305::parseRegisterReadPrompt(frame=" + frame + ")");
+ // comprobamos SREAD:<NodeID>,<EUI64>,<Register>,<errorcode>[=<Data>]
+ if (frame.startsWith(Prompt305.REGISTER_READ.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = parameters[0];
+ String EUI64Addr = parameters[1];
+ short register = (short) Integer.parseInt(parameters[2], 16);
+ String[] errorAndData = parameters[3].split(SpecialSequence305.DATA_SEPARATOR.getText());
+ short errorCode = (short) Integer.parseInt(errorAndData[0], 16);
+ String data = (errorAndData.length == 2 ? errorAndData[1] : null);
+ fireRegisterReaded(nodeId, EUI64Addr, register, errorCode, data);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de escritura de registro, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseRegisterWritePrompt(String frame) {
+ logger.trace("Gateway305::parseRegisterWritePrompt(frame=" + frame + ")");
+ // comprobamos SWRITE:<NodeID>,<EUI64>,<errorcode>
+ if (frame.startsWith(Prompt305.REGISTER_WRITE.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = parameters[0];
+ String EUI64Addr = parameters[1];
+ short errorCode = (short) Integer.parseInt(parameters[2], 16);
+ fireRegisterWrited(nodeId, EUI64Addr, errorCode);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de respuesta desde direccion, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseAddrResponsePrompt(String frame) {
+ logger.trace("Gateway305::parseAddrResponsePrompt(frame=" + frame + ")");
+ // comprobamos AddrResp:<errorcode>[,<NodeID>,<EUI64>]
+ if (frame.startsWith(Prompt305.ADDR_RESPONSE.getText())) {
+ String[] parameters = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ short errorCode = (short) Integer.parseInt(parameters[0], 16);
+ String nodeId = (parameters.length == 3 ? parameters[1] : null);
+ String EUI64Addr = (parameters.length == 3 ? parameters[2] : null);
+ fireAddrResponse(errorCode, nodeId, EUI64Addr);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de tabla de vecinos, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseNeighbourTableResponsePrompt(String frame) {
+ logger.trace("Gateway305::parseNeighbourTableResponsePrompt(frame=" + frame + ")");
+ // comprobamos:
+ //[0]NTable:<NodeID>,<errorcode>
+ //[1]Length:03
+ //[2]No.| Type | EUI | ID | LQI
+ //[3]00.| FFD | 000D6F000015896B | BC04 | FF
+ //[4]01.| FFD | 000D6F00000B3E77 | 739D | FF
+ //[5]02.| FFD | 000D6F00000AAD11 | 75E3 | FF
+ if (frame.startsWith(Prompt305.NEIGHBOUR_TABLE_RESPONSE.getText())) {
+ // separamos el comando en lÃneas:
+ String[] lines = frame.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ // analizamos la primera linea
+ String[] params = lines[0].split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = params[0];
+ short errorCode = (short) Integer.parseInt(params[1], 16);
+ // continuamos analizando el mensaje
+ int tableLength = 0;
+ NeighbourTableEntry[] nTable = null;
+ if (errorCode == 0) {
+ tableLength = Integer.parseInt(lines[1].split(":")[1]);
+ int numRecords = lines.length - 3;
+ /* Se ha detectado este tipo de respuesta:
+ [0]NTable:<NodeID>,<errorcode>
+ [1]Length:02
+ ==> esto hará que numRecords sea negativo, con lo que saltará una excepción
+ El caso numRecords = 0 también es anormal
+ */
+ if (numRecords <= 0) {
+ logger.warn(String.format("[Gateway] Received malformed NTable response: %s ", frame));
+ // respondemos TRUE, pero no lanzamos el evento
+ return true;
+ }
+ nTable = new NeighbourTableEntry[numRecords];
+ for (int i = 3; i < lines.length; i++) {
+ String line = lines[i].replace("|", ",");
+ String[] record = line.split(",");
+ short index = (short) Integer.parseInt(record[0].substring(0, 2));
+ ZigbeeDeviceType type = getTypeFromPrompt(record[1].trim());
+ String EUI64Addr = record[2].trim();
+ String nodeID = record[3].trim();
+ short LQI = (short) Integer.parseInt(record[4].trim(), 16);
+ nTable[i - 3] = new NeighbourTableEntry(index, type, EUI64Addr, nodeID, LQI);
+ }
+
+ }
+ fireNeighbourTableResponse(nodeId, errorCode, tableLength, nTable);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje Node Descriptor, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseNodeDescriptorResponsePrompt(String frame) {
+ logger.trace("Gateway305::parseNodeDescriptorResponsePrompt(frame=" + frame + ")");
+ // comprobamos:
+ //[0]NodeDesc:<NodeID>,<errorcode>
+ //[1]NodeDesc:0D57
+ //[2]Type:FFD
+ //[3]ComplexDesc:No
+ //[4]UserDesc:No
+ //[5]APSFlags:00
+ //[6]FreqBand:40
+ //[7]MacCap:8E
+ //[8]ManufCode:1010
+ //[9]MaxBufSize:52
+ //[.]MaxInSize:0080
+ //[.]SrvMask:0000
+ //[.]MaxOutSize:0080
+ //[.]DescCap:00
+ if (frame.startsWith(Prompt305.NODE_DESC_RESPONSE.getText())) {
+ // separamos el comando en lÃneas:
+ String[] lines = frame.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ // analizamos la primera linea
+ String[] params = lines[0].split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = params[0];
+ short errorCode = (short) Integer.parseInt(params[1], 16);
+ // continuamos analizando el mensaje
+ Map descriptor = new HashMap();
+ for (int i = 1; i < lines.length; i++) {
+ String[] record = lines[i].split(":");
+ descriptor.put(record[0], record[1]);
+ }
+ fireNodeDescriptorResponse(nodeId, errorCode, descriptor);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje Power Descriptor, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parsePowerDescriptorResponsePrompt(String frame) {
+ logger.trace("Gateway305::parsePowerDescriptorResponsePrompt(frame=" + frame + ")");
+ // comprobamos:
+ //PowerDesc:<NodeID>,<errorcode>[,<PowerDescriptor>]
+ if (frame.startsWith(Prompt305.POWER_DESC_RESPONSE.getText())) {
+ // obtenemos parámetros
+ String[] params = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = params[0];
+ short errorCode = (short) Integer.parseInt(params[1], 16);
+ // continuamos analizando el mensaje
+ String descriptor = (params.length == 3 ? params[2] : null);
+ firePowerDescriptorResponse(nodeId, errorCode, descriptor);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje Active EndPoint List, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseActiveEndPointsResponsePrompt(String frame) {
+ logger.trace("Gateway305::parseActiveEndPointsResponsePrompt(frame=" + frame + ")");
+ // comprobamos:
+ //ActEpDesc:<NodeID>,<errorcode>[,XX,...]
+ if (frame.startsWith(Prompt305.ACTIVE_EP_RESPONSE.getText())) {
+ // obtenemos parámetros
+ String[] params = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = params[0];
+ short errorCode = (short) Integer.parseInt(params[1], 16);
+ // continuamos analizando el mensaje
+ int numEPs;
+ short[] EPList;
+ if (errorCode == (short) 0) {
+ numEPs = params.length - 2;
+ EPList = new short[numEPs];
+ for (int i = 2; i < params.length; i++) {
+ EPList[i - 2] = (short) Integer.parseInt(params[i], 16);
+ }
+ } else {
+ numEPs = 0;
+ EPList = null;
+
+ }
+ fireNodeActiveEPResponse(nodeId, errorCode, EPList);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje Node EndPoint Simple Descriptor, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseNodeEndPointSimpleDescriptorResponsePrompt(String frame) {
+ logger.trace("Gateway305::parseNodeEndPointSimpleDescriptorResponsePrompt(frame=" + frame + ")");
+ // comprobamos:
+ //[0]SimpleDesc:<NodeID>,<errorcode>
+ //[1]EP:XX
+ //[2]ProfileID:XXXX
+ //[3]DeviceID:XXXXvXX
+ //[4]InCluster:<Cluster List>
+ //[5]OutCluster:<Cluster List>
+ if (frame.startsWith(Prompt305.EP_SIMPLE_DESC_RESPONSE.getText())) {
+ // separamos el comando en lÃneas:
+ String[] lines = frame.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ // analizamos la primera linea
+ String[] params = lines[0].split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = params[0];
+ short errorCode = (short) Integer.parseInt(params[1], 16);
+ // continuamos analizando el mensaje
+ short EP = (short) Integer.parseInt(lines[1].split(":")[1]);
+ String[] arrProfileID = (lines.length == 1 ? null : lines[2].split(":"));
+ String[] arrDeviceID = (lines.length == 1 ? null : lines[3].split(":"));
+ String[] arrInClusterList = (lines.length == 1 ? null : lines[4].split(":"));
+ String[] arrOutClusterList = (lines.length == 1 ? null : lines[5].split(":"));
+ String profileID = (arrProfileID.length == 1 ? null : arrProfileID[1]);
+ String deviceID = (arrDeviceID.length == 1 ? null : arrDeviceID[1]);
+ String[] inCluster = (arrInClusterList.length == 1 ? null : arrInClusterList[1].split(","));
+ String[] outCluster = (arrOutClusterList.length == 1 ? null : arrOutClusterList[1].split(","));
+
+// String inClusterList = (lines.length == 1 ? null : lines[4].split(":")[1]);
+// String outClusterList = (lines.length == 1 ? null : lines[5].split(":")[1]);
+// String[] inCluster = (inClusterList == null ? null : inClusterList.split(","));
+// String[] outCluster = (outClusterList == null ? null : outClusterList.split(","));
+ fireNodeEndPointSimpleDescriptorResponse(nodeId, errorCode, EP, profileID, deviceID, inCluster, outCluster);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje Active EndPoint List, lanzando las notificaciones
+ * correspondientes
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseNodeMatchingDescriptorResponsePrompt(String frame) {
+ logger.trace("Gateway305::parseNodeMatchingDescriptorResponsePrompt(frame=" + frame + ")");
+ // comprobamos:
+ //MatchDesc:<NodeID>,<errorcode>,XX,...
+ if (frame.startsWith(Prompt305.NODES_MATCH_DESC_RESPONSE.getText())) {
+ // obtenemos parámetros
+ String[] params = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText())[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ String nodeId = params[0];
+ short errorCode = (short) Integer.parseInt(params[1], 16);
+ // continuamos analizando el mensaje
+ int numEPs = params.length - 2;
+ short[] EPList = new short[numEPs];
+ for (int i = 2; i < params.length; i++) {
+ EPList[i - 2] = (short) Integer.parseInt(params[i], 16);
+ }
+ fireNodeMatchingDescriptorResponse(nodeId, errorCode, EPList);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Procesa un mensaje de respuesta no procesada, lanzando las notificaciones
+ * correspondientes
+ * - SDATA
+ * - FN0130
+ * - SINK
+ * - ADSK
+ * - DataMODE
+ * - OPEN
+ * - CLOSED
+ * - TRACK
+ * - TRACK2
+ * - PWRCHANGE
+ * - RX
+ * - NM
+ * - ENTERING BLOAD
+ * @param frame mensaje a analizar
+ * @return TRUE si efectivamente es un mensaje válido, FALSE en otro caso
+ */
+ private boolean parseUnhandledMessagePrompt(String frame) {
+ logger.trace("Gateway305::parseUnhandledMessagePrompt(frame=" + frame + ")");
+ // comprobamos mensajes
+ if (frame.startsWith(Prompt305.SINK_DATA_MESSAGE.getText())
+ || frame.startsWith(Prompt305.SINK_DATA_MESSAGE_FN0130.getText())
+ || frame.startsWith(Prompt305.SINK_ANNOUCE.getText())
+ || frame.startsWith(Prompt305.SINK_SELECTED.getText())
+ || frame.startsWith(Prompt305.DATA_MODE.getText())
+ || frame.startsWith(Prompt305.DATA_MODE_OPEN.getText())
+ || frame.startsWith(Prompt305.DATA_MODE_CLOSED.getText())
+ || frame.startsWith(Prompt305.TRACKING_MESSAGE.getText())
+ || frame.startsWith(Prompt305.TRACKING_MESSAGE_2.getText())
+ || frame.startsWith(Prompt305.POWER_CHANGE.getText())
+ || frame.startsWith(Prompt305.REPORT_WARNING.getText())
+ || frame.startsWith(Prompt305.ENTERING_BOOTLOAD.getText())) {
+ String[] frameSpplited = frame.split(SpecialSequence305.COMMAND_SEPARATOR.getText());
+ String command = frameSpplited[0];
+ String[] parameters;
+ if (frameSpplited.length == 2) {
+ parameters = frameSpplited[1].split(SpecialSequence305.PARAMETER_SEPARATOR.getText());
+ } else {
+ parameters = new String[0];
+ }
+ fireUnhandledCommand(command, parameters);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // </editor-fold>
+ // <editor-fold defaultstate="collapsed" desc="Operaciones del Gateway">
+ @Override
+ public String[] getProductId() {
+ logger.trace("Gateway305::getProductId()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISPLAY_PRODUCT_IDENTIFICATION.getText();
+
+ // Enviamos el mensaje
+ String response = null;
+ try {
+ response = writeCommand(cmd);
+ return response.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ } catch (TelegesisErrorException ex) {
+ // lanzamos un warning
+ logger.warn("Gateway305::getProductId(): ERROR", ex);
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public void reset() {
+ logger.trace("Gateway305::reset()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SOFTWARE_RESET.getText();
+
+// // Enviamos directamente el comando por el puerto serie, sin esperar respuesta ni bloquear puerto
+// serialPort.writeString(cmd + SpecialSequence305.CMD_END.getText());
+ // Enviamos el mensaje
+ String response = null;
+ try {
+ response = writeCommand(cmd, RESET_RESPONSE_TIMEOUT);
+ // deberÃa ser OK, no la comprobamos
+ if (!response.equals(SpecialSequence305.COMMAND_OK.getText())) {
+ // lanzamos un warning
+ logger.warn(String.format("Gateway305::reset(): ERROR (unexpected response: %s)", response));
+ }
+ } catch (TelegesisErrorException ex) {
+ // lanzamos un warning
+ logger.warn("Gateway305::reset(): ERROR", ex);
+ }
+
+ }
+ }
+
+ @Override
+ public void restoreFactoryDefaults() {
+ logger.trace("Gateway305::restoreFactoryDefaults()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.RESTORE_FACTORY_DEFAULTS.getText();
+
+// // Enviamos directamente el comando por el puerto serie, sin esperar respuesta ni bloquear puerto
+// serialPort.writeString(cmd + SpecialSequence305.CMD_END.getText());
+ // Enviamos el mensaje
+ String response = null;
+ try {
+ response = writeCommand(cmd, FACTORY_RESPONSE_TIMEOUT);
+ // deberÃa ser OK, no la comprobamos
+ if (!response.equals(SpecialSequence305.COMMAND_OK.getText())) {
+ // lanzamos un warning
+ logger.warn(String.format("Gateway305::restoreFactoryDefaults(): ERROR (unexpected response: %s)", response));
+ } else {
+ // inicializamos la comunicacion
+ if (!init()) {
+ logger.warn("Gateway305::restoreFactoryDefaults(): ERROR re-initializiong dongle");
+
+ }
+
+ }
+ } catch (TelegesisErrorException ex) {
+ // lanzamos un warning
+ logger.warn("Gateway305::restoreFactoryDefaults(): ERROR", ex);
+ }
+
+ }
+ }
+
+ @Override
+ public String readRegister(short regAddress) throws TelegesisErrorException {
+ logger.trace("Gateway305::readRegister(regAddress=" + regAddress + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ // componemos mensaje
+ String cmd = Command305.S_REGISTER_ACCESS.getText()
+ + register
+ + SpecialSequence305.REGISTER_QUERY.getText();
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ return response;
+
+ }
+ }
+
+ @Override
+ public boolean readRegisterBit(short regAddress, short bitNumber) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRegisterBit(regAddress=" + regAddress + ", bitNumber=" + bitNumber + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ String bit = String.format("%02X", bitNumber);
+ // componemos mensaje
+ String cmd = Command305.S_REGISTER_ACCESS.getText()
+ + register + bit
+ + SpecialSequence305.REGISTER_QUERY.getText();
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ if (response.equals("0")) {
+ return false;
+ } else if (response.equals("1")) {
+ return true;
+ } else {
+ ErrorCode305 errorCode = ErrorCode305.BAD_RESPONSE;
+ throw new TelegesisErrorException(errorCode.name(), errorCode.getMessage());
+ }
+
+ }
+
+ }
+
+ @Override
+ public void writeRegister(short regAddress, String regData) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRegister(regAddress=" + regAddress + ", regData=" + regData + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ // componemos mensaje
+ String cmd = Command305.S_REGISTER_ACCESS.getText()
+ + register
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + regData;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+
+ }
+ }
+
+ @Override
+ public void writeRegisterBit(short regAddress, short bitNumber, boolean bitData) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRegisterBit(regAddress=" + regAddress + ", bitNumber=" + bitNumber + ", bitData=" + bitData + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ String bit = String.format("%02X", bitNumber);
+ String bitValue = (bitData ? "1" : "0");
+ // componemos mensaje
+ String cmd = Command305.S_REGISTER_ACCESS.getText()
+ + register + bit
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + bitValue;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+
+ }
+ }
+
+ @Override
+ public void writeRegister(short regAddress, String regData, String password) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRegister(regAddress=" + regAddress + ", regData=" + regData + ", password=" + password + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ // componemos mensaje
+ String cmd = Command305.S_REGISTER_ACCESS.getText()
+ + register
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + regData
+ + SpecialSequence305.PASSWORD_SEPARATOR.getText()
+ + password;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void writeRegisterBit(short regAddress, short bitNumber, boolean bitData, String password) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRegisterBit(regAddress=" + regAddress + ", bitNumber=" + bitNumber + ", bitData=" + bitData + ", password=" + password + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ String bit = String.format("%02X", bitNumber);
+ String bitValue = (bitData ? "1" : "0");
+ // componemos mensaje
+ String cmd = Command305.S_REGISTER_ACCESS.getText()
+ + register + bit
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + bitValue
+ + SpecialSequence305.PASSWORD_SEPARATOR.getText()
+ + password;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+
+ }
+ }
+
+ @Override
+ public short readRemoteRegisterRequest(String EUI64Addr, short regAddress) throws TelegesisErrorException {
+ logger.trace("Gateway305::readRemoteRegisterRequest(EUI64Addr=" + EUI64Addr + ", regAddress=" + regAddress + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ // componemos mensaje
+ String cmd = Command305.REMOTE_S_REGISTER_ACCESS.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + EUI64Addr
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + register
+ + SpecialSequence305.REGISTER_QUERY.getText();
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+
+ }
+ }
+
+ @Override
+ public short readRemoteRegisterBitRequest(String EUI64Addr, short regAddress, short bitNumber) throws TelegesisErrorException {
+ logger.trace("Gateway305::readRemoteRegisterBitRequest(EUI64Addr=" + EUI64Addr + ", regAddress=" + regAddress + ", bitNumber=" + bitNumber + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ String bit = String.format("%02X", bitNumber);
+ // componemos mensaje
+ String cmd = Command305.REMOTE_S_REGISTER_ACCESS.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + EUI64Addr
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + register + bit
+ + SpecialSequence305.REGISTER_QUERY.getText();
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+
+ }
+ }
+
+ @Override
+ public short writeRemoteRegisterRequest(String EUI64Addr, short regAddress, String regData) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRemoteRegisterRequest(EUI64Addr=" + EUI64Addr + ", regAddress=" + regAddress + ", regData=" + regData + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ // componemos mensaje
+ String cmd = Command305.REMOTE_S_REGISTER_ACCESS.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + EUI64Addr
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + register
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + regData;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+
+ }
+ }
+
+ @Override
+ public short writeRemoteRegisterBitRequest(String EUI64Addr, short regAddress, short bitNumber, boolean bitData) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRemoteRegisterBitRequest(EUI64Addr=" + EUI64Addr + ", regAddress=" + regAddress + ", bitNumber=" + bitNumber + ", bitData=" + bitData + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ String bit = String.format("%02X", bitNumber);
+ String bitValue = (bitData ? "1" : "0");
+ // componemos mensaje
+ String cmd = Command305.REMOTE_S_REGISTER_ACCESS.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + EUI64Addr
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + register + bit
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + bitValue;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+
+ }
+ }
+
+ @Override
+ public short writeRemoteRegisterRequest(String EUI64Addr, short regAddress, String regData, String password) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRemoteRegisterRequest(EUI64Addr=" + EUI64Addr + ", regAddress=" + regAddress + ", regData=" + regData + ", password=" + password + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ // componemos mensaje
+ String cmd = Command305.REMOTE_S_REGISTER_ACCESS.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + EUI64Addr
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + register
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + regData
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + password;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+
+ }
+ }
+
+ @Override
+ public short writeRemoteRegisterBitRequest(String EUI64Addr, short regAddress, short bitNumber, boolean bitData, String password) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeRemoteRegisterBitRequest(EUI64Addr=" + EUI64Addr + ", regAddress=" + regAddress + ", bitNumber=" + bitNumber + ", bitData=" + bitData + ", password=" + password + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // obtenemos el registro
+ String register = String.format("%02X", regAddress);
+ String bit = String.format("%02X", bitNumber);
+ String bitValue = (bitData ? "1" : "0");
+ // componemos mensaje
+ String cmd = Command305.REMOTE_S_REGISTER_ACCESS.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + EUI64Addr
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + register + bit
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + bitValue
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + password;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+
+ }
+ }
+
+ @Override
+ public short[] scanEnergy() throws TelegesisErrorException {
+ logger.trace("Gateway305::scanEnergy()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SCAN_THE_ENERGY_OF_ALL_CHANNELS.getText();
+
+ // enviamos el mensaje, esperando respuesta durante 16 segundos
+ String response = writeCommand(cmd, SERIAL_PORT_BLOCKING_16_SEC); //throws TelegesisErrorException if null or ERROR:XX
+
+ // analizamos la respuesta
+ if (response.startsWith("+ESCAN")) {
+ String[] channels = response.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ short[] energy = new short[16]; //Nota: el scan no tiene por que devolver los 16 canales
+ for (int i = 1; i < channels.length; i++) {
+ String[] strChannel = channels[i].split(":");
+ int channelId = Integer.parseInt(strChannel[0]) - 11; // los canales empiezan a contar en 11
+ energy[channelId] = (short) Integer.parseInt(strChannel[1], 16);
+ }
+ return energy;
+ } else {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public PANScanResult[] scanForActivePANs() throws TelegesisErrorException {
+ logger.trace("Gateway305::scanForActivePANs()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SCAN_FOR_ACTIVE_PANS.getText();
+
+ // bloqueamos la escritura para recibir respuestas durante 4 segundos
+ lockPortForResponses(SERIAL_PORT_BLOCKING_4_SEC);
+
+ //Enviamos el comando directamente por el puerto serie
+ serialPort.writeString(cmd + SpecialSequence305.CMD_END.getText());
+
+ boolean scanEnd = false;
+ ArrayList<PANScanResult> scanResult = new ArrayList<PANScanResult>();
+ while (!scanEnd) {
+ // recuperamos la respuesta
+ String scanResponse = spLstnr.waitForNextResponse(SERIAL_PORT_BLOCKING_4_SEC);
+ checkResponseNullOrErrorAndThrowException(scanResponse);
+ // analizamos la respuesta
+ if (scanResponse.startsWith(SpecialSequence305.COMMAND_OK.getText())) {
+ // hemos finalizado el scan
+ scanEnd = true;
+ } else if (scanResponse.startsWith("+PANSCAN")) {
+ String[] scanRecord = scanResponse.split(":")[1].split(",");
+ int channel = Integer.parseInt(scanRecord[0]);
+ String PANID = scanRecord[1];
+ String EPID = scanRecord[2];
+ short profile = (short) Integer.parseInt(scanRecord[3], 16);
+ boolean permitJoin = scanRecord[4].equals("01") ? true : false;
+ PANScanResult psr = new PANScanResult(channel, PANID, EPID, profile, permitJoin);
+ scanResult.add(psr);
+ } else {
+ unlockPortForResponses();
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), scanResponse);
+ }
+ }
+ // liberamos el puerto
+ unlockPortForResponses();
+
+ // devolvemos resultados
+ return scanResult.toArray(new PANScanResult[0]);
+
+ }
+ }
+
+ @Override
+ public NetworkJoinedInfo createNetwork() throws TelegesisErrorException {
+ logger.trace("Gateway305::createNetwork()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.ESTABLISH_PERSONAL_AREA_NETWORK.getText();
+ // lanzamos la ejecucion
+ return executeNetworkJoinCommand(cmd, SERIAL_PORT_BLOCKING_16_SEC);
+ }
+ }
+
+ @Override
+ public NetworkJoinedInfo joinNetwork() throws TelegesisErrorException {
+ logger.trace("Gateway305::joinNetwork()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.JOIN_NETWORK.getText();
+ // lanzamos la ejecucion
+ return executeNetworkJoinCommand(cmd, SERIAL_PORT_BLOCKING_4_SEC);
+ }
+ }
+
+ @Override
+ public NetworkJoinedInfo joinNetwork(int channel, String PID) throws TelegesisErrorException {
+ logger.trace("Gateway305::joinNetwork(channel=" + channel + ", PID=" + PID + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.JOIN_SPECIFIC_PAN.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02d", channel)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + PID;
+ // lanzamos la ejecucion
+ return executeNetworkJoinCommand(cmd, SERIAL_PORT_BLOCKING_4_SEC);
+ }
+ }
+
+ /**
+ * Procesamiento comun para comandos:
+ * ESTABLISH_PERSONAL_AREA_NETWORK
+ * JOIN_NETWORK
+ * JOIN_SPECIFIC_PAN
+ * @param cmd comando a ejecutar
+ * @param blockingTime tiempo de bloqueo de puerto
+ * @return resultado de la operacion de red
+ * @throws TelegesisErrorException si ocurre algún error
+ */
+ private NetworkJoinedInfo executeNetworkJoinCommand(String cmd, int blockingTime) throws TelegesisErrorException {
+ logger.trace("Gateway305::executeNetworkJoinCommand(cmd=" + cmd + ", blockingTime=" + blockingTime + ")");
+ // bloqueamos la escritura en el puerto para recibir repsuestas, y
+ // marcamos que JPAN debe considerarse como respuesta
+ lockPortForResponses(blockingTime);
+ spLstnr.capturePromptAsResponse("JPAN");
+
+ //Enviamos el comando directamente por el puerto serie
+ serialPort.writeString(cmd + SpecialSequence305.CMD_END.getText());
+
+ // recuperamos las respuestas (JPAN,OK)
+ String jpanResponse = spLstnr.waitForNextResponse(blockingTime);
+
+ // analizamos la respuesta
+ checkResponseNullOrErrorAndThrowException(jpanResponse);
+ NetworkJoinedInfo nji = null;
+ boolean unexpectedResponse = false;
+
+ if (jpanResponse.startsWith("JPAN")) {
+ // analizamos resultado
+ String[] jpanRecord = jpanResponse.split(":")[1].split(",");
+ int channel = Integer.parseInt(jpanRecord[0]);
+ String PANID = jpanRecord[1];
+ String EPID = jpanRecord[2];
+ nji = new NetworkJoinedInfo(channel, PANID, EPID);
+
+ // recuperamos la siguiente respuesta (debe ser OK)
+ jpanResponse = spLstnr.getNextResponse();
+ checkResponseNullOrErrorAndThrowException(jpanResponse);
+ if (!jpanResponse.equals(SpecialSequence305.COMMAND_OK.getText())) { // respuesta inesperada!!!
+ unexpectedResponse = true;
+ }
+ } else { // respuesta inesperada!!!
+ unexpectedResponse = true;
+ }
+
+ // liberamos puerto
+ unlockPortForResponses();
+ spLstnr.clearExpectedPrompts();
+ if (unexpectedResponse) {
+ //hacemos log de la respuesta
+ TelegesisErrorException tee = new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), jpanResponse);
+ logger.warn("Gateway305::executeNetworkJoinCommand: ERROR", tee);
+ return null;
+ } else {
+ return nji;
+ }
+
+ }
+
+ @Override
+ public void leaveNetwork() throws TelegesisErrorException {
+ logger.trace("Gateway305::leaveNetwork()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISASSOCIATE_LOCAL_DEVICE_FROM_PAN.getText();
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public short leaveNetworkRequest(String address) throws TelegesisErrorException {
+ logger.trace("Gateway305::leaveNetworkRequest(address=" + address + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISASSOCIATE_REMOTE_NODE_FROM_PAN.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public NetworkInformation getNetworkInformation() {
+ logger.trace("Gateway305::getNetworkInformation()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISPLAY_NETWORK_INFORMATION.getText();
+ // enviamos el mensaje, esperando respuesta
+ String response = null;
+ try {
+ response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ } catch (TelegesisErrorException ex) {
+ return null;
+ }
+
+ // analizamos la respuesta
+ if (response.startsWith("+N")) {
+ // analizamos resultado
+ String[] niRecord = response.split("=")[1].split(",");
+ if (niRecord[0].equalsIgnoreCase("NoPAN")) {
+ //no hay red formada, devolvemos null
+ return null;
+ } else {
+ ZigbeeDeviceType devType = getTypeFromPrompt(niRecord[0]);
+ int channel = Integer.parseInt(niRecord[1]);
+ short power = (short) Integer.parseInt(niRecord[2], 16);
+ String PID = niRecord[3];
+ String EPID = niRecord[4];
+
+ return new NetworkInformation(devType, channel, power, PID, EPID);
+ }
+ } else {
+ // respuesta inesperada
+ //TODO: hacer log del error
+ return null;
+ }
+
+ }
+ }
+
+ @Override
+ public short requestNeighbourTable(short index, String address) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNeighbourTable(index=" + index + ", address=" + address + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISPLAY_NEIGHBOUR_TABLE.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02X", index)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + address;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public void requestNodeId(String address) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNodeId(address=" + address + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.REQUEST_NODEID.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address;
+ // enviamos el mensaje, esperando la respuesta (pero no hacemos nada con ella
+ writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ }
+ }
+
+ @Override
+ public short requestNodeEUI64Addr(String address, String nodeId) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNodeEUI64Addr(address=" + address + ", nodeId=" + nodeId + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.REQUEST_EUI.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + nodeId;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public short requestNodeDescriptor(String address, String nodeId) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNodeDescriptor(address=" + address + ", nodeId=" + nodeId + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.REQUEST_NODE_DESCRIPTOR.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + nodeId;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public short requestNodePowerDescriptor(String address, String nodeId) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNodePowerDescriptor(address=" + address + ", nodeId=" + nodeId + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.REQUEST_NODE_POWER_DESCRIPTOR.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + nodeId;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public short requestNodeActiveEndPoints(String address, String nodeId) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNodeActiveEndPoints(address=" + address + ", nodeId=" + nodeId + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.REQUEST_NODE_ACTIVE_ENDPOINT_LIST.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + nodeId;
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public short requestNodeEndPointSimpleDescriptor(String address, String nodeId, short EP) throws TelegesisErrorException {
+ logger.trace("Gateway305::requestNodeEndPointSimpleDescriptor(address=" + address + ", nodeId=" + nodeId + ", EP=" + EP + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.REQUEST_ENDPOINT_SIMPLE_DESCRIPTOR.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + nodeId
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + String.format("%02X", EP);
+ // enviamos el mensaje, esperando la respuesta
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+
+ //devolvemos el seq Number
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public void findNodesMatchingDescriptor(String profileId, String[] inClusterList, String[] outClusterList) throws TelegesisErrorException {
+ logger.trace("Gateway305::findNodesMatchingDescriptor(profileId=" + profileId + ", inClusterList=" + inClusterList + ", outClusterList=" + outClusterList + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.FIND_NODES_WHICH_MATCH_A_SPECIFIC_DESCRIPTOR.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + profileId
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText();
+ // añadimos inClusterList
+ cmd += String.format("%02d", inClusterList.length);
+ for (int i = 0; i < inClusterList.length; i++) {
+ cmd += SpecialSequence305.PARAMETER_SEPARATOR.getText() + inClusterList[i];
+ }
+ // añadimos outClusterList
+ cmd += SpecialSequence305.PARAMETER_SEPARATOR.getText() + String.format("%02d", outClusterList.length);
+ for (int i = 0; i < outClusterList.length; i++) {
+ cmd += SpecialSequence305.PARAMETER_SEPARATOR.getText() + outClusterList[i];
+ }
+
+ // enviamos el mensaje, esperando la respuesta, pero no hacemos nada con ella
+ writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ }
+ }
+
+ @Override
+ public void annouceLocalNode() throws TelegesisErrorException {
+ logger.trace("Gateway305::annouceLocalNode()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.ANNOUNCE_LOCAL_DEVICE_IN_THE_NETWORK.getText();
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void setSourceRoute(String destNode, String[] route) throws TelegesisErrorException {
+ logger.trace("Gateway305::setSourceRoute(destNode=" + destNode + ", route=" + route + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SET_SOURCE_ROUTE_TO_REMOTE_DEVICE.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + destNode;
+ for (int i = 0; i < route.length; i++) {
+ cmd += SpecialSequence305.PARAMETER_SEPARATOR.getText() + route[i];
+ }
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+
+ }
+ }
+
+ @Override
+ public void findRoute(String address) throws TelegesisErrorException {
+ logger.trace("Gateway305::findRoute(address=" + address + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.FIND_THE_SOURCE_ROUTE_TO_A_REMOTE_DEVICE.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address;
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void scanNetwork(int numHops) throws TelegesisErrorException {
+ logger.trace("Gateway305::scanNetwork(numHops=" + numHops + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SCAN_NETWORK.getText();
+ if ((numHops >= 0) && (numHops <= 30)) {
+ cmd += SpecialSequence305.COMMAND_SEPARATOR.getText() + String.format("%02d", numHops);
+ }
+
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void updateNetworkKey() throws TelegesisErrorException {
+ logger.trace("Gateway305::updateNetworkKey()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.UPDATE_THE_NETWORK_KEY.getText();
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void becomeTrustCenter() throws TelegesisErrorException {
+ logger.trace("Gateway305::becomeTrustCenter()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.MAKE_LOCAL_DEVICE_THE_TRUST_CENTRE.getText();
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void becomeNetworkManager() throws TelegesisErrorException {
+ logger.trace("Gateway305::becomeNetworkManager()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.MAKE_THE_LOCAL_DEVICE_NETWORK_MANAGER.getText();
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void changeNetworkChannel() throws TelegesisErrorException {
+ logger.trace("Gateway305::changeNetworkChannel()");
+ changeNetworkChannel(0);
+ }
+
+ @Override
+ public void changeNetworkChannel(int channel) throws TelegesisErrorException {
+ logger.trace("Gateway305::changeNetworkChannel(channel=" + channel + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.CHANGE_THE_NETWORK_CHANNEL.getText();
+ if ((channel >= 11) && (channel <= 26)) {
+ cmd += SpecialSequence305.COMMAND_SEPARATOR.getText() + String.format("%02d", channel);
+ }
+
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public AddressTableEntry[] getAddressTable() {
+ logger.trace("Gateway305::getAddressTable()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISPLAY_ADDRESS_TABLE.getText();
+ // la respuesta a este comando puede vernir fraccionada, por lo que
+ // indicamos que la respuesta puede tener un tamaño estimado de 260 bytes
+ spLstnr.setNextFrameExpectedSize(240); // este valor está tuneado para que funcione
+ // enviamos el mensaje, esperando respuesta
+ String response = null;
+ try {
+ response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ } catch (TelegesisErrorException ex) {
+ logger.warn("[GATEWAY] error requesting address table: " + ex.getLocalizedMessage());
+ return null;
+ }
+ // analizamos la respuesta
+ //[0]No. | Active | ID | EUI
+ //[1]00 | N | FFFF |FFFFFFFFFFFFFFFF
+ //[2]01 | N | FFFF |FFFFFFFFFFFFFFFF
+ //[3]02 | N | FFFF |FFFFFFFFFFFFFFFF
+ //[4]03 | N | FFFF |FFFFFFFFFFFFFFFF
+ //[5]04 | N | FFFF |FFFFFFFFFFFFFFFF
+ //[6]05 | N | FFFF |FFFFFFFFFFFFFFFF
+ String[] lines = response.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ if (lines.length == 7) {
+ // analizamos resultado
+ AddressTableEntry[] ate = new AddressTableEntry[6];
+ for (int i = 1; i < lines.length; i++) {
+ String line = lines[i].replace("|", ",");
+ String[] record = line.split(",");
+ short index = (short) Integer.parseInt(record[0].substring(0, 2), 16);
+ boolean active = (record[1].trim().equals("N") ? false : true);
+ String nodeID = record[2].trim();
+ String EUI64Addr = record[3].trim();
+ ate[i - 1] = new AddressTableEntry(index, active, nodeID, EUI64Addr);
+ }
+ return ate;
+ } else {
+ // respuesta inesperada
+ //TODO: hacer log del error
+ return null;
+ }
+
+ }
+ }
+
+ @Override
+ public void setAddressTableEntry(short index, String nodeID, String EUI64Addr) throws TelegesisErrorException {
+ logger.trace("Gateway305::setAddressTableEntry(index=" + index + ", nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SET_ADDRESS_TABLE_ENTRY.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02X", index)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + nodeID
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + EUI64Addr;
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public MulticastTableEntry[] getMulticastTable() {
+ logger.trace("Gateway305::getMulticastTable()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.DISPLAY_MULTICAST_TABLE.getText();
+
+ // la respuesta a este comando puede vernir fraccionada, por lo que
+ // indicamos que la respuesta puede tener un tamaño estimado de 96 bytes
+ spLstnr.setNextFrameExpectedSize(96);
+ // enviamos el mensaje, esperando respuesta
+ String response = null;
+ try {
+ response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ } catch (TelegesisErrorException ex) {
+ logger.warn("[GATEWAY] error requesting multicast address table: " + ex.getLocalizedMessage());
+ return null;
+ }
+ // analizamos la respuesta
+ //[0]No. | ID | EP
+ //[1]00 | 0000 | 01
+ //[2]01 | 0000 | 01
+ //[3]02 | 0000 | 00
+ //[4]03 | 0000 | 00
+ //[5]04 | 0000 | 00
+ String[] lines = response.split(SpecialSequence305.FRAME_SEPARATOR.getText());
+ if (lines.length == 6) {
+ // analizamos resultado
+ MulticastTableEntry[] mte = new MulticastTableEntry[5];
+ for (int i = 1; i < lines.length; i++) {
+ String line = lines[i].replace("|", ",");
+ String[] record = line.split(",");
+ short index = (short) Integer.parseInt(record[0].substring(0, 2), 16);
+ String ID = record[1].trim();
+ short EP = (short) Integer.parseInt(record[2].trim(), 16);
+ mte[i - 1] = new MulticastTableEntry(index, ID, EP);
+ }
+ return mte;
+ } else {
+ // respuesta inesperada
+ //TODO: hacer log del error
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public void setMulticastTableEntry(short index, String ID, short EP) throws TelegesisErrorException {
+ logger.trace("Gateway305::setMulticastTableEntry(index=" + index + ", ID=" + ID + ", EP=" + EP + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.SET_MULTICAST_TABLE_ENTRY.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02X", index)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + ID
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + String.format("%02X", EP);
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void sendBroadcast(int numHops, String data) throws TelegesisErrorException {
+ logger.trace("Gateway305::sendBroadcast(numHops=" + numHops + ", data=" + data + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // validamos numHops
+ if ((numHops < 0) || (numHops > 30)) {
+ numHops = 0;
+ }
+ // componemos mensaje
+ String cmd = Command305.TRANSMIT_A_BROADCAST.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02d", numHops)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + data;
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+ }
+
+ @Override
+ public void sendBroadcast(int numHops, byte[] data) throws TelegesisErrorException {
+ logger.trace("Gateway305::sendBroadcast(numHops=" + numHops + ", data=" + data + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // validamos numHops
+ if ((numHops < 0) || (numHops > 30)) {
+ numHops = 0;
+ }
+ // componemos mensaje
+ String cmd = Command305.TRANSMIT_A_BROADCAST_OF_BINARY_DATA.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02X", data.length)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + String.format("%02d", numHops)
+ + SpecialSequence305.CMD_END.getText()
+ + new String(data, Charset.forName("ISO-8859-1"));
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+
+ }
+ }
+
+ @Override
+ public short sendMessageRequest(String address, String data) throws TelegesisErrorException {
+ logger.trace("Gateway305::sendMessageRequest(address=" + address + ", data=" + data + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.TRANSMIT_A_UNICAST.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.DATA_SEPARATOR.getText()
+ + data;
+ // enviamos el mensaje, esperando la respuesta (SEQ)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public short sendMessageRequest(String address, byte[] data) throws TelegesisErrorException {
+ logger.trace("Gateway305::sendMessageRequest(address=" + address + ", data=" + data + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // componemos mensaje
+ String cmd = Command305.TRANSMIT_A_UNICAST_OF_BINARY_DATA.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02X", data.length)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + address
+ + SpecialSequence305.CMD_END.getText()
+ + new String(data, Charset.forName("ISO-8859-1"));
+ // enviamos el mensaje, esperando la respuesta (SEQ)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ return getSeqNumber(response);
+ }
+ }
+
+ @Override
+ public void sendMulticastBroadcast(int numHops, String ID, String data) throws TelegesisErrorException {
+ logger.trace("Gateway305::sendMulticastBroadcast(numHops=" + numHops + ", ID=" + ID + ", data=" + data + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // validamos numHops
+ if ((numHops < 0) || (numHops > 30)) {
+ numHops = 0;
+ }
+ // componemos mensaje
+ String cmd = Command305.TRANSMIT_A_MULTICAST.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02d", numHops)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + ID
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + data;
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+
+ }
+ }
+
+ @Override
+ public void sendMulticastBroadcast(int numHops, String ID, byte[] data) throws TelegesisErrorException {
+ logger.trace("Gateway305::sendMulticastBroadcast(numHops=" + numHops + ", ID=" + ID + ", data=" + data + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // validamos numHops
+ if ((numHops < 0) || (numHops > 30)) {
+ numHops = 0;
+ }
+ // componemos mensaje
+ String cmd = Command305.TRANSMIT_A_MULTICAST_OF_BINARY_DATA.getText()
+ + SpecialSequence305.COMMAND_SEPARATOR.getText()
+ + String.format("%02X", data.length)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + String.format("%02d", numHops)
+ + SpecialSequence305.PARAMETER_SEPARATOR.getText()
+ + ID
+ + SpecialSequence305.CMD_END.getText()
+ + new String(data, Charset.forName("ISO-8859-1"));
+ // enviamos el mensaje, esperando la respuesta (OK)
+ String response = writeCommand(cmd); //throws TelegesisErrorException if null or ERROR:XX
+ if (!SpecialSequence305.COMMAND_OK.getText().equals(response)) {
+ throw new TelegesisErrorException(ErrorCode305.BAD_RESPONSE.name(), response);
+ }
+ }
+
+ }
+
+ @Override
+ public String writeCommand(String cmd, boolean expectResponse) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeCommand(cmd=" + cmd + ", expectResponse=" + expectResponse + ")");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ synchronized (SYNC_COMMAND) { // sincronizamos para evitar solape de comandos
+ // comprobamos si esperamos respuesta
+ if (expectResponse) {
+ // enviamos el mensaje, esperando la respuesta
+ return writeCommand(cmd);
+ } else {
+ //Enviamos el comando por el puerto serie, sin esperar respuesta
+ serialPort.writeString(cmd + SpecialSequence305.CMD_END.getText());
+ return null;
+ }
+ }
+
+ }
+
+ /**
+ * EnvÃa un comando, por el puerto serie, esperando la respuesta
+ * predeterminada del gateway ([response][OK] o [ERROR])
+ * @param cmd comando a enviar
+ * @return respuesta recibida ([response] o [OK])
+ * @throws TelegesisErrorException si se ha recibido un [ERROR] o null
+ */
+ private String writeCommand(String cmd) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeCommand(cmd=" + cmd + ")");
+
+ // llamamos al método con timeout por defecto
+ return writeCommand(cmd, COMMAND_RESPONSE_TIMEOUT);
+
+ }
+
+ /**
+ * EnvÃa un comando, por el puerto serie, esperando la respuesta
+ * predeterminada del gateway ([response][OK] o [ERROR])
+ * @param cmd comando a enviar
+ * @param milliseconds tiempo de bloqueo de puerto para esperar respuesta
+ * @return respuesta recibida ([response] o [OK])
+ * @throws TelegesisErrorException si se ha recibido un [ERROR] o null
+ */
+ private String writeCommand(String cmd, int milliseconds) throws TelegesisErrorException {
+ logger.trace("Gateway305::writeCommand(cmd=" + cmd + ", milliseconds=" + milliseconds + ")");
+ // bloqueamos el acceso al puerto para recibir la respuesta
+ lockPortForResponses(milliseconds);
+
+ //Enviamos el comando por el puerto serie
+ serialPort.writeString(cmd + SpecialSequence305.CMD_END.getText());
+
+ // recuperamos la respuesta
+ String response = this.spLstnr.waitForNextResponse(milliseconds);
+ // comprobamos respuestas de error (null o ERROR)
+ checkResponseNullOrErrorAndThrowException(response);
+
+ // comprobamos respuesta distinta de OK
+ if (response.startsWith(SpecialSequence305.COMMAND_OK.getText())) {
+ // liberamos puerto y borramos marca de respuesta
+ unlockPortForResponses();
+ return response;
+ } else {
+ // se trata de un comando con respuesta local, a continuación deberÃamos
+ // tener un OK
+ spLstnr.setNextFrameExpectedSize(1);
+ lockPortForResponses(milliseconds);
+ String secResponse = spLstnr.waitForNextResponse(milliseconds);
+ checkResponseNullOrErrorAndThrowException(secResponse);
+ // liberamos puerto y borramos marca de respuesta
+ unlockPortForResponses();
+ return response;
+
+ }
+ }
+
+ // </editor-fold>
+ @Override
+ public boolean open() {
+ logger.trace("Gateway305::open()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ logger.info("[Gateway open] Checking available gateway at " + serialPort);
+
+ // preinicializamos la marca de gateway abierto a false
+ gtwyIsOpen = false;
+
+ // comprobamos si el puerto está abierto
+ if (!serialPort.isOpen()) {
+ // intentamos abrir el puerto, si hay error devolvemos false
+ if (!serialPort.open()) {
+ logger.info("[Gateway open] Error opening serial port " + serialPort);
+ return false;
+ }
+ }
+
+ // registramos el listener del puerto
+ serialPort.registerListener(spLstnr);
+
+ // Recuperamos el productID
+ String[] pid = getProductId();
+ // comprobamos resultados
+ if (pid == null) { // comprobamos respuesta válida
+ close();
+ return false;
+ } else if (pid.length != 3) {
+ close();
+ return false;
+ }
+
+ // guardamos respuesta
+ deviceName = pid[0].trim();
+ firmwareRevision = pid[1].trim();
+ dongleAddress = pid[2].trim();
+
+ // comprobamos versión base
+ boolean isFWComp = false;
+ if (firmwareRevision.startsWith(FIRMWARE_REVISION)) {
+ isFWComp = true;
+ } else // comprobamos compatibilidad firmware
+ {
+ for (int i = 0; i < COMPATIBLE_FIRMWARE.length; i++) {
+ if (COMPATIBLE_FIRMWARE[i].equals(firmwareRevision)) {
+ isFWComp = true;
+ break;
+ }
+ }
+ }
+
+ // si no es compatible, cerramos el puerto
+ if (!isFWComp) {
+ close();
+ return false;
+ }
+
+ // configuramos el gateway
+ if (!init()) {
+ close();
+ return false;
+ }
+
+ // hemos llegado hasta aquÃ, todo correcto, marcamos gateway abierto y devolvemos true
+ logger.info("Gateway sucessfully open");
+ gtwyIsOpen = true;
+ return gtwyIsOpen;
+ }
+
+ /**
+ * Realiza la configuración básica del gateway
+ * @return true si se han ejecutado todas las operaciones correctamente
+ */
+ private boolean init() {
+ logger.trace("Gateway305::init()");
+
+ // escribimos la configuración de registros
+ try {
+ this.writeRegister(S_REG_ADDR_PROMPT_ENABLE_1, DEFAULT_PROMPT_ENABLE_1);
+ this.writeRegister(S_REG_ADDR_PROMPT_ENABLE_2, DEFAULT_PROMPT_ENABLE_2);
+ this.writeRegisterBit(S_REG_ADDR_UART_SETUP, S_REG_BIT_NO_COMMAND_ECHO, true);
+ } catch (TelegesisErrorException ex) {
+ logger.warn("Error while initializing gateway", ex);
+ return false;
+ }
+
+
+ return true;
+
+ }
+
+ @Override
+ public boolean close() {
+ logger.trace("Gateway305::close()");
+ // comprobamos el bloqueo del gateway
+ checkLock();
+
+ gtwyIsOpen = false;
+ // eliminamos el registro del listener con el puerto serie
+ serialPort.unregisterListener(spLstnr);
+ logger.info("Gateway closed");
+ return true;
+ }
+
+ @Override
+ public boolean isOpen() {
+ logger.trace("Gateway305::isOpen()");
+ return gtwyIsOpen;
+ }
+
+ @Override
+ public SerialConnection getConnection() {
+ logger.trace("Gateway305::getConnection()");
+
+ return serialPort;
+
+ }
+ // #########################################################################
+
+ private ZigbeeDeviceType getTypeFromPrompt(String prompt) {
+ logger.trace("Gateway305::getTypeFromPrompt(prompt=" + prompt + ")");
+ if (prompt.startsWith(Prompt305.COO_ANNOUNCE.getText())) {
+ return ZigbeeDeviceType.Coordinator;
+ } else if (prompt.startsWith(Prompt305.FFD_ANNOUNCE.getText())) {
+ return ZigbeeDeviceType.Router;
+ } else if (prompt.startsWith("RFD")) { // asumimos EndDevice para consuatl en tabla de vecinos
+ return ZigbeeDeviceType.EndDevice;
+ } else if (prompt.startsWith(Prompt305.ZED_ANNOUNCE.getText())) {
+ return ZigbeeDeviceType.EndDevice;
+ } else if (prompt.startsWith(Prompt305.MED_ANNOUNCE.getText())) {
+ return ZigbeeDeviceType.MobileEndDevice;
+ } else if (prompt.startsWith(Prompt305.SED_ANNOUNCE.getText())) {
+ return ZigbeeDeviceType.SleepyEndDevice;
+ } else { // NEWNODE
+ return ZigbeeDeviceType.Unknown;
+ }
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/GatewayFactoryImpl.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/GatewayFactoryImpl.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/GatewayFactoryImpl.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,46 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+import es.unizar.howlab.core.io.serial.SerialConnection;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class GatewayFactoryImpl implements es.unizar.howlab.core.zigbee.telegesis.gateway.GatewayFactory {
+
+ @Override
+ public Gateway createGateway(SerialConnection connection) {
+
+ // comprobamos para todas las implementaciones soportadas
+ Gateway testGtwy;
+
+ // comprobamos version R305X
+ testGtwy = new Gateway305(connection);
+ if (testGtwy.open()){
+ return testGtwy;
+ } else {
+ testGtwy.close();
+ }
+
+ // no es un gateway valido
+ return null;
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/SerialListener.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/SerialListener.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/SerialListener.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,521 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import es.unizar.howlab.core.io.serial.SerialConnection.State;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.Prompt305;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.SpecialSequence305;
+import es.unizar.howlab.core.io.serial.*;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Class for
+ * @author alvaro
+ */
+public class SerialListener implements SerialConnectionListener {
+
+ private byte[] msgBuffer = null;
+ private LinkedBlockingQueue<String> strPrompts = new LinkedBlockingQueue<String>();
+ private LinkedBlockingQueue<String> strResponses = new LinkedBlockingQueue<String>();
+ // Coleccion para almacenar los promts de longitud variable
+ ArrayList variableLengthPrompt = new ArrayList();
+ final MessageParser msgParser;
+ // Logger
+ Log logger = LogFactory.getLog(SerialListener.class.getName());
+
+ /**
+ * Constructor. realiza las operaciones de inicialización del listener
+ */
+ public SerialListener(MessageParser parser) {
+ logger.trace("SerialListener::SerialListener(parser=" + parser + ")");
+
+ msgParser = parser;
+ // Inicializamos la coleccion de promts de longitud variable
+ variableLengthPrompt.add(Prompt305.BROADCAST_RECEIVED);
+ variableLengthPrompt.add(Prompt305.MULTICAST_RECEIVED);
+ variableLengthPrompt.add(Prompt305.UNICAST_RECEIVED);
+ variableLengthPrompt.add(Prompt305.END_POINT_MESSAGE);
+
+
+ }
+
+ @Override
+ public void stateChanged(State state, SerialConnection serial) {
+ switch (state) {
+ case OPEN:
+ case PORT_IN_USE:
+ case TOO_MANY_LISTENERS:
+ case UNKNOWN:
+ case NO_SUCH_PORT:
+ case UNSUPPORTED_COMM:
+ // Estos estados no deberÃan producirse o no nos interesan
+ break;
+ case UNPLUGGED:
+ // notificamos error para cerrar el gateway
+ msgParser.serialPortError();
+ break;
+ case CLOSE:
+ // notificamos error para cerrar el gateway
+ msgParser.serialPortError();
+ break;
+ }
+ }
+
+ /**
+ * Interfaz para notificar de la existencia de mensajes recibidos
+ */
+ public interface MessageParser {
+
+ /**
+ * Notifica que se han recibido prompts
+ */
+ public void hasNewPromps();
+
+ /**
+ * Notifica de un error de puerto
+ */
+ public void serialPortError();
+ }
+
+ /**
+ * Comprueba si tenemos nuevos datos
+ * @return
+ */
+ public boolean hasNewFrames() {
+ logger.trace("SerialListener::hasNewFrames()");
+ return !strPrompts.isEmpty();
+ }
+
+ @Override
+ public void eventMessage(SerialMessage message, SerialConnection serialConnection) {
+ logger.trace("SerialListener::eventMessage(message=" + message + ", serialConnection=" + serialConnection + ")");
+ switch (message.getType()) {
+ case messageReceived:
+ processIncommingMessage(message.getBinaryMessage());
+ break;
+ case commandSent: // mensaje saliente, ignoramos
+ break;
+ }
+ }
+
+ /**
+ * Acumula los mensajes recibidos
+ * @param incommingMsg
+ */
+ public synchronized void processIncommingMessage(byte[] incommingMsg) {
+ logger.trace("SerialListener::processIncommingMessage(incommingMsg=" + incommingMsg + ")");
+ logger.info(String.format("received %d bytes by SerialListener", incommingMsg.length));
+ // acumulamos mensaje recibido
+ if (msgBuffer == null) {
+ msgBuffer = incommingMsg.clone();
+ } else {
+ byte[] previousMsg = msgBuffer.clone();
+ msgBuffer = new byte[incommingMsg.length + previousMsg.length];
+ System.arraycopy(previousMsg, 0, msgBuffer, 0, previousMsg.length);
+ System.arraycopy(incommingMsg, 0, msgBuffer, previousMsg.length, incommingMsg.length);
+ }
+
+ // Lanzamos el procesamiento del mensaje
+ parseMsgBuffer();
+
+ }
+
+ /**
+ * Recupera el siguiente prompt recibido (eliminándolo de la cola)
+ * @return Siguiente prompt recibido, o null si no hay ninguno
+ */
+ public String getNextPrompt() {
+ logger.trace("SerialListener::getNextPrompt()");
+ try {
+ return strPrompts.poll(10, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException ex) {
+ logger.warn("SerialListener::getNextPrompt() interrupted", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Recupera la siguiente respuesta a comando recibida (aliminádolo de la cola)
+ * @return Siguiente respuesta, o null si no hay ninguna
+ */
+ public String getNextResponse() {
+ logger.trace("SerialListener::getNextResponse()");
+ try {
+ return strResponses.poll(10, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException ex) {
+ logger.warn("SerialListener::getNextResponse() interrupted", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Recupera la siguiente repuesta (eliminándola de la cola), esperando
+ * @param timeout tiempo antes de abandonar respuesta
+ * @return Siguiente respuesta recibida, o null si no hay ninguna
+ */
+ public String waitForNextResponse(long timeout) {
+ logger.trace("SerialListener::waitForNextResponse(timeout=" + timeout + ")");
+ try {
+ return strResponses.poll(timeout, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException ex) {
+ logger.warn("SerialListener::waitForNextResponse() interrupted", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Examina el siguiente prompt recibido (sin eliminarlo de la cola)
+ * @return Siguiente prompt recibido, o null si no hay ninguno
+ */
+ public String inspectNextPrompt() {
+ logger.trace("SerialListener::inspectNextPrompt()");
+ return strPrompts.peek();
+ }
+
+ /**
+ * Examina la siguiente respuesta a comando recibida (sin eliminarlo de la cola)
+ * @return Siguiente respuesta, o null si no hay ninguna
+ */
+ public String inspectNextResponse() {
+ logger.trace("SerialListener::inspectNextResponse()");
+ return strResponses.peek();
+ }
+ private ArrayList promptsToCaptureAsResponses = new ArrayList();
+
+ /**
+ * Establece un prompt para que se considere respuesta a un comando
+ * @param prompt prompt experado
+ */
+ public void capturePromptAsResponse(String prompt) {
+ logger.trace("SerialListener::capturePromptAsResponse(prompt=" + prompt + ")");
+ promptsToCaptureAsResponses.add(prompt);
+ }
+
+ /**
+ * Elimina un prompt de la lista de prompts a capturar como respuesta
+ * @param prompt
+ */
+ public void removeExpectedPrompt(String prompt) {
+ logger.trace("SerialListener::removeExpectedPrompt()");
+ promptsToCaptureAsResponses.remove(prompt);
+ }
+
+ /**
+ * VacÃa la lista de prompts a capturar
+ */
+ public void clearExpectedPrompts() {
+ logger.trace("SerialListener::clearExpectedPrompts()");
+ promptsToCaptureAsResponses.clear();
+ }
+ private boolean expectResponse;
+ private int nextFrameExpectedSize;
+
+ /**
+ * Establece el tamaño estimado del frame a recibir
+ * @param frameSize Tamaño estimado del frame a recibir
+ */
+ public void setNextFrameExpectedSize(int frameSize) {
+ logger.trace("SerialListener::setNextFrameExpectedSize(frameSize=" + frameSize + ")");
+ nextFrameExpectedSize = frameSize;
+ }
+
+ /**
+ * Establece la marca de que esperamos una respuesta
+ */
+ public void setExpectResponse() {
+ logger.trace("SerialListener::setExpectResponse()");
+ expectResponse = true;
+ }
+
+ /**
+ * Borra la marca de esperar respuesta, con lo que todos los mensajes
+ * entrantes serán intepretados como prompts
+ */
+ public void clearExpectResponse() {
+ logger.trace("SerialListener::clearExpectResponse()");
+ expectResponse = false;
+ }
+
+ /**
+ * Realiza el procesamiento del buffer de entrada
+ */
+ private void parseMsgBuffer() {
+ logger.trace("SerialListener::parseMsgBuffer()");
+ // recuperamos las tramas de mensajes
+ String frame = getNextFrameFromMsgBuffer();
+ boolean hasNewPrompt = false;
+ while (frame != null) {
+ logger.info("Received frame by SerialListener: " + frame);
+ // comprobamos si no está marcado el flag de esperando respuesta,
+ //en cuyo caso directamente lo interpretamos como un prompt
+ if (!expectResponse) {
+ hasNewPrompt = true;
+ strPrompts.add(frame);
+ } else { // si esperamos una respuesta, comprobamos si se trata de una respuesta o un prompt
+ // comprobamos primero si se trata de un prompt a capturar como respuesta
+ String command = frame.split(":")[0];
+ if (promptsToCaptureAsResponses.contains(command)) {
+ strResponses.add(frame);
+ promptsToCaptureAsResponses.remove(command);
+ } else {
+ // comprobamos si se trata de un promot o una respuesta
+ Prompt305[] promptList = Prompt305.values();
+ boolean isPrompt = false;
+ for (int i = 0; i < promptList.length; i++) {
+ if (promptList[i].chekMessage(frame.getBytes(Charset.forName("ISO-8859-1")), 0)) {
+ isPrompt = true;
+ break;
+ }
+ }
+ if (isPrompt) {
+ strPrompts.add(frame);
+ hasNewPrompt = true;
+ } else { // se trata de una respuesta a un comando
+ strResponses.add(frame);
+ }
+ }
+
+ }
+ // recuperamos el siguiente frame
+ frame = getNextFrameFromMsgBuffer();
+ }
+ //Notificamos la existencia de mensajes
+ if (hasNewPrompt) {
+ msgParser.hasNewPromps();
+ }
+
+ }
+
+ /**
+ * Obtiene la siguiente trama siguiente en el mensaje, y la elimina del buffer.
+ * @return String con la trama del mensaje o null si no hay trama
+ */
+ private String getNextFrameFromMsgBuffer() {
+ logger.trace("SerialListener::getNextFrameFromMsgBuffer()");
+ /*
+ * La estructura del mensaje es:
+ * 0x0D, 0x0A ==> inicio de trama
+ * 0xXX, 0xXX, ... ==> datos
+ * 0x0D, 0x0A ==> fin de trama
+ *
+ * Nota: los datos también pueden contener la secuencia {0x0D, 0x0A}
+ * (salto de lÃnea), por lo que el final de trama efectivo debe
+ * considerarse si:
+ * - no hay más datos (esto implica cierto riesgo), o
+ * - el resto del mensaje empieza con un inicio de trama
+ */
+
+ // Comprobamos que el inicio del mensaje es correcto
+ //int startMsgPos = findSequence(msgBuffer, SpecialSequence305.FRAME_SEPARATOR.getBytes(Charset.forName("ISO-8859-1")), 0);
+ int startMsgPos = findSequence(new String(msgBuffer, Charset.forName("ISO-8859-1")), SpecialSequence305.FRAME_SEPARATOR.getText(), 0);
+ if (startMsgPos < 0) { // no hemos encontrado el inicio del mensaje, abandonamos
+ return null;
+ } else if (startMsgPos > 0) { // hemos recibido un mensaje incompleto, borramos el principio y notificamos warning
+ //Log warning de mensaje incompleto
+ byte[] discardBuffer = new byte[startMsgPos];
+ System.arraycopy(msgBuffer, 0, discardBuffer, 0, discardBuffer.length);
+ logger.warn(String.format("[SerialListener] Received message incomplete. Discarding %d bytes (%s)", startMsgPos, new String(discardBuffer, Charset.forName("ISO-8859-1"))));
+ // guardamos el mensaje a procesar
+ byte[] trimBuffer = new byte[msgBuffer.length - startMsgPos];
+ System.arraycopy(msgBuffer, startMsgPos, trimBuffer, 0, trimBuffer.length);
+ msgBuffer = trimBuffer.clone();
+ }
+
+ //Nota: a partir de este punto, el mensaje empieza con un inicio de trama en la posicion 0
+
+ // Comprobamos el extremo final
+ boolean frameEndFound = false;
+ int frameSepLength = SpecialSequence305.FRAME_SEPARATOR.getBytes().length;
+ // para buscar el final de la trama, estimamos cual es la posición del
+ // final de la misma en función de la trama recibida
+ int nextSearchEndPos = frameSepLength + estimateFrameMinLength(msgBuffer, frameSepLength);
+ int endMsgPos = nextSearchEndPos; // por inicializarlo en algo...
+ while (!frameEndFound) {
+ //endMsgPos = findSequence(msgBuffer, SpecialSequence305.FRAME_SEPARATOR.getBytes(Charset.forName("ISO-8859-1")), nextSearchEndPos);
+ endMsgPos = findSequence(new String(msgBuffer, Charset.forName("ISO-8859-1")), SpecialSequence305.FRAME_SEPARATOR.getText(), nextSearchEndPos);
+ // comprobamos las condiciones de final de trama
+ if (endMsgPos < 0) { // no hemos encontrado el final del mensaje, abandonamos
+ return null;
+ } else if ((endMsgPos - frameSepLength < nextFrameExpectedSize)) { // comprobamos si el tamaño del frame se corresponde con lo que esperabamos recibir, y en caso negativo seguimos buscando
+ nextSearchEndPos = endMsgPos + frameSepLength;
+ } else if ((endMsgPos + frameSepLength) == msgBuffer.length) { // no hay más datos
+ frameEndFound = true;
+ //} else if (checkSequence(msgBuffer, SpecialSequence305.FRAME_SEPARATOR.getBytes(Charset.forName("ISO-8859-1")), endMsgPos + frameSepLength)) { // comprobamos si los datos siguientes contienen el inicio de trama
+ } else if (checkSequence(new String(msgBuffer, Charset.forName("ISO-8859-1")), SpecialSequence305.FRAME_SEPARATOR.getText(), endMsgPos + frameSepLength)) { // comprobamos si los datos siguientes contienen el inicio de trama
+ frameEndFound = true;
+ } else { // modificamos el indice para buscar la secuencia y continuamos buscando
+ nextSearchEndPos = endMsgPos + frameSepLength;
+ }
+ }
+
+ // recuperamos el frame
+ byte[] msgFrame = new byte[endMsgPos - frameSepLength];
+ System.arraycopy(msgBuffer, frameSepLength, msgFrame, 0, msgFrame.length);
+ String nextFrame = new String(msgFrame, Charset.forName("ISO-8859-1"));
+
+ // guardamos el resto del mensaje
+ byte[] remainderMsg = new byte[msgBuffer.length - endMsgPos - frameSepLength];
+ System.arraycopy(msgBuffer, endMsgPos + frameSepLength, remainderMsg, 0, remainderMsg.length);
+ msgBuffer = remainderMsg.clone();
+
+ // comprobacion de mensajes con doble FRAME_SEPARATOR al principio
+ if (nextFrame.startsWith(SpecialSequence305.FRAME_SEPARATOR.getText())) {
+ nextFrame = nextFrame.substring(SpecialSequence305.FRAME_SEPARATOR.getBytes().length);
+ }
+
+ //Restablecemos el tamaño esperado para el proximo frame
+ nextFrameExpectedSize = 1;
+
+ logger.debug(String.format("[SerialListener] getNexFrame: frame=%s, length=%d", nextFrame, nextFrame.length()));
+ // devolvemos el frame localizado
+ return nextFrame;
+ }
+
+ /**
+ * Estima la longitud mÃnima de la trama, de acuerdo al contenido de la misma
+ * @param msg Mensaje a analizar
+ * @param startPos Punto a partir del cual se busca
+ * @return posible longitud de la trama
+ */
+ private int estimateFrameMinLength(byte[] msg, int startPos) {
+ logger.trace("SerialListener::estimateFrameMinLength(msg=" + msg + ", startPos=" + startPos + ")");
+ int estimateLength = 0;
+
+ // comprobamos si se trata de una respuesta tipo prompt de longitud variable
+ Iterator it = variableLengthPrompt.iterator();
+ while (it.hasNext()) {
+//------------------------------------------------------------------------------
+// Posible alternativa para omitir el uso de Prompt305
+//------------------------------------------------------------------------------
+// String strTestPrompt = ((Prompt305) it.next()).getText();
+// String inMsg = new String(msg);
+// int pos = inMsg.indexOf(strTestPrompt, startPos);
+// if (pos >= startPos) {
+// int sizePos = findSequence(msg, "=".getBytes(Charset.forName("ISO-8859-1")), startPos) - 2;
+// String strDataSize = new String(msg, sizePos, 2);
+// int dataSize = Integer.parseInt(strDataSize);
+// estimateLength = (sizePos - startPos) + dataSize + 3; //...XX=<data>
+// break;
+// } else {
+// estimateLength = strTestPrompt.length();
+// }
+//------------------------------------------------------------------------------
+
+ Prompt305 testPrompt = (Prompt305) it.next();
+ if (testPrompt.chekMessage(msg, startPos)) {
+ if (testPrompt.getHasData()) {
+ int sizePos = startPos + testPrompt.getMinSize();
+ if (sizePos == startPos) {
+ //sizePos = findSequence(msg, "=".getBytes(Charset.forName("ISO-8859-1")), startPos) - 2;
+ sizePos = findSequence(new String(msg, Charset.forName("ISO-8859-1")), "=", startPos) - 2;
+ }
+ String strDataSize = new String(msg, sizePos, 2, Charset.forName("ISO-8859-1"));
+ int dataSize = Integer.parseInt(strDataSize, 16);
+ estimateLength = (sizePos - startPos) + dataSize + 3; //...XX=<data>
+ } else {
+ estimateLength = testPrompt.getMinSize();
+ }
+ break;
+ }
+ }// el resto de opciones son mensajes en respuesta a un comando que deben seguir un fin de trama
+
+ // devolvemos la longitud estimada
+ return estimateLength;
+ }
+
+ /**
+ * Devuelve la posición de inicio de la secuencia en el mensaje
+ * @param message mensaje a analizar
+ * @param sequence secuencia a buscar
+ * @param start posición de inicio de búsqueda
+ * @return posición donde se ubica la seuencia
+ */
+ private int findSequence(byte[] message, byte[] sequence, int start) {
+ logger.trace("SerialListener::findSequence(message=" + message + ", sequence=" + sequence + ", start=" + start + ")");
+ int startPos = -1;
+ // recorremos el mensaje
+ for (int i = start; i <= message.length - sequence.length; i++) {
+ // Buscamos la secuencia en la posición del Ãndice
+ if (checkSequence(message, sequence, i)) {
+ startPos = i;
+ break;
+ }
+ }
+
+ return startPos;
+ }
+
+ /**
+ * Devuelve la posición de inicio de la secuencia en el mensaje
+ * @param message mensaje a analizar
+ * @param sequence secuencia a buscar
+ * @param start posición de inicio de búsqueda
+ * @return posición donde se ubica la seuencia
+ */
+ private int findSequence(String message, String sequence, int start) {
+ logger.trace("SerialListener::findSequence(message=" + message + ", sequence=" + sequence + ", start=" + start + ")");
+ return message.indexOf(sequence, start);
+ }
+
+ /**
+ * Comprueba si el mensaje contiene la secuencia en la posición indicada
+ * (no hace búsqueda)
+ * @param message mensaje que contiene (o no) la secuencia
+ * @param sequence secuencia a buscar
+ * @param pos posición donde queremos comprobar la secuencia
+ * @return TRUE si coincide, FALSE si no
+ */
+ private boolean checkSequence(byte[] message, byte[] sequence, int pos) {
+ logger.trace("SerialListener::checkSequence(message=" + message + ", sequence=" + sequence + ", pos=" + pos + ")");
+ // comprobamos tamaño
+ if (message.length < sequence.length + pos) {
+ return false;
+ }
+ // comprobamos secuencia
+ for (int i = 0; i < sequence.length; i++) {
+ // si no coincide la secuencia en un carácter, devolvemos FALSE
+ if (message[pos + i] != sequence[i]) {
+ return false;
+ }
+ }
+ // si hemos llegado aquÃ, coincide la secuencia, devolvemos TRUE
+ return true;
+ }
+
+ /**
+ * Comprueba si el mensaje contiene la secuencia en la posición indicada
+ * (no hace búsqueda)
+ * @param message mensaje que contiene (o no) la secuencia
+ * @param sequence secuencia a buscar
+ * @param pos posición donde queremos comprobar la secuencia
+ * @return TRUE si coincide, FALSE si no
+ */
+ private boolean checkSequence(String message, String sequence, int pos) {
+ logger.trace("SerialListener::checkSequence(message=" + message + ", sequence=" + sequence + ", pos=" + pos + ")");
+ if (message.indexOf(sequence, pos) == pos) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/Activator.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/Activator.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/Activator.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,76 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl.osgi;
+
+import es.unizar.howlab.core.zigbee.telegesis.gateway.GatewayFactory;
+import es.unizar.howlab.core.io.serial.SerialConnection;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.GatewayFactoryImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext bc = null;
+ private ServiceRegistration srGF = null;
+ private ServiceTracker st = null;
+ SerialConnectionServiceTracker stc = null;
+ // Logger
+ static Log logger = LogFactory.getLog(Activator.class.getName());
+
+ public static BundleContext getBundleContext(){
+ logger.trace("Activator::getBundleContext()");
+ return bc;
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ logger.trace("Activator::start(context=" + context + ")");
+
+ // guardamos el bundle m_context
+ bc = context;
+
+ // Creamos el GatewayFactoryImpl
+ GatewayFactory gtwyF = new GatewayFactoryImpl();
+ // Registramos el GatewayFactoryImpl //TODO: revisar propiedades en el registro?
+ srGF = context.registerService(GatewayFactory.class.getName(), gtwyF, null);
+
+ // Creamos el tracker para el puerto serie que se encargará de crear los gateways
+ stc = new SerialConnectionServiceTracker();
+ st = new ServiceTracker(bc, SerialConnection.class.getName(), stc);
+ // arrancamos el tracker
+ st.open();
+
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ logger.trace("Activator::stop(context=" + context + ")");
+ // paramos el service tracker
+ st.close();
+
+ // paramos el SerialConnectionServiceTracker para despublicar los gateways
+ stc.stop();
+
+ // desregistramos el Gateway Factory
+ srGF.unregister();
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/SerialConnectionServiceTracker.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/SerialConnectionServiceTracker.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/osgi/SerialConnectionServiceTracker.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,133 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl.osgi;
+
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.GatewayFactory;
+import es.unizar.howlab.core.io.serial.SerialConnection;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.osgi.Constants;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ *
+ * @author alvaro
+ */
+public class SerialConnectionServiceTracker implements ServiceTrackerCustomizer {
+
+ HashMap<ServiceReference, ServiceRegistration> serialConnectionsUsed = new HashMap<ServiceReference, ServiceRegistration>();
+
+ /**
+ * Ejecuta las operaciones de detencion del tracker
+ */
+ public void stop() {
+
+ // Despublicamos los gateways publicados
+ Iterator<ServiceReference> it = serialConnectionsUsed.keySet().iterator();
+ BundleContext bc = Activator.getBundleContext();
+ while (it.hasNext()) {
+ ServiceReference srefSerial = it.next();
+ // recuperamos el gateway correspondiente para cerrarlo
+ ServiceRegistration sregGtwy = serialConnectionsUsed.get(srefSerial);
+ Gateway gt = (Gateway) bc.getService(sregGtwy.getReference());
+ gt.close();
+
+ // desregisramos el gatewaw
+ sregGtwy.unregister();
+
+ // soltamos el puerto serie
+ bc.ungetService(srefSerial);
+ }
+
+ }
+
+ @Override
+ public Object addingService(ServiceReference reference) {
+
+ BundleContext bc = Activator.getBundleContext();
+ // recuperamos el GatewayFactory
+ ServiceReference srFactory = bc.getServiceReference(GatewayFactory.class.getName());
+ if (srFactory == null) { // no se deberÃa dar esta situación, pero...
+ return null;
+ }
+ GatewayFactory gtwyF = (GatewayFactory) bc.getService(srFactory);
+
+ // recuperamos el puerto serie
+ SerialConnection serialCNX = (SerialConnection) bc.getService(reference);
+
+
+ // intentamos crear un gateway en el puerto serie
+ Gateway gtwy = gtwyF.createGateway(serialCNX);
+ if (gtwy == null) {
+ // soltamos el puerto serie
+ bc.ungetService(reference);
+ serialCNX = null;
+ } else {
+ // registramos el Gateway en OSGi
+ Dictionary properties = new Hashtable();
+ properties.put(Constants.GATEWAY_DEVICE_NAME, gtwy.getDeviceName());
+ properties.put(Constants.GATEWAY_DONGLE_ADDRESS, gtwy.getDongleAddress());
+ properties.put(Constants.GATEWAY_FIRMWARE_REVISION, gtwy.getFirmwareRevision());
+ ServiceRegistration srGateway = bc.registerService(Gateway.class.getName(), gtwy, properties);
+
+ // lo añadimos a la lista de gateways
+ serialConnectionsUsed.put(reference, srGateway);
+ }
+
+ // Soltamos el GatewayFactory
+ bc.ungetService(srFactory);
+ gtwyF = null;
+
+ // devolvemos el puerto serie (será null si no hemos abierto un gateway
+ return serialCNX;
+
+ }
+
+ @Override
+ public void modifiedService(ServiceReference reference, Object service) {
+ // no hacemos nada
+ }
+
+ @Override
+ public void removedService(ServiceReference reference, Object service) {
+ // Comprobamos si es un puerto asociado a un SerialConnection
+ if (serialConnectionsUsed.containsKey(reference)) {
+ BundleContext bc = Activator.getBundleContext();
+ // Recuperamos el Gateway
+ ServiceRegistration sregGateway = serialConnectionsUsed.get(reference);
+ Gateway gtwy = (Gateway) bc.getService(sregGateway.getReference());
+ // cerramos el gateway
+ gtwy.close();
+ // despublicamos el gateway
+ sregGateway.unregister();
+
+ // Soltamos el puerto serie
+ bc.ungetService(reference);
+
+ // los eliminamos de la lista
+ serialConnectionsUsed.remove(reference);
+
+ }
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Command305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Command305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Command305.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,96 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol;
+
+import java.nio.charset.Charset;
+
+/**
+ *
+ * @author alvaro
+ */
+public enum Command305 {
+
+ DISPLAY_PRODUCT_IDENTIFICATION("ATI"),
+ SOFTWARE_RESET("ATZ"),
+ RESTORE_FACTORY_DEFAULTS("AT&F"),
+ ENTER_THE_BOOTLOADER_MENU("AT+BLOAD"),
+ CLONE_LOCAL_NODE_TO_REMOTE_NODE("AT+CLONE"),
+ PASS_NEW_FIRMWARE_IMAGE_TO_REMOTE_NODE("AT+PASSTHROUGH"),
+ RECOVER_FROM_A_FAILED_CLONE_ATTEMPT("AT+RECOVER"),
+ S_REGISTER_ACCESS("ATS"),
+ REMOTE_S_REGISTER_ACCESS("ATREMS"),
+ REMOTE_S_REGISTER_ACCESS_ALL("ATSALL"),
+ DISPLAY_ALL_S_REGISTERS("AT+TOKDUMP"),
+ SCAN_THE_ENERGY_OF_ALL_CHANNELS("AT+ESCAN"),
+ SCAN_FOR_ACTIVE_PANS("AT+PANSCAN"),
+ ESTABLISH_PERSONAL_AREA_NETWORK("AT+EN"),
+ JOIN_NETWORK("AT+JN"),
+ JOIN_SPECIFIC_PAN("AT+JPAN"),
+ SILENT_JOIN("AT+SJN"),
+ DISASSOCIATE_LOCAL_DEVICE_FROM_PAN("AT+DASSL"),
+ DISASSOCIATE_REMOTE_NODE_FROM_PAN("AT+DASSR"),
+ DISPLAY_NETWORK_INFORMATION("AT+N?"),
+ DISPLAY_NEIGHBOUR_TABLE("AT+NTABLE"),
+ DISPLAY_ROUTING_TABLE("AT+RTABLE"),
+ REQUEST_NODEID("AT+IDREQ"),
+ REQUEST_EUI("AT+EUIREQ"),
+ REQUEST_NODE_DESCRIPTOR("AT+NODEDESC"),
+ REQUEST_NODE_POWER_DESCRIPTOR("AT+POWERDESC"),
+ REQUEST_NODE_ACTIVE_ENDPOINT_LIST("AT+ACTEPDESC"),
+ REQUEST_ENDPOINT_SIMPLE_DESCRIPTOR("AT+SIMPLEDESC"),
+ FIND_NODES_WHICH_MATCH_A_SPECIFIC_DESCRIPTOR("AT+MATCHREQ"),
+ ANNOUNCE_LOCAL_DEVICE_IN_THE_NETWORK("AT+ANNCE"),
+ SET_SOURCE_ROUTE_TO_REMOTE_DEVICE("AT+SR"),
+ FIND_THE_SOURCE_ROUTE_TO_A_REMOTE_DEVICE("AT+FNDSR"),
+ POLL_FOR_DATA_FROM_PARENT("AT+POLL"),
+ REJOIN_THE_NETWORK("AT+REJOIN"),
+ SCAN_NETWORK("AT+SN"),
+ UPDATE_THE_NETWORK_KEY("AT+KEYUPD"),
+ MAKE_LOCAL_DEVICE_THE_TRUST_CENTRE("AT+BECOMETC"),
+ MAKE_THE_LOCAL_DEVICE_NETWORK_MANAGER("AT+BECOMENM"),
+ CHANGE_THE_NETWORK_CHANNEL("AT+CCHANGE"),
+ DISPLAY_ADDRESS_TABLE("AT+ATABLE"),
+ SET_ADDRESS_TABLE_ENTRY("AT+ASET"),
+ DISPLAY_MULTICAST_TABLE("AT+MTABLE"),
+ SET_MULTICAST_TABLE_ENTRY("AT+MSET"),
+ TRANSMIT_A_BROADCAST("AT+BCAST"),
+ TRANSMIT_A_BROADCAST_OF_BINARY_DATA("AT+BCASTB"),
+ TRANSMIT_A_UNICAST("AT+UCAST"),
+ TRANSMIT_A_UNICAST_OF_BINARY_DATA("AT+UCASTB"),
+ TRANSMIT_DATA_TO_THE_SINK("AT+SCAST"),
+ TRANSMIT_BINARY_DATA_TO_THE_SINK("AT+SCASTB"),
+ SEARCH_FOR_A_SINK("AT+SSINK"),
+ TRANSMIT_A_MULTICAST("AT+MCAST"),
+ TRANSMIT_A_MULTICAST_OF_BINARY_DATA("AT+MCASTB"),
+ ENTER_DATA_MODE("AT+DMODE"),
+ LEAVE_DATA_MODE("+++"),
+ PLAY_A_TUNE_ON_REMOTE_DEVBOARD("AT+IDENT"),
+ SEND_BINARY_RAW_DATA("AT+RDATAB");
+ private final String command;
+
+ Command305(String command) {
+ this.command = command;
+ }
+
+ public String getText() {
+ return command;
+ }
+
+ public byte[] getBytes() {
+ return command.getBytes(Charset.forName("ISO-8859-1"));
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/ErrorCode305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/ErrorCode305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/ErrorCode305.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,94 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol;
+
+/**
+ *
+ * @author alvaro
+ */
+public enum ErrorCode305 {
+ TELEGESIS_ERROR_00("Everything OK - Success"),
+ TELEGESIS_ERROR_01("Couldnât poll Parent because of Timeout"),
+ TELEGESIS_ERROR_02("Unknown command"),
+ TELEGESIS_ERROR_04("Invalid S-Register"),
+ TELEGESIS_ERROR_05("Invalid parameter"),
+ TELEGESIS_ERROR_06("Recipient could not be reached"),
+ TELEGESIS_ERROR_07("Message was not acknowledged"),
+ TELEGESIS_ERROR_08("No sink known"),
+ TELEGESIS_ERROR_09("Address Table entry is in use and cannot be modified"),
+ TELEGESIS_ERROR_0A("Message could not be sent"),
+ TELEGESIS_ERROR_0B("Local node is not sink"),
+ TELEGESIS_ERROR_0C("Too many characters"),
+ TELEGESIS_ERROR_0E("Background Scan in Progress (Please wait and try again)"),
+ TELEGESIS_ERROR_0F("Fatal error initialising the network"),
+ TELEGESIS_ERROR_10("Error bootloading"),
+ TELEGESIS_ERROR_12("Fatal error initialising the stack"),
+ TELEGESIS_ERROR_18("Node has run out of Buffers"),
+ TELEGESIS_ERROR_19("Trying to write read-only register"),
+ TELEGESIS_ERROR_1A("Data Mode Refused by Remote Node"),
+ TELEGESIS_ERROR_1B("Connection Lost in Data Mode"),
+ TELEGESIS_ERROR_1C("Remote node is already in Data Mode"),
+ TELEGESIS_ERROR_20("Invalid password"),
+ TELEGESIS_ERROR_25("Cannot form network"),
+ TELEGESIS_ERROR_27("No network found"),
+ TELEGESIS_ERROR_28("Operation cannot be completed if node is part of a PAN"),
+ TELEGESIS_ERROR_2C("Error leaving the PAN"),
+ TELEGESIS_ERROR_2D("Error scanning for PANs"),
+ TELEGESIS_ERROR_33("No response from the remote bootloader"),
+ TELEGESIS_ERROR_34("Target did not respond during cloning"),
+ TELEGESIS_ERROR_35("Timeout occurred during xCASTB"),
+ TELEGESIS_ERROR_39("MAC Transmit Queue is Full"),
+ TELEGESIS_ERROR_70("Invalid Operation"),
+ TELEGESIS_ERROR_72("More than 10 unicast messages were in flight at the same time"),
+ TELEGESIS_ERROR_74("Message too long"),
+ TELEGESIS_ERROR_80("ZDP Invalid Request Type"),
+ TELEGESIS_ERROR_81("ZDP Device not Found"),
+ TELEGESIS_ERROR_82("ZDP Invalid Endpoint"),
+ TELEGESIS_ERROR_83("ZDP Not Active"),
+ TELEGESIS_ERROR_84("ZDP Not Supported"),
+ TELEGESIS_ERROR_85("ZDP Timeout"),
+ TELEGESIS_ERROR_86("ZDP No Match"),
+ TELEGESIS_ERROR_87("ZDP Table Full"),
+ TELEGESIS_ERROR_88("ZDP No Entry"),
+ TELEGESIS_ERROR_89("ZDP No Descriptor"),
+ TELEGESIS_ERROR_91("Operation only possible if connected to a PAN"),
+ TELEGESIS_ERROR_93("Node is not part of a Network"),
+ TELEGESIS_ERROR_94("Cannot join network"),
+ TELEGESIS_ERROR_96("Mobile End Device Move to new Parent Failed"),
+ TELEGESIS_ERROR_98("Cannot join ZigBee 2006 Network as Router"),
+ TELEGESIS_ERROR_A1("More than 8 broadcasts were sent within 8 seconds"),
+ TELEGESIS_ERROR_AB("Trying to join, but no beacons could be heard"),
+ TELEGESIS_ERROR_AC("Network key was sent in the clear when trying to join secured"),
+ TELEGESIS_ERROR_AD("Did not receive Network Key"),
+ TELEGESIS_ERROR_AE("No Link Key received"),
+ TELEGESIS_ERROR_AF("Preconfigured Key Required"),
+ TELEGESIS_ERROR_C5("NWK Already Present"),
+ TELEGESIS_ERROR_C7("NWK Table Full"),
+ TELEGESIS_ERROR_C8("NWK Unknown Device"),
+ COMMUNICATION_ERROR("Communication error"),
+ NULL_RESPONSE("No expected response after timeout"),
+ BAD_RESPONSE("Unexpected response");
+ private final String message;
+
+ ErrorCode305(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Prompt305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Prompt305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/Prompt305.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,148 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol;
+
+import java.nio.charset.Charset;
+
+/**
+ *
+ * @author alvaro
+ */
+public enum Prompt305 {
+
+ //OK("OK", 2, false, false), //OK
+ //ERROR("ERROR", 8, true, false), //ERROR:XX
+ //SEQ("SEQ", 6, true, false), //SEQ:XX
+ ACK("ACK", 6, true, false), //ACK:XX
+ NACK("NACK", 7, true, false), //NACK:XX
+ ROUTE_RECORD("SR", 27, true, false), //SR:XX,<EUI64>,<nodeId>
+ BROADCAST_RECEIVED("BCAST", 0, true, true), // BCAST:[<EUI64>,]XX=<data>
+ MULTICAST_RECEIVED("MCAST", 0, true, true), // MCAST:[<EUI64>,]XX=<data>
+ UNICAST_RECEIVED("UCAST", 0, true, true), // UCAST:[<EUI64>,]XX=<data>
+ SINK_DATA_MESSAGE("SDATA", 32, true, false), //{NO BIEN DOCUMENTADO} SDATA:[<EUI64>],<ioread>,<A/D1>,<A/D2>, <sequenceNo>,<Vcc>
+ SINK_DATA_MESSAGE_FN0130("FN0130", 32, true, false), //{NO BIEN DOCUMENTADO}FN0130:[<EUI64>,]<NodeID>,<ioread>,<sequence no>,<S46>[,<A/D1>][,<A/D2>][,<A/D3>][,<A/D4>]
+ COO_ANNOUNCE("COO", 25, true, false), //COO:<EUI64>,<nodeId>
+ FFD_ANNOUNCE("FFD", 25, true, false), //FFD:<EUI64>,<nodeId>
+ SED_ANNOUNCE("SED", 25, true, false), //SED:<EUI64>,<nodeId>
+ MED_ANNOUNCE("MED", 25, true, false), //MED:<EUI64>,<nodeId>
+ ZED_ANNOUNCE("ZED", 25, true, false), //ZED:<EUI64>,<nodeId>
+ NEWNODE_ANNOUNCE("NEWNODE", 34, true, false), //NEWNODE:<EUI64>,<nodeId>,<parent nodeId>
+ LEFT_PAN("LeftPAN", 7, false, false), //LeftPAN
+ LOST_PAN("LostPAN", 7, false, false), //LostPAN
+ JOIN_PAN("JPAN", 29, true, false), //JPAN:<channel>,<PID>,<EPID>
+ SINK_SELECTED("SINK", 26, true, false), //SINK:<EUI64>,<NodeID>
+ SINK_ANNOUCE("ADSK", 26, true, false), //ADSK:<EUI64>,<NodeID>
+ REGISTER_READ("SREAD", 33, true, false), //SREAD:<NodeID>,<EUI64>,<Register>,<errorcode>[=<Data>]
+ REGISTER_WRITE("SWRITE", 31, true, false), //SWRITE:<NodeID>,<EUI64>,<errorcode>
+ DATA_MODE("DataMODE", 30, true, false), //DataMODE:<NodeID>,<EUI64>
+ DATA_MODE_RESPONSE("DataMODE", 33, true, false), //DataMODE:<NodeID>,<EUI64>,<errorcode>
+ DATA_MODE_OPEN("OPEN", 4, false, false), //OPEN
+ DATA_MODE_CLOSED("CLOSED", 6, false, false), //CLOSED
+ TRACKING_MESSAGE("TRACK", 87, true, false), //{NO BIEN DOCUMENTADO} TRACK:<EUI64 R>,<EUI64 S>,<RSSI>, <i/o read>,<AD1>,<AD2>,<Vcc>,<S46>
+ TRACKING_MESSAGE_2("TRACK2", 61, true, false), //{NO BIEN DOCUMENTADO} TRACK2:<EUI64 R>,<EUI64 S>,<RSSI>,<I/O read>,<S46>
+ POWER_CHANGE("PWRCHANGE", 14, true, false), //PWRCHANGE:XXXX
+ END_POINT_MESSAGE("RX", 41, true, true), //RX:<EUI64>,<NodeID>,<profileID>, <destinationEndpoint>,<SourceEndpoint>,<clusterID>,<length>:<payload>
+ REPORT_WARNING("NM", 20, true, false), //NM:ES REPORT WARNING
+ ENTERING_BOOTLOAD("ENTERING BLOAD", 14, false, false), //ENTERING BLOAD
+ NEIGHBOUR_TABLE_RESPONSE("NTable", 14, true, false), //NTable:<NodeID>,<errorcode>...
+ //ROUTE_TABLE_RESPONSE("RTable", 14, true, false), //RTable:<NodeID>,<errorcode>...
+ ADDR_RESPONSE("AddrResp", 11, true, false), //AddrResp:<errorcode>[,<NodeID>,<EUI64>]
+ NODE_DESC_RESPONSE("NodeDesc", 16, true, false), //NodeDesc:<NodeID>[,<errorcode> | ...]
+ POWER_DESC_RESPONSE("PowerDesc", 17, true, false), //PowerDesc:<NodeID>,<errorcode>[,PowerDescriptor]
+ ACTIVE_EP_RESPONSE("ActEpDesc", 17, true, false), //ActEpDesc:<NodeID>,<errorcode>[,XX,...]
+ EP_SIMPLE_DESC_RESPONSE("SimpleDesc", 18, true, false), //SimpleDesc:<NodeID>,<errorcode> ...
+ NODES_MATCH_DESC_RESPONSE("MatchDesc", 17, true, false); //MatchDesc:<NodeID>,<errorcode>,XX,...
+ //
+ private final String prompt;
+ private final int minSize;
+ private final boolean hasParameters;
+ private final boolean hasData;
+
+ /**
+ *
+ * @param prompt Cadena de texto correspondiente
+ * @param minSize Tamaño mÃnimo del mensaje, o posición que ocupa el campo de datos si es distinto de cero
+ * @param hasData indica si tiene un campo de datos
+ */
+ Prompt305(String prompt, int minSize, boolean hasParameters, boolean hasData) {
+ this.prompt = prompt;
+ this.minSize = minSize;
+ this.hasParameters = hasParameters;
+ this.hasData = hasData;
+ }
+
+ /**
+ * Comprueba si el mensaje proporcionado corresponde al promt
+ * @param message Mensaje a comprobar
+ * @param startPos Posicion de inicio de búsqueda
+ * @return
+ */
+ public boolean chekMessage(byte[] message, int startPos) {
+ // componemos cadena de comparacion
+ String testPrompt = prompt;
+ if (hasParameters) {
+ testPrompt += SpecialSequence305.COMMAND_SEPARATOR.getText();
+ }
+ byte[] sequence = testPrompt.getBytes(Charset.forName("ISO-8859-1"));
+
+ // comprobamos tamaño
+ if (message.length < sequence.length + startPos) {
+ return false;
+ }
+ // comprobamos secuencia
+ for (int i = 0; i < sequence.length; i++) {
+ // si no coincide la secuencia en un carácter, devolvemos FALSE
+ if (message[startPos + i] != sequence[i]) {
+ return false;
+ }
+ }
+ // si hemos llegado aquÃ, coincide la secuencia, devolvemos TRUE
+ return true;
+
+
+ }
+
+ public String getText() {
+ return prompt;
+ }
+
+ /**
+ * representación en bytes de la cadena de texto del mensaje
+ * @return
+ */
+ public byte[] getBytes() {
+ return prompt.getBytes(Charset.forName("ISO-8859-1"));
+ }
+
+ /**
+ * Tamaño del mensaje (o tamaño mÃnimo), para mensajes de longitud fija.
+ * Para mensajes que tienen un campo de datos, si el valor es distinto de
+ * cero indica la posición del parámetro que indica la longitud de los datos
+ * @return Tamaño o posición de los datos
+ */
+ public int getMinSize() {
+ return minSize;
+ }
+
+ /**
+ * Indica si tiene un campo de datos de longitud variable
+ * @return TRUE si tiene campo de datos
+ */
+ public boolean getHasData() {
+ return hasData;
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/SpecialSequence305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/SpecialSequence305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/protocol/SpecialSequence305.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,50 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol;
+
+import java.nio.charset.Charset;
+
+/**
+ *
+ * @author alvaro
+ */
+public enum SpecialSequence305 {
+
+ COMMAND_OK("OK"),
+ COMMAND_ERROR("ERROR"),
+ SEQUENCE_NUMBER("SEQ"),
+ COMMAND_SEPARATOR(":"),
+ PASSWORD_SEPARATOR(":"),
+ PARAMETER_SEPARATOR(","),
+ REGISTER_QUERY("?"),
+ DATA_SEPARATOR("="),
+ CMD_END("\r"),
+ FRAME_SEPARATOR("\r\n");
+ private final String sequence;
+
+ SpecialSequence305(String sequence) {
+ this.sequence = sequence;
+ }
+
+ public String getText() {
+ return sequence;
+ }
+
+ public byte[] getBytes(){
+ return sequence.getBytes(Charset.forName("ISO-8859-1"));
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/LICENSE
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/LICENSE (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/main/resources/LICENSE Thu Feb 2 13:18:52 2012
@@ -1,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/CnxListenerTest.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/CnxListenerTest.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/CnxListenerTest.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,162 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import java.nio.charset.Charset;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.SerialListener;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.SpecialSequence305;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author alvaro
+ */
+public class CnxListenerTest {
+
+ public CnxListenerTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of hasNewFrames method, of class SerialListener.
+ */
+ //@Test
+ public void testprocessIncommingMessage() {
+ System.out.println("testprocessIncommingMessage");
+ SerialListener instance = new SerialListener(new SerialListener.MessageParser() {
+ @Override
+ public void hasNewPromps() {
+ //throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void serialPortError() {
+ //throw new UnsupportedOperationException("Not supported yet.");
+ }
+ });
+ String EUI64 = "1122334455667788";
+ String nodeID = "1122";
+ String PID = "1122";
+ String EPID = "1122334455667788";
+ //String msgData = "123\r\n678";
+ String msgData = "12345678";
+ String[] testMessages = new String[]{
+ "TRACK2:" + EUI64 + "," + EUI64 + ",00,12341234,12341234",
+ "RX:" + EUI64 + "," + nodeID + ",0011,01,01,0123,08:0011223344556677",
+ //"OK", //(se ha eliminado de la lista de prompts)
+ //"ERROR:01", //(se ha eliminado de la lista de prompts)
+ //"TELEGESIS ETRX2\r\nR305X\r\n000D6F0000945F79\r\n\r\nOK",
+ //"ERROR:01\r\n\r\nERROR:03", //(se ha eliminado de la lista de prompts)
+ "ACK:01",
+ "NACK:01",
+ //"SEQ:01",
+ "SR:01," + EUI64 + "," + nodeID,
+ "BCAST:05=12345",
+ "UCAST:" + EUI64 + ",05=123\r\n",
+ "UCAST:" + EUI64 + ",05=\r\n123",
+ "BCAST:" + EUI64 + ",05=12345",
+ "MCAST:" + EUI64 + ",05=12345",
+ "UCAST:" + EUI64 + ",05=12345",
+ //
+ //"ERROR:XX", //(se ha eliminado de la lista de prompts)
+ "ACK:XX",
+ "NACK:XX",
+ "SR:XX," + EUI64 + "," + nodeID,
+ "BCAST:08=" + msgData,
+ "BCAST:" + EUI64 + ",08=" + msgData,
+ "MCAST:08=" + msgData,
+ "MCAST:" + EUI64 + ",08=" + msgData,
+ "UCAST:08=" + msgData,
+ "UCAST:" + EUI64 + ",08=" + msgData,
+ "SDATA:12341234,12341234,12341234,01,12341234",
+ "SDATA:" + EUI64 + ",12341234,12341234,12341234,01,12341234",
+ "FN0130:" + nodeID + ",12341234,01,12341234",
+ "FN0130:" + nodeID + ",12341234,01,12341234,12341234,12341234,12341234,12341234",
+ "FN0130:" + EUI64 + "," + nodeID + ",12341234,01,12341234",
+ "FN0130:" + EUI64 + "," + nodeID + ",12341234,01,12341234,12341234,12341234,12341234,12341234",
+ "COO:" + EUI64 + "," + nodeID,
+ "FFD:" + EUI64 + "," + nodeID,
+ "SED:" + EUI64 + "," + nodeID,
+ "MED:" + EUI64 + "," + nodeID,
+ "ZED:" + EUI64 + "," + nodeID,
+ "NEWNODE:" + EUI64 + "," + nodeID + "," + nodeID,
+ "LeftPAN",
+ "LostPAN",
+ "JPAN:11," + PID + "," + EPID,
+ "SINK:" + EUI64 + "," + nodeID,
+ "ADSK:" + EUI64 + "," + nodeID,
+ "SREAD:" + nodeID + "," + EUI64 + ",00,02",
+ "SREAD:" + nodeID + "," + EUI64 + ",00,00=0800",
+ "SWRITE:" + nodeID + "," + EUI64 + ",00",
+ "DataMODE:" + nodeID + "," + EUI64,
+ "DataMODE:" + nodeID + "," + EUI64 + ",00",
+ "OPEN",
+ "CLOSED",
+ "TRACK:" + EUI64 + "," + EUI64 + ",00,12341234,12341234,12341234,12341234,12341234",
+ "TRACK2:" + EUI64 + "," + EUI64 + ",00,12341234,12341234",
+ "PWRCHANGE:XXXX",
+ "AddrResp:02",
+ "AddrResp:00," + nodeID + "," + EUI64,
+ "NTable:" + nodeID + ",00\r\nLength:02\r\nNo. | Dev | EUI | ID | LQI\r\n00. | FFD | 000D6F000086F533 | 8FC6 | FF\r\n01. | FFD | 000D6F0000354A07 | CF8E | FF",
+ //"ACK:31\r\n\r\nSR:00,000D6F000086F533,8FC6\r\n\r\nRTable:8FC6,00\r\nLength:40\r\nNo. | Dest | Next | Status00. | 0000 | 0000 | 38\r\n01. | 0000 | 0000 | 03\r\n02. | 0000 | 0000 | 03\r\n03. | 0000 | 0000 | 03\r\n04. | 0000 | 0000 | 03\r\n05. | 0000 | 0000 | 03\r\n06. | 0000 | 0000 | 03\r\n07. | 0000 | 0000 | 03\r\n08. | 0000 | 0000 | 03\r\n09. | 0000 | 0000 | 03\r\n10. | 0000 | 0000 | 03\r\n11. | 0000 | 0000 | 03\r\n12. | 0000 | 0000 | 03\r\n13. | 0000 | 0000 | 03\r\n14. | 0000 | 0000 | 03",
+ "ACK:35\r\n\r\nNodeDesc:0000,00\r\nType:COO\r\nComplexDesc:No\r\nUserDesc:No\r\nAPSFlags:00\r\nFreqBand:40\r\nMacCap:8F\r\nManufCode:1010\r\nMaxBufSize:52\r\nMaxInSize:0080\r\nSrvMask:0000\r\nMaxOutSize:0080\r\nDescCap:00",
+ "ACK:38\r\n\r\nPowerDesc:0000,00,C110",
+ "ACK:3B\r\n\r\nActEpDesc:0000,00,01",
+ "ACK:41\r\n\r\nSimpleDesc:0000,00\r\nEP:01\r\nProfileID:C091\r\nDeviceID:0001v05\r\nInCluster:0002,0003,000B,000D\r\nOutCluster:0002,0004,0006,000B,000D",
+ "MatchDesc:0000,00,01\r\n\r\nSR:00,000D6F000086F533,8FC6\r\n\r\nMatchDesc:8FC6,00,01",
+ "RX:" + EUI64 + "," + nodeID + ",0011,01,01,0123,08:12345678",
+ "NM:ES REPORT WARNING",
+ "ENTERING BLOAD",};
+
+ for (int i = 0; i < testMessages.length; i++) {
+ String testMessage = SpecialSequence305.FRAME_SEPARATOR.getText() + testMessages[i] + SpecialSequence305.FRAME_SEPARATOR.getText();
+ instance.processIncommingMessage(testMessage.getBytes(Charset.forName("ISO-8859-1")));
+ String frame = instance.getNextPrompt();
+ String wholeFrame = "";
+ while (frame != null) {
+ wholeFrame += SpecialSequence305.FRAME_SEPARATOR.getText() + frame + SpecialSequence305.FRAME_SEPARATOR.getText();
+ frame = instance.getNextPrompt();
+ }
+ if (!wholeFrame.equals(SpecialSequence305.FRAME_SEPARATOR.getText() + testMessages[i] + SpecialSequence305.FRAME_SEPARATOR.getText())) {
+ System.out.println("Enviado: " + SpecialSequence305.FRAME_SEPARATOR.getText() + testMessages[i] + SpecialSequence305.FRAME_SEPARATOR.getText());
+ System.out.println("Recibido: " + wholeFrame);
+ fail("No coincide lo enviado y lo recibido");
+ }
+ //assertEquals(testMessages[i],frame);
+ }
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeGatewayListener.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeGatewayListener.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeGatewayListener.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,777 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import java.nio.charset.Charset;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.GatewayListener;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.ZigbeeDeviceType;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.NeighbourTableEntry;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class FakeGatewayListener implements GatewayListener {
+
+ Gateway gtwy = null;
+ String lastCommand;
+ short seqNumber;
+ boolean wasACK;
+ String EUI64Addr;
+ String payload;
+ int numHops;
+ String[] route;
+ String message;
+ String messageType;
+ ZigbeeDeviceType devType;
+ String nodeID;
+ String parentID;
+ int RSSI;
+ short LQI;
+ int channel;
+ String PID;
+ String EPID;
+ String data;
+ short errorCode;
+ short register;
+ int neighbourTableLength;
+ NeighbourTableEntry[] neighbourTable;
+ Map nodeDescriptor;
+ String powerDescriptor;
+ short[] EPList;
+ short EP;
+ short destEP;
+ short sourceEP;
+ String profileID;
+ String clusterID;
+ String DeviceID;
+ String[] inClusterList;
+ String[] outClusterList;
+ String command;
+ String[] parameters;
+
+ private void sleep() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(FakeGatewayListener.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+
+ /**
+ * Notifies about acknowledgement of a node communication operation,
+ * providing SEQ number and acknowledge result (ACK/NACK)
+ * @param seqNumber SEQ number
+ * @param wasOK True for ACK, false for NACK
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void acknowledgement(short seqNumber, boolean wasACK, Gateway gtwy) {
+ System.out.println("acknowledgement");
+ lastCommand = "acknowledgement";
+ this.seqNumber = seqNumber;
+ this.wasACK = wasACK;
+ this.gtwy = gtwy;
+ }
+
+ public void checkAcknowledgementError(short seqNumber, boolean wasACK, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("acknowledgement")) {
+ fail("acknowledgement");
+ } else if (seqNumber != this.seqNumber) {
+ fail("seqNumber: " + this.seqNumber);
+ } else if (wasACK != this.wasACK) {
+ fail("wasACK: " + this.wasACK);
+ } else if (wasACK != this.wasACK) {
+ fail("wasACK: " + this.wasACK);
+ }
+ }
+
+ /**
+ * Notifies about a route to a remote device found
+ * @param EUI64Addr Remote node address
+ * @param numHops Number of hops
+ * @param route Array containing network addresses of intermediate nodes up
+ * to remote node, excluding local node
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void routeRecordReceived(String EUI64Addr, int numHops, String[] route, Gateway gtwy) {
+ System.out.println("routeRecordReceived");
+ lastCommand = "routeRecordReceived";
+ this.gtwy = gtwy;
+ this.EUI64Addr = EUI64Addr;
+ this.numHops = numHops;
+ this.route = route;
+ }
+
+ public void checkRouteRecordReceived(String EUI64Addr, int numHops, String[] route, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("routeRecordReceived")) {
+ fail("routeRecordReceived");
+ } else if (!EUI64Addr.equals(this.EUI64Addr)) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (numHops != this.numHops) {
+ fail("numHops: " + this.numHops);
+ } else if (!Arrays.equals(route, this.route)) {
+ fail("route: " + this.route);
+ }
+ }
+
+ /**
+ * Notifies about reception of a broadcast message
+ * @param EUI64Addr Sender address
+ * @param message Message received
+ */
+ @Override
+ public void broadcastMessageReceived(String EUI64Addr, byte[] message, Gateway gtwy) {
+ System.out.println("broadcastMessageReceived");
+ lastCommand = "broadcastMessageReceived";
+ this.gtwy = gtwy;
+ this.EUI64Addr = (EUI64Addr != null ? EUI64Addr : "");
+ this.message = new String(message,Charset.forName("ISO-8859-1"));
+ }
+
+ public void checkBroadcastMessageReceived(String EUI64Addr, byte[] message, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("broadcastMessageReceived")) {
+ fail("broadcastMessageReceived");
+ } else if (!this.EUI64Addr.equals((EUI64Addr != null ? EUI64Addr : ""))) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (!Arrays.equals(message, this.message.getBytes(Charset.forName("ISO-8859-1")))) {
+ fail("message: " + this.message);
+ }
+ }
+
+ /**
+ * Notifies about reception of a message, whether it was a broadcast message
+ * multicast or unicast
+ * @param EUI64Addr Sender address
+ * @param message Message received
+ * @param messageType Message messageType
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void messageReceived(String EUI64Addr, byte[] message, String type, Gateway gtwy) {
+ System.out.println("messageReceived");
+ lastCommand = "messageReceived";
+ this.gtwy = gtwy;
+ this.EUI64Addr = (EUI64Addr != null ? EUI64Addr : "");
+ this.message = new String(message,Charset.forName("ISO-8859-1"));
+ this.messageType = type;
+ }
+
+ public void checkMessageReceived(String EUI64Addr, byte[] message, String type, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("messageReceived")) {
+ fail("messageReceived");
+ } else if (!this.EUI64Addr.equals((EUI64Addr != null ? EUI64Addr : ""))) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (!Arrays.equals(message, this.message.getBytes(Charset.forName("ISO-8859-1")))) {
+ fail("message: " + this.message);
+ } else if (!type.equals(this.messageType)) {
+ fail("type: " + this.messageType);
+ }
+ }
+
+ /**
+ * Notifies about reception of a message not handled by Telegesis dongle,
+ * providing whole APS frame
+ * @param EUI64Addr Sender address
+ * @param nodeID Sender network address
+ * @param sourceEP Sender EndPoint id
+ * @param destEP Receiver EndPoint id
+ * @param profileID profileID
+ * @param clusterID ClusterID
+ * @param payload Message received
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void endpointMessageReceived(String EUI64Addr, String nodeID, short sourceEP, short destEP, String profileID, String clusterID, byte[] payload, Gateway gtwy){
+ System.out.println("endpointMessageReceived");
+ lastCommand = "endpointMessageReceived";
+ this.gtwy = gtwy;
+ this.EUI64Addr = (EUI64Addr != null ? EUI64Addr : "");
+ this.nodeID = nodeID;
+ this.sourceEP = sourceEP;
+ this.destEP = destEP;
+ this.profileID = profileID;
+ this.clusterID = clusterID;
+ this.payload = new String(payload,Charset.forName("ISO-8859-1"));
+
+ }
+
+ public void checkendpointMessageReceived(String EUI64Addr, String nodeID, short sourceEP, short destEP, String profileID, String clusterID, byte[] payload, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("endpointMessageReceived")) {
+ fail("endpointMessageReceived");
+ } else if (!this.EUI64Addr.equals((EUI64Addr != null ? EUI64Addr : ""))) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (!this.nodeID.equals(nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (this.sourceEP !=sourceEP) {
+ fail("sourceEP: " + this.sourceEP + " received: "+ sourceEP);
+ } else if (this.destEP !=destEP) {
+ fail("destEP: " + this.destEP);
+ } else if (!this.profileID.equals(profileID)) {
+ fail("profileID: " + this.profileID);
+ } else if (!this.clusterID.equals(clusterID)) {
+ fail("clusterID: " + this.clusterID);
+ } else if (!this.payload.equals(new String(payload,Charset.forName("ISO-8859-1")))) {
+ fail("payload: " + this.payload + " received: " + new String(payload,Charset.forName("ISO-8859-1")));
+ }
+ }
+
+ /**
+ * Notifies about a node announce
+ * @param messageType DeviceType (COO, FFD...)
+ * @param EUI64Addr Node's address
+ * @param nodeID Node's network address
+ * @param RSSI RSSI level (dBm) of the last hop
+ * @param LQI LQI indicator of the last hop
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void nodeAnnounce(ZigbeeDeviceType type, String EUI64Addr, String nodeID, int RSSI, short LQI, Gateway gtwy) {
+ System.out.println("nodeAnnounce");
+ lastCommand = "nodeAnnounce";
+ this.gtwy = gtwy;
+ this.devType = type;
+ this.EUI64Addr = EUI64Addr;
+ this.nodeID = nodeID;
+ this.RSSI = RSSI;
+ this.LQI = LQI;
+ }
+
+ public void checkNodeAnnounce(ZigbeeDeviceType type, String EUI64Addr, String nodeID, int RSSI, short LQI, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("nodeAnnounce")) {
+ fail("nodeAnnounce");
+ } else if (!type.equals(this.devType)) {
+ fail("type: " + this.devType);
+ } else if (!EUI64Addr.equals(this.EUI64Addr)) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (RSSI != this.RSSI) {
+ fail("RSSI: " + this.RSSI);
+ } else if (LQI != this.LQI) {
+ fail("LQI: " + this.LQI);
+ }
+ }
+
+ /**
+ * Notifies about a new node
+ * @param EUI64Addr Node's address
+ * @param nodeID Node's network address
+ * @param parentID Parent's network address or null
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void newNode(String EUI64Addr, String nodeID, String parentID, Gateway gtwy) {
+ System.out.println("newNode");
+ lastCommand = "newNode";
+ this.gtwy = gtwy;
+ this.EUI64Addr = EUI64Addr;
+ this.nodeID = nodeID;
+ this.parentID = (parentID == null ? "" : parentID);
+ }
+
+ public void checkNewNode(String EUI64Addr, String nodeID, String parentID, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("newNode")) {
+ fail("newNode");
+ } else if (!EUI64Addr.equals(this.EUI64Addr)) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (!this.parentID.equals((parentID == null ? "" : parentID))) {
+ fail("parentID: " + this.parentID);
+ }
+ }
+
+ /**
+ * Notifies about local node left PAN
+ * Note: also notifies about end device losing parent
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void leftPAN(Gateway gtwy) {
+ System.out.println("leftPAN");
+ lastCommand = "leftPAN";
+ this.gtwy = gtwy;
+ }
+
+ public void checkLeftPAN(Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("leftPAN")) {
+ fail("leftPAN");
+ }
+ }
+
+ /**
+ * Notifies about local node joining PAN
+ * @param channel Network channel (ranging from 0x0B to 0x1A)
+ * @param PID Network PID
+ * @param EPID Network EPID
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void joinedPan(int channel, String PID, String EPID, Gateway gtwy) {
+ System.out.println("joinedPan");
+ lastCommand = "joinedPan";
+ this.gtwy = gtwy;
+ this.channel = channel;
+ this.PID = PID;
+ this.EPID = EPID;
+ }
+
+ public void checkJoinedPan(int channel, String PID, String EPID, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("joinedPan")) {
+ fail("joinedPan");
+ } else if (channel != this.channel) {
+ fail("channel: " + this.channel);
+ } else if (!PID.equals(this.PID)) {
+ fail("PID: " + this.PID);
+ } else if (!EPID.equals(this.EPID)) {
+ fail("EPID: " + this.EPID);
+ }
+ }
+
+ /**
+ * Notifies about operation result of writing on a register
+ * @param nodeID Node's network address
+ * @param EUI64Addr Node's address
+ * @param errorCode Operation result
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void registerWrited(String nodeID, String EUI64Addr, short errorCode, Gateway gtwy) {
+ System.out.println("registerWrited");
+ lastCommand = "registerWrited";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.EUI64Addr = EUI64Addr;
+ this.errorCode = errorCode;
+ }
+
+ public void checkRegisterWrited(String nodeID, String EUI64Addr, short errorCode, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("registerWrited")) {
+ fail("registerWrited");
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (!EUI64Addr.equals(this.EUI64Addr)) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ }
+ }
+
+ /**
+ * Notifies about reading of a register
+ * @param nodeID Node's network address
+ * @param EUI64Addr Node's address
+ * @param register Register readed
+ * @param errorCode Operation result
+ * @param data Register contents
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void registerReaded(String nodeID, String EUI64Addr, short register, short errorCode, String data, Gateway gtwy) {
+ System.out.println("registerReaded");
+ lastCommand = "registerReaded";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.EUI64Addr = EUI64Addr;
+ this.register = register;
+ this.errorCode = errorCode;
+ this.data = (data == null ? "" : data);
+ }
+
+ public void checkRegisterReaded(String nodeID, String EUI64Addr, short register, short errorCode, String data, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("registerReaded")) {
+ fail("registerReaded");
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (!EUI64Addr.equals(this.EUI64Addr)) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ } else if (register != this.register) {
+ fail("register: " + this.register);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (!this.data.equals((data == null ? "" : data))) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ }
+ }
+
+ /**
+ * Notifies response about an address request to a node
+ * @param errorCode request result
+ * @param nodeID Node's network address
+ * @param EUI64Addr Node's address
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void addrResponse(short errorCode, String nodeID, String EUI64Addr, Gateway gtwy) {
+ System.out.println("addrResponse");
+ lastCommand = "addrResponse";
+ this.gtwy = gtwy;
+ this.errorCode = errorCode;
+ this.nodeID = (nodeID == null ? "" : nodeID);
+ this.EUI64Addr = (EUI64Addr == null ? "" : EUI64Addr);
+ }
+
+ public void checkAddrResponse(short errorCode, String nodeID, String EUI64Addr, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("addrResponse")) {
+ fail("addrResponse");
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (!this.nodeID.equals((nodeID == null ? "" : nodeID))) {
+ fail("nodeID: " + this.nodeID);
+ } else if (!this.EUI64Addr.equals((EUI64Addr == null ? "" : EUI64Addr))) {
+ fail("EUI64Addr: " + this.EUI64Addr);
+ }
+ }
+
+ /**
+ * Notifies about a Neighbour table request response.
+ * Note: tableLength != table.length() means there are records pending to
+ * receive (if requested)
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param tableLength Total neighbour table
+ * @param table received records
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void neighbourTableResponse(String nodeID, short errorCode, int tableLength, NeighbourTableEntry[] table, Gateway gtwy) {
+ System.out.println("neighbourTableResponse");
+ lastCommand = "neighbourTableResponse";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.errorCode = errorCode;
+ this.neighbourTableLength = tableLength;
+ this.neighbourTable = table;
+ }
+
+ public void checkNeighbourTableResponse(String nodeID, short errorCode, int tableLength, NeighbourTableEntry[] table, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("neighbourTableResponse")) {
+ fail("neighbourTableResponse");
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (!Arrays.equals(table, this.neighbourTable)) {
+ fail("neighbourTable: " + this.neighbourTable);
+ } else if (tableLength != this.neighbourTableLength) {
+ fail("neighbourTableLength: " + this.neighbourTableLength);
+ }
+ }
+
+ /**
+ * Notifies about a node descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param descriptor Map containig pairs <key,value> of related descriptor
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void nodeDescriptorResponse(String nodeID, short errorCode, Map descriptor, Gateway gtwy) {
+ System.out.println("nodeDescriptorResponse");
+ lastCommand = "nodeDescriptorResponse";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.errorCode = errorCode;
+ this.nodeDescriptor = descriptor;
+ }
+
+ public void checkNodeDescriptorResponse(String nodeID, short errorCode, Map descriptor, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("nodeDescriptorResponse")) {
+ fail("nodeDescriptorResponse: " + lastCommand);
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (!descriptor.equals(this.nodeDescriptor)) {
+ fail("nodeDescriptor: " + this.nodeDescriptor);
+ }
+ }
+
+ /**
+ * Notifies about a node descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param descriptor power descriptor
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void powerDescriptorResponse(String nodeID, short errorCode, String descriptor, Gateway gtwy) {
+ System.out.println("powerDescriptorResponse");
+ lastCommand = "powerDescriptorResponse";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.errorCode = errorCode;
+ this.powerDescriptor = (descriptor == null ? "" : descriptor);
+ }
+
+ public void checkPowerDescriptorResponse(String nodeID, short errorCode, String descriptor, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("powerDescriptorResponse")) {
+ fail("powerDescriptorResponse: " + lastCommand);
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (!this.powerDescriptor.equals((descriptor == null ? "" : descriptor))) {
+ fail("powerDescriptor: " + this.powerDescriptor);
+ }
+ }
+
+ /**
+ * Notifies about a node descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param EPList EndPoint list
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void nodeActiveEPResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ System.out.println("nodeActiveEPResponse");
+ lastCommand = "nodeActiveEPResponse";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.errorCode = errorCode;
+ this.EPList = EPList;
+ }
+
+ public void checkNodeActiveEPResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("nodeActiveEPResponse")) {
+ fail("nodeActiveEPResponse");
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (EPList == null) {
+ if (this.EPList != null) {
+ fail("EPList: " + this.EPList);
+ } else if (!Arrays.equals(EPList, this.EPList)) {
+ fail("EPList: " + this.EPList);
+ }
+ }
+ }
+
+ /**
+ * Notifies about a node EndPoint simple descriptor request response
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param EP EndPoint requested
+ * @param profileID
+ * @param DeviceID
+ * @param inClusterList String array containing supported in cluster
+ * @param outClusterList String array containing supported out cluster
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void nodeEndPointSimpleDescriptorResponse(String nodeID,
+ short errorCode,
+ short EP, String ProfileID, String DeviceID, String[] inClusterList, String[] outClusterList, Gateway gtwy) {
+ System.out.println("nodeEndPointSimpleDescriptorResponse");
+ lastCommand = "nodeEndPointSimpleDescriptorResponse";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.errorCode = errorCode;
+ this.EP = EP;
+ this.profileID = ProfileID;
+ this.DeviceID = DeviceID;
+ this.inClusterList = inClusterList;
+ this.outClusterList = outClusterList;
+
+ }
+
+ public void checkNodeEndPointSimpleDescriptorResponse(String nodeID, short errorCode, short EP, String ProfileID, String DeviceID, String[] inClusterList, String[] outClusterList, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("nodeEndPointSimpleDescriptorResponse")) {
+ fail("nodeEndPointSimpleDescriptorResponse");
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (!ProfileID.equals(this.profileID)) {
+ fail("ProfileID: " + this.profileID);
+ } else if (!DeviceID.equals(this.DeviceID)) {
+ fail("DeviceID: " + this.DeviceID);
+ } else if (!Arrays.equals(inClusterList, this.inClusterList)) {
+ fail("inClusterList: " + this.inClusterList);
+ } else if (!Arrays.equals(outClusterList, this.outClusterList)) {
+ fail("outClusterList: " + this.outClusterList);
+ }
+ }
+
+ /**
+ * Notifies about a node matching a previous descriptor request response
+ * NOTE: profile
+ * @param nodeID Node's network address
+ * @param errorCode request result
+ * @param EPList EndPoint list
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void nodeMatchingDescriptorResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ System.out.println("nodeMatchingDescriptorResponse");
+ lastCommand = "nodeMatchingDescriptorResponse";
+ this.gtwy = gtwy;
+ this.nodeID = nodeID;
+ this.errorCode = errorCode;
+ this.EPList = EPList;
+
+ }
+
+ public void checkNodeMatchingDescriptorResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("nodeMatchingDescriptorResponse")) {
+ fail("nodeMatchingDescriptorResponse");
+ } else if (!nodeID.equals(this.nodeID)) {
+ fail("nodeID: " + this.nodeID);
+ } else if (errorCode != this.errorCode) {
+ fail("errorCode: " + this.errorCode);
+ } else if (EPList == null) {
+ if (this.EPList != null) {
+ fail("EPList: " + this.EPList);
+ } else if (!Arrays.equals(EPList, this.EPList)) {
+ fail("EPList: " + this.EPList);
+ }
+ }
+ }
+
+ /**
+ * Notifies about and unhandled telegesis command:
+ * - SDATA
+ * - FN0130
+ * - SINK
+ * - ADSK
+ * - DataMODE
+ * - OPEN
+ * - CLOSED
+ * - TRACK
+ * - TRACK2
+ * - PWRCHANGE
+ * - RX
+ * - NM
+ * - ENTERING BLOAD
+ * @param command not handled command
+ * @param parameters command parameters list
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void unhandledCommand(String command, String[] parameters, Gateway gtwy) {
+ System.out.println("unhandledCommand");
+ lastCommand = "unhandledCommand";
+ this.gtwy = gtwy;
+ this.command = command;
+ this.parameters = parameters;
+
+ }
+
+ public void checkUnhandledCommand(String command, String[] parameters, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("unhandledCommand")) {
+ fail("unhandledCommand");
+ } else if (!command.equals(this.command)) {
+ fail("command: " + this.command);
+ } else if (!Arrays.equals(parameters, this.parameters)) {
+ fail("parameters: " + this.parameters);
+ }
+ }
+
+ /**
+ * Notifies about unknonwn incomming messages
+ * @param message
+ * @param gtwy Gateway launching notification
+ */
+ @Override
+ public void unknownMessage(String message, Gateway gtwy) {
+ System.out.println("unknownMessage");
+ lastCommand = "unknownMessage";
+ this.gtwy = gtwy;
+ this.message = message;
+
+ }
+
+ public void checkUnknownMessage(String message, Gateway gtwy) {
+ sleep(); // para dar tiempo a que se procesen los eventos
+ if (!gtwy.equals(this.gtwy)) {
+ fail("gateway");
+ } else if (!lastCommand.equals("unknownMessage")) {
+ fail("unknownMessage (received: " + lastCommand + ")");
+ } else if (!message.equals(this.message)) {
+ fail("message: " + this.message);
+ }
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeSerialPort.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeSerialPort.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/FakeSerialPort.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,155 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import es.unizar.howlab.core.io.serial.*;
+import java.nio.charset.Charset;
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class FakeSerialPort implements SerialConnection {
+
+ private boolean isPortOpen = false;
+ private boolean isBlocked = false;
+ SerialConnectionConfig config = null;
+ SerialConnectionListener serialListener = null;
+ LinkedBlockingDeque<byte[]> messages = new LinkedBlockingDeque<byte[]>();
+
+ @Override
+ public boolean open() {
+ isPortOpen = true;
+ return true;
+ }
+
+ @Override
+ public boolean close() {
+ isPortOpen = false;
+ return true;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return isPortOpen;
+ }
+
+ @Override
+ public int writeMessage(byte[] bytes) {
+ System.out.println(">>>>" + new String(bytes));
+ String testATI = new String(bytes,Charset.forName("ISO-8859-1"));
+ if (testATI.equals("ATI\r")) {
+ String ATI_RESPONSE = "\r\nTELEGESIS ETRX2\r\nR305X\r\n000D6F0000945F79\r\n\r\nOK\r\n";
+ injectMessage(ATI_RESPONSE.getBytes(Charset.forName("ISO-8859-1")));
+ } else if (testATI.equals("ATS0E=8000\r")) {
+ injectMessage("\r\nOK\r\n".getBytes(Charset.forName("ISO-8859-1")));
+ } else if (testATI.equals("ATS0F=0106\r")) {
+ injectMessage("\r\nOK\r\n".getBytes(Charset.forName("ISO-8859-1")));
+ } else if (testATI.equals("ATS1204=1\r")) {
+ injectMessage("\r\nOK\r\n".getBytes(Charset.forName("ISO-8859-1")));
+ } else {
+ messages.add(bytes);
+ }
+ return 0;
+ }
+
+ @Override
+ public int writeString(String string) {
+ return writeMessage(string.getBytes(Charset.forName("ISO-8859-1")));
+ }
+
+ @Override
+ public void blockWriting(int milliseconds) {
+ isBlocked = true;
+ }
+
+ @Override
+ public boolean unblockWriting() {
+ isBlocked = false;
+ return true;
+ }
+
+ @Override
+ public boolean tryBlockWriting(int milliseconds) {
+ isBlocked = true;
+ return true;
+ }
+
+ @Override
+ public boolean setConfiguration(SerialConnectionConfig scc) {
+ config = scc;
+ return true;
+ }
+
+ @Override
+ public SerialConnectionConfig getConfiguration() {
+ return config;
+ }
+
+ @Override
+ public boolean registerListener(SerialConnectionListener sl) {
+ this.serialListener = sl;
+ return true;
+ }
+
+ @Override
+ public boolean unregisterListener(SerialConnectionListener sl) {
+ this.serialListener = null;
+ return true;
+ }
+
+ public class SerialMessageImpl implements SerialMessage {
+
+ final byte[] message;
+
+ public SerialMessageImpl(byte[] msg) {
+ message = msg;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.messageReceived;
+ }
+
+ @Override
+ public byte[] getBinaryMessage() {
+ return message;
+ }
+
+ @Override
+ public String getMessage(){
+ return new String(message,Charset.forName("ISO-8859-1"));
+ }
+ }
+
+ public void injectMessage(byte[] message) {
+ if (serialListener != null) {
+ System.out.println("<<<<" + new String(message));
+ SerialMessage sm = new SerialMessageImpl(message);
+ serialListener.eventMessage(sm, this);
+ }
+ }
+
+ public String getLastMessageWrited() {
+ return new String(messages.poll(),Charset.forName("ISO-8859-1"));
+ }
+
+ public void clearMessagesWrited() {
+ messages.clear();
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305Test.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305Test.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-gateway-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/gateway/impl/Gateway305Test.java Thu Feb 2 13:18:52 2012
@@ -1,0 +1,1600 @@
+/*
+ * Copyright 2011-2012 HOWLab. http://howlab.unizar.es/
+ * Human OpenWare Research Lab. Universidad Zaragoza
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package es.unizar.howlab.core.zigbee.telegesis.gateway.impl;
+
+import java.nio.charset.Charset;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.TelegesisErrorException;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.ZigbeeDeviceType;
+import java.util.Map;
+//import es.unizar.howlab.core.zigbee.telegesis.gateway30x.*;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.*;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.Command305;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.impl.protocol.SpecialSequence305;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author alvaro
+ */
+public class Gateway305Test {
+
+ class MessageInjector implements Runnable {
+
+ final FakeSerialPort port;
+ ArrayList messages = new ArrayList();
+ ArrayList delays = new ArrayList();
+
+ public MessageInjector(FakeSerialPort sp) {
+ port = sp;
+ }
+
+ public void addMessage(String message, int delay) {
+ messages.add(message);
+ delays.add(new Long(delay));
+ }
+
+ @Override
+ public void run() {
+
+
+ Iterator itM = messages.iterator();
+ Iterator itD = delays.iterator();
+ while (itM.hasNext()) {
+ Long delay = (Long) itD.next();
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(Gateway305Test.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ String message = (String) itM.next();
+ port.injectMessage(message.getBytes(Charset.forName("ISO-8859-1")));
+ }
+ }
+ }
+ static final String ATI_RESPONSE = "\r\nTELEGESIS ETRX2\r\nR305X\r\n000D6F0000945F79\r\n\r\nOK\r\n";
+ static final String PID = "1030";
+ static final String EPID = "1122334455667788";
+ static final String EUI64Addr = "1122334455667788";
+ static final String msgData = "12345";
+ static final String nodeID = "1122";
+ static final int channel = 20;
+ static final String OK_FRAME = "\r\nOK\r\n";
+ static final String SEQ_FRAME_1A = "\r\nSEQ:1A\r\n";
+ static final String SEQ_FRAME_FA = "\r\nSEQ:FA\r\n";
+ Gateway305 testGateway;
+ FakeSerialPort sp;
+
+ public Gateway305Test() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ }
+
+ @Before
+ public void setUp() {
+ // puerto serie virtual
+ sp = new FakeSerialPort();
+ testGateway = new Gateway305(sp);
+ System.out.println("creando gateway...");
+// MessageInjector mi = new MessageInjector(sp);
+// mi.addMessage(ATI_RESPONSE, 5);
+// Thread th = new Thread(mi);
+// th.start();
+ testGateway.open();
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of open method, of class Gateway305.
+ */
+ @Test
+ public void testOpen() {
+ System.out.println("test open");
+ // comprobamos gateway abierto
+ if (!testGateway.isOpen()) {
+ fail("error al abrir el gateway");
+ }
+ }
+
+ /**
+ * Test of GetProductId method, of class Gateway305.
+ */
+ @Test
+ public void testGetProductId() {
+ System.out.println("test getProductId");
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(ATI_RESPONSE, 10);
+ Thread th = new Thread(mi);
+ th.start();
+ String[] response = testGateway.getProductId();
+ System.out.println("DeviceName: " + response[0]);
+ System.out.println("FirmwareVersion: " + response[1]);
+ System.out.println("EUI64Addr: " + response[2]);
+ }
+
+ /**
+ * Test of reset method, of class Gateway305.
+ */
+ @Test
+ public void testReset() {
+ System.out.println("reset");
+ sp.clearMessagesWrited();
+ testGateway.reset();
+ String msgWrited = sp.getLastMessageWrited();
+ String msgExpected = Command305.SOFTWARE_RESET.getText() + SpecialSequence305.CMD_END.getText();
+ if (!msgWrited.equals(msgExpected)) {
+ fail("Enviado: " + msgWrited + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of restoreFactoryDefaults method, of class Gateway305.
+ */
+ @Test
+ public void testRestoreFactoryDefaults() {
+ System.out.println("restoreFactoryDefaults");
+
+ sp.clearMessagesWrited();
+ testGateway.restoreFactoryDefaults();
+ String msgWrited = sp.getLastMessageWrited();
+ String msgExpected = Command305.RESTORE_FACTORY_DEFAULTS.getText() + SpecialSequence305.CMD_END.getText();
+ if (!msgWrited.equals(msgExpected)) {
+ fail("Enviado: " + msgWrited + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of readRegister method, of class Gateway305.
+ */
+ @Test
+ public void testReadRegister() throws Exception {
+ System.out.println("readRegister");
+
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\n3FFC\r\n\r\nOK\r\n", 10);
+ mi.addMessage("\r\n<hidden>\r\n\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short reg = (short) 0xFC;
+ String response = testGateway.readRegister(reg);
+ if (!response.equals("3FFC")) {
+ fail("Enviado: 3FFC Esperado: " + response);
+ }
+ reg = 0x08;
+ response = testGateway.readRegister(reg);
+ if (!response.equals("<hidden>")) {
+ fail("Enviado: <hidden> Esperado: " + response);
+ }
+ }
+
+ /**
+ * Test of writeRegister method, of class Gateway305.
+ */
+ @Test
+ public void testWriteRegister_byte_String() throws Exception {
+ System.out.println("writeRegister");
+
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nOK\r\n", 10);
+ mi.addMessage("\r\nERROR:20\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short reg = 0x0C;
+ try {
+ testGateway.writeRegister(reg, "password");
+ } catch (TelegesisErrorException ex) {
+ fail("excepcion: " + ex.getErrorMessage());
+ }
+ boolean exception = true;
+ try {
+ testGateway.writeRegister(reg, "password");
+ } catch (TelegesisErrorException ex) {
+ exception = false;
+ System.out.println("excepcion error: " + ex.getErrorMessage());
+ }
+ if (exception) {
+ fail("no ha saltado exception");
+ }
+ }
+
+ /**
+ * Test of writeRegister method, of class Gateway305.
+ */
+ @Test
+ public void testWriteRegister_3args() throws Exception {
+ System.out.println("writeRegister");
+
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nOK\r\n", 10);
+ mi.addMessage("\r\nERROR:20\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short reg = 0x0C;
+ try {
+ testGateway.writeRegister(reg, "newpassword", "password");
+ } catch (TelegesisErrorException ex) {
+ fail("excepcion: " + ex.getErrorMessage());
+ }
+ boolean exception = false;
+ try {
+ testGateway.writeRegister(reg, "newpassword", "password");
+ } catch (TelegesisErrorException ex) {
+ exception = true;
+ System.out.println("excepcion error: " + ex.getErrorMessage());
+ }
+ if (!exception) {
+ fail("no ha saltado exception");
+ }
+ }
+
+ /**
+ * Test of readRemoteRegisterRequest method, of class Gateway305.
+ */
+ @Test
+ public void testReadRemoteRegisterRequest() throws Exception {
+ System.out.println("readRemoteRegisterRequest");
+
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nSEQ:A1\r\n\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short reg = 0x0C;
+ short response = testGateway.readRemoteRegisterRequest("0025", reg);
+ if (!String.format("%02X", response).equals("A1")) {
+ fail("Enviado: A1 Recibido: " + String.format("%02X", response));
+ }
+ }
+
+ /**
+ * Test of writeRemoteRegisterRequest method, of class Gateway305.
+ */
+ @Test
+ public void testWriteRemoteRegisterRequest_3args() throws Exception {
+ System.out.println("writeRemoteRegisterRequest");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ short regAddress = 0x1A;
+ String regData = "0800";
+ mi.addMessage("\r\nSEQ:A1\r\n\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short result = testGateway.writeRemoteRegisterRequest(EUI64Addr, regAddress, regData);
+ short expResult = (short) 0xA1;
+ // comparamos seq recibido
+ if (result != expResult) {
+ fail("recibido: " + result + " Esperado: " + expResult);
+ }
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "ATREMS:" + EUI64Addr + ",1A=0800\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of writeRemoteRegisterRequest method, of class Gateway305.
+ */
+ @Test
+ public void testWriteRemoteRegisterRequest_4args() throws Exception {
+ System.out.println("writeRemoteRegisterRequest");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ String password = "tecnodis";
+ short regAddress = 0x1A;
+ String regData = "0800";
+ mi.addMessage("\r\nSEQ:A1\r\n\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short result = testGateway.writeRemoteRegisterRequest(EUI64Addr, regAddress, regData, password);
+ short expResult = (short) 0xA1;
+ // comparamos seq recibido
+ if (result != expResult) {
+ fail("recibido: " + result + " Esperado: " + expResult);
+ }
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "ATREMS:1122334455667788,1A=0800,tecnodis\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of scanEnergy method, of class Gateway305.
+ */
+ @Test
+ public void testScanEnergy() throws Exception {
+ System.out.println("scanEnergy");
+
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\n+ESCAN:\r\n11:AA\r\n12:A9\r\n13:0C\r\n14:0D\r\n26:FF\r\n\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ short[] response = testGateway.scanEnergy();
+ short[] expectedResp = new short[16];
+ expectedResp[0] = (short) 0xAA;
+ expectedResp[1] = (short) 0xA9;
+ expectedResp[2] = (short) 0x0C;
+ expectedResp[3] = (short) 0x0D;
+ expectedResp[15] = (short) 0xFF;
+ for (int i = 0; i < 16; i++) {
+ if (response[i] != expectedResp[i]) {
+ fail("Canal " + i + " Recibido: " + response[i] + " Esperado: " + expectedResp[i]);
+ }
+ }
+
+ }
+
+ /**
+ * Test of scanForActivePANs method, of class Gateway305.
+ */
+ @Test
+ public void testScanForActivePANs() throws Exception {
+ System.out.println("scanForActivePANs");
+
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\n+PANSCAN:13,1030,60D52B879671815F,02,01\r\n", 1000);
+ mi.addMessage("\r\n+PANSCAN:20,1702,9261A18566C329AD,02,01\r\n", 1000);
+ mi.addMessage("\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+ PANScanResult[] response = testGateway.scanForActivePANs();
+ PANScanResult[] expectedResp = new PANScanResult[2];
+ expectedResp[0] = new PANScanResult((short) 13, "1030", "60D52B879671815F", (short) 02, true);
+ expectedResp[1] = new PANScanResult((short) 20, "1702", "9261A18566C329AD", (short) 02, true);
+ for (int i = 0; i < 2; i++) {
+ if ((response[i].getChannel() != expectedResp[i].getChannel())
+ || (response[i].getJoinPermission() != expectedResp[i].getJoinPermission())
+ || (!response[i].getPANID().equals(expectedResp[i].getPANID()))
+ || (!response[i].getEPID().equals(expectedResp[i].getEPID()))
+ || (response[i].getProfile() != expectedResp[i].getProfile())) {
+ fail("Canal " + i + " Recibido: " + response[i] + " Esperado: " + expectedResp[i]);
+ }
+
+ }
+ }
+
+ @Test
+ public void testPrompts() {
+
+ FakeGatewayListener fgl = new FakeGatewayListener();
+ testGateway.registerListener(fgl);
+ String message;
+
+ // ACK, NACK
+ message = "ACK:FF";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkAcknowledgementError((short) 0xFF, true, testGateway);
+ message = "NACK:01";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkAcknowledgementError((short) 0x01, false, testGateway);
+
+ // SR:XX,<EUI64>,<NodeID>,
+ message = "SR:02," + EUI64Addr + ",1001,1002";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkRouteRecordReceived(EUI64Addr, 02, new String[]{"1001", "1002"}, testGateway);
+
+
+ String[] dataArray = new String[]{"1234567890", "=23:4,5,"};
+ for (int j = 0; j < dataArray.length; j++) {
+ String data = dataArray[j];
+ // UCAST:[<EUI64>,]XX=<data>
+ // MCAST:[<EUI64>,]XX=<data>
+ String[] msgType = new String[]{"UCAST", "MCAST"};
+ for (int i = 0; i < 2; i++) {
+ message = String.format("%s:%s,%02X=%s", msgType[i], EUI64Addr, data.length(), data);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkMessageReceived(EUI64Addr, data.getBytes(Charset.forName("ISO-8859-1")), msgType[i], testGateway);
+ message = String.format("%s:%02X=%s", msgType[i], data.length(), data);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkMessageReceived(null, data.getBytes(Charset.forName("ISO-8859-1")), msgType[i], testGateway);
+
+ }
+ // BCAST:[<EUI64>,]XX=<data>
+ message = String.format("BCAST:%s,%02X=%s", EUI64Addr, data.length(), data);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkBroadcastMessageReceived(EUI64Addr, data.getBytes(Charset.forName("ISO-8859-1")), testGateway);
+ message = String.format("BCAST:%02X=%s", data.length(), data);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkBroadcastMessageReceived(null, data.getBytes(Charset.forName("ISO-8859-1")), testGateway);
+ }
+
+ //"COO:" + EUI64Addr + "," + nodeID,
+ //"FFD:" + EUI64Addr + "," + nodeID,
+ //"SED:" + EUI64Addr + "," + nodeID,
+ //"MED:" + EUI64Addr + "," + nodeID,
+ //"ZED:" + EUI64Addr + "," + nodeID,
+ short LQI = (short) 0xFF;
+ int RSSI = -70;
+
+ message = String.format("COO:%s,%s,%d,%02X", EUI64Addr, nodeID, RSSI, LQI);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeAnnounce(ZigbeeDeviceType.Coordinator, EUI64Addr, nodeID, RSSI, LQI, testGateway);
+ message = String.format("FFD:%s,%s,%d,%02X", EUI64Addr, nodeID, RSSI, LQI);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeAnnounce(ZigbeeDeviceType.Router, EUI64Addr, nodeID, RSSI, LQI, testGateway);
+ message = String.format("ZED:%s,%s,%d,%02X", EUI64Addr, nodeID, RSSI, LQI);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeAnnounce(ZigbeeDeviceType.EndDevice, EUI64Addr, nodeID, RSSI, LQI, testGateway);
+ message = String.format("SED:%s,%s,%d,%02X", EUI64Addr, nodeID, RSSI, LQI);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeAnnounce(ZigbeeDeviceType.SleepyEndDevice, EUI64Addr, nodeID, RSSI, LQI, testGateway);
+ message = String.format("MED:%s,%s,%d,%02X", EUI64Addr, nodeID, RSSI, LQI);
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeAnnounce(ZigbeeDeviceType.MobileEndDevice, EUI64Addr, nodeID, RSSI, LQI, testGateway);
+
+ //"NEWNODE:" + EUI64Addr + "," + nodeID + "," + nodeID,
+ message = "NEWNODE:" + nodeID + "," + EUI64Addr + "," + nodeID;
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNewNode(EUI64Addr, nodeID, nodeID, testGateway);
+
+ // LeftPAN
+ message = "LeftPAN";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkLeftPAN(testGateway);
+ message = "LostPAN";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkLeftPAN(testGateway);
+
+ // JPAN:<channel>,<PID>,<EPID>
+ message = "JPAN:" + channel + "," + PID + "," + EPID;
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkJoinedPan(channel, PID, EPID, testGateway);
+
+ //SREAD:<NodeID>,<EUI64>,<Register>, <errorcode>[=<Data>]
+ message = "SREAD:" + nodeID + "," + EUI64Addr + ",0B,00=1234";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkRegisterReaded(nodeID, EUI64Addr, (short) 0x0B, (short) 00, "1234", testGateway);
+ message = "SREAD:" + nodeID + "," + EUI64Addr + ",0B,02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkRegisterReaded(nodeID, EUI64Addr, (short) 0x0B, (short) 02, null, testGateway);
+
+ //SWRITE:<NodeID>,<EUI64>,<errorcode>
+ message = "SWRITE:" + nodeID + "," + EUI64Addr + ",00";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkRegisterWrited(nodeID, EUI64Addr, (short) 00, testGateway);
+ message = "SWRITE:" + nodeID + "," + EUI64Addr + ",02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkRegisterWrited(nodeID, EUI64Addr, (short) 02, testGateway);
+
+ //AddrResp:<errorcode>[,<NodeID>,<EUI64>]
+ message = "AddrResp:00," + nodeID + "," + EUI64Addr;
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkAddrResponse((short) 0, nodeID, EUI64Addr, testGateway);
+ message = "AddrResp:02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkAddrResponse((short) 02, null, null, testGateway);
+
+
+ //NTable...
+ message = "NTable:" + nodeID + ",00\r\n"
+ + "Length:02\r\n"
+ + "No. | Dev | EUI | ID | LQI\r\n"
+ + "00. | FFD | " + EUI64Addr + " | 1122 | FF\r\n"
+ + "01. | FFD | " + EUI64Addr + " | 1122 | FF";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ NeighbourTableEntry[] nti = new NeighbourTableEntry[2];
+ for (int i = 0; i < 2; i++) {
+ nti[i] = new NeighbourTableEntry((short) i, ZigbeeDeviceType.Router, EUI64Addr, "1122", (short) 0xFF);
+ }
+ fgl.checkNeighbourTableResponse(nodeID, (short) 0, 2, nti, testGateway);
+
+ message = "NTable:" + nodeID + ",02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNeighbourTableResponse(nodeID, (short) 2, 0, null, testGateway);
+
+ //NodeDesc
+ message = "NodeDesc:" + nodeID + ",00\r\n"
+ + "NodeDesc:0D57\r\n"
+ + "Type:FFD\r\n"
+ + "ComplexDesc:No\r\n"
+ + "UserDesc:No\r\n"
+ + "APSFlags:00\r\n"
+ + "FreqBand:40\r\n"
+ + "MacCap:8E\r\n"
+ + "ManufCode:1010\r\n"
+ + "MaxBufSize:52\r\n"
+ + "MaxInSize:0080\r\n"
+ + "SrvMask:0000\r\n"
+ + "MaxOutSize:0080\r\n"
+ + "DescCap:00";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ Map descriptor = new HashMap();
+ descriptor.put("NodeDesc", "0D57");
+ descriptor.put("Type", "FFD");
+ descriptor.put("ComplexDesc", "No");
+ descriptor.put("UserDesc", "No");
+ descriptor.put("APSFlags", "00");
+ descriptor.put("FreqBand", "40");
+ descriptor.put("MacCap", "8E");
+ descriptor.put("ManufCode", "1010");
+ descriptor.put("MaxBufSize", "52");
+ descriptor.put("MaxInSize", "0080");
+ descriptor.put("SrvMask", "0000");
+ descriptor.put("MaxOutSize", "0080");
+ descriptor.put("DescCap", "00");
+ fgl.checkNodeDescriptorResponse(nodeID, (short) 0, descriptor, testGateway);
+
+ //PowerDesc:<NodeID>,<errorcode> [,<PowerDescriptor>]
+ message = "PowerDesc:" + nodeID + ",00,1111";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkPowerDescriptorResponse(nodeID, (short) 0, "1111", testGateway);
+ message = "PowerDesc:" + nodeID + ",02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkPowerDescriptorResponse(nodeID, (short) 02, null, testGateway);
+
+ //ActEpDesc:<NodeID>,<errorcode>[,XX,...]
+ message = "ActEpDesc:" + nodeID + ",00,00,01";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ short[] EPList = new short[]{0, 1};
+ fgl.checkNodeActiveEPResponse(nodeID, (short) 0, EPList, testGateway);
+ message = "ActEpDesc:" + nodeID + ",02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeActiveEPResponse(nodeID, (short) 02, new short[0], testGateway);
+
+ //SimpleDesc:<NodeID>,<errorcode> EP:XX ProfileID:XXXX DeviceID:XXXXvXX InCluster:<Cluster List> OutCluster:<Cluster List>
+ String profile = "0110";
+ String DeviceId = "0110v32";
+ message = "SimpleDesc:" + nodeID + ",00\r\n"
+ + "EP:01\r\n"
+ + "ProfileID:" + profile + "\r\n"
+ + "DeviceID:" + DeviceId + "\r\n"
+ + "InCluster:0020\r\n"
+ + "OutCluster:0020,0021";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeEndPointSimpleDescriptorResponse(nodeID, (short) 0, (short) 1, profile, DeviceId, new String[]{"0020"}, new String[]{"0020", "0021"}, testGateway);
+
+ message = "SimpleDesc:" + nodeID + ",00\r\n"
+ + "EP:01\r\n"
+ + "ProfileID:" + profile + "\r\n"
+ + "DeviceID:" + DeviceId + "\r\n"
+ + "InCluster:\r\n"
+ + "OutCluster:";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeEndPointSimpleDescriptorResponse(nodeID, (short) 0, (short) 1, profile, DeviceId, null, null, testGateway);
+
+ //MatchDesc:<NodeID>,<errorcode>,XX,â¦
+ message = "MatchDesc:" + nodeID + ",00,01,02";
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkNodeMatchingDescriptorResponse(nodeID, (short) 0, new short[]{0, 1}, testGateway);
+
+ //RX:<EUI64>,<NodeID>,<profileID>, <destinationEndpoint>,<SourceEndpoint>,<clusterID>,<length>:<payload>
+ String[] payloads = new String[]{"12345", "123455678901224", "::3,=00"};
+ String profileID = "1002";
+ short sourceEP = 0x01;
+ short destEP = 0x0F;
+ String clusterID = "1002";
+ for (int i = 0; i < payloads.length; i++) {
+ String payload = payloads[i];
+ message = String.format("RX:%s,%s,%s,%02X,%02X,%s,%02X:%s", EUI64Addr, nodeID, profileID, destEP, sourceEP, clusterID, payload.length(), payload);
+// message = "RX:" + EUI64Addr + "," + nodeID + ",1002,00,F4,1002," + String.format("%02X", payload.length()) + ":" + payload;
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+// fgl.checkendpointMessageReceived(EUI64Addr, nodeID, (short) 0xF4, (short) 0, "1002", "1002", payload.getBytes(Charset.forName("ISO-8859-1")), testGateway);
+ fgl.checkendpointMessageReceived(EUI64Addr, nodeID, sourceEP, destEP, profileID, clusterID, payload.getBytes(Charset.forName("ISO-8859-1")), testGateway);
+
+ }
+
+ /**
+ * Notifies about and unhandled telegesis command:
+ * - SDATA
+ * - FN0130
+ * - SINK
+ * - ADSK
+ * - DataMODE
+ * - OPEN
+ * - CLOSED
+ * - TRACK
+ * - TRACK2
+ * - PWRCHANGE
+ * - RX
+ * - NM
+ * - ENTERING BLOAD
+ * @param command not handled command
+ * @param parameters command parameters list
+ * @param gtwy Gateway launching notification
+ */
+ String[] unhandledPrompts = new String[]{
+ "SDATA:12341234,12341234,12341234,01,12341234",
+ "SDATA:" + EUI64Addr + ",12341234,12341234,12341234,01,12341234",
+ "FN0130:" + nodeID + ",12341234,01,12341234",
+ "FN0130:" + nodeID + ",12341234,01,12341234,12341234,12341234,12341234,12341234",
+ "FN0130:" + EUI64Addr + "," + nodeID + ",12341234,01,12341234",
+ "FN0130:" + EUI64Addr + "," + nodeID + ",12341234,01,12341234,12341234,12341234,12341234,12341234",
+ "SINK:" + EUI64Addr + "," + nodeID,
+ "ADSK:" + EUI64Addr + "," + nodeID,
+ "DataMODE:" + nodeID + "," + EUI64Addr,
+ "DataMODE:" + nodeID + "," + EUI64Addr + ",00",
+ "OPEN",
+ "CLOSED",
+ "TRACK:" + EUI64Addr + "," + EUI64Addr + ",00,12341234,12341234,12341234,12341234,12341234",
+ "TRACK2:" + EUI64Addr + "," + EUI64Addr + ",00,12341234,12341234",
+ "PWRCHANGE:XXXX",
+ "NM:ES REPORT WARNING",
+ "ENTERING BLOAD"
+ };
+ for (int i = 0; i < unhandledPrompts.length; i++) {
+ message = unhandledPrompts[i];
+ String[] messageSplited = message.split(":");
+ String command = messageSplited[0];
+ String[] parameters;
+ if (messageSplited.length == 2) {
+ parameters = messageSplited[1].split(",");
+ } else {
+ parameters = new String[0];
+ }
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkUnhandledCommand(command, parameters, testGateway);
+
+ }
+
+ /**
+ * Notifies about unknonwn incomming messages
+ * @param message
+ * @param gtwy Gateway launching notification
+ */
+ String[] unknonwMessages = new String[]{
+ "AA_SDATA:12341234,12341234,12341234,01,12341234",
+ "AA_SDATA:" + EUI64Addr + ",12341234,12341234,12341234,01,12341234",
+ "AA_FN0130:" + nodeID + ",12341234,01,12341234",
+ "AA_FN0130:" + nodeID + ",12341234,01,12341234,12341234,12341234,12341234,12341234",
+ "AA_FN0130:" + EUI64Addr + "," + nodeID + ",12341234,01,12341234",
+ "AA_FN0130:" + EUI64Addr + "," + nodeID + ",12341234,01,12341234,12341234,12341234,12341234,12341234",
+ "AA_SINK:" + EUI64Addr + "," + nodeID,
+ "AA_ADSK:" + EUI64Addr + "," + nodeID,
+ "AA_DataMODE:" + nodeID + "," + EUI64Addr,
+ "AA_DataMODE:" + nodeID + "," + EUI64Addr + ",00",
+ "AA_OPEN",
+ "AA_CLOSED",
+ "AA_TRACK:" + EUI64Addr + "," + EUI64Addr + ",00,12341234,12341234,12341234,12341234,12341234",
+ "AA_TRACK2:" + EUI64Addr + "," + EUI64Addr + ",00,12341234,12341234",
+ "AA_PWRCHANGE:XXXX",
+ "AA_RX:" + EUI64Addr + "," + nodeID + ",0011,01,01,0123,08:12345678",
+ "AA_NM:ES REPORT WARNING",
+ "AA_ENTERING BLOAD"
+ };
+ for (int i = 0; i < unknonwMessages.length; i++) {
+ message = unknonwMessages[i];
+ sp.injectMessage(("\r\n" + message + "\r\n").getBytes(Charset.forName("ISO-8859-1")));
+ fgl.checkUnknownMessage(message, testGateway);
+ }
+
+
+ }
+
+ /**
+ * Test of createNetwork method, of class Gateway305.
+ */
+ @Test
+ public void testCreateNetwork() throws Exception {
+ System.out.println("createNetwork");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nJPAN:11,011A,1122334455667788\r\n\r\nOK\r\n", 1000);
+ Thread th = new Thread(mi);
+ th.start();
+
+ NetworkJoinedInfo nji = testGateway.createNetwork();
+ if (!nji.getEPID().equals("1122334455667788")) {
+ fail("error EPID " + nji.getEPID());
+ } else if (!nji.getPANID().equals("011A")) {
+ fail("error PANID " + nji.getPANID());
+ } else if (nji.getChannel() != 11) {
+ fail("error channel " + nji.getChannel());
+
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+EN\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of joinNetwork method, of class Gateway305.
+ */
+ @Test
+ public void testJoinNetwork_0args() throws Exception {
+ System.out.println("joinNetwork");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nJPAN:11,011A,1122334455667788\r\n\r\nOK\r\n", 1000);
+ Thread th = new Thread(mi);
+ th.start();
+
+ NetworkJoinedInfo nji = testGateway.joinNetwork();
+ if (!nji.getEPID().equals("1122334455667788")) {
+ fail("error EPID " + nji.getEPID());
+ } else if (!nji.getPANID().equals("011A")) {
+ fail("error PANID " + nji.getPANID());
+ } else if (nji.getChannel() != 11) {
+ fail("error channel " + nji.getChannel());
+
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+JN\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of joinNetwork method, of class Gateway305.
+ */
+ @Test
+ public void testJoinNetwork_String_String() throws Exception {
+ System.out.println("joinNetwork");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nJPAN:20,011A,1122334455667788\r\n\r\nOK\r\n", 1000);
+ Thread th = new Thread(mi);
+ th.start();
+
+ NetworkJoinedInfo nji = testGateway.joinNetwork(20, "011A");
+ if (!nji.getEPID().equals("1122334455667788")) {
+ fail("error EPID " + nji.getEPID());
+ } else if (!nji.getPANID().equals("011A")) {
+ fail("error PANID " + nji.getPANID());
+ } else if (nji.getChannel() != 20) {
+ fail("error channel " + nji.getChannel());
+
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+JPAN:20,011A\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of leaveNetwork method, of class Gateway305.
+ */
+ @Test
+ public void testLeaveNetwork() throws Exception {
+ System.out.println("leaveNetwork");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.leaveNetwork();
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+DASSL\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of leaveNetworkRequest method, of class Gateway305.
+ */
+ @Test
+ public void testLeaveNetworkRequest() throws Exception {
+ System.out.println("leaveNetworkRequest");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\nSEQ:1A\r\n\r\nOK\r\n", 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ String address = "112234455667788";
+ short expResult = 0x1A;
+ short result = testGateway.leaveNetworkRequest(address);
+ if (result != expResult) {
+ fail("recibido: " + result + " Esperado: " + expResult);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+DASSR:" + address + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of getNetworkInformation method, of class Gateway305.
+ */
+ @Test
+ public void testGetNetworkInformation() {
+ System.out.println("getNetworkInformation");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage("\r\n+N=COO," + channel + ",A3," + PID + "," + EPID + "\r\n" + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ NetworkInformation expResult =
+ new NetworkInformation(ZigbeeDeviceType.Coordinator, channel, (short) 0xA3, PID, EPID);
+ NetworkInformation result = testGateway.getNetworkInformation();
+ if (result.getChannel() != expResult.getChannel()) {
+ fail("result.getChannel(): " + result.getChannel());
+ } else if (result.getPower() != expResult.getPower()) {
+ fail("result.getPower(): " + result.getPower());
+ } else if (result.getDeviceType() != expResult.getDeviceType()) {
+ fail("result.getDeviceType(): " + result.getDeviceType());
+ } else if (!result.getPID().equals(expResult.getPID())) {
+ fail("result.getPID(): " + result.getPID());
+ } else if (!result.getEPID().equals(expResult.getEPID())) {
+ fail("result.getEPID(): " + result.getEPID());
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+N?\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of requestNeighbourTable method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNeighbourTable_byte_String() throws Exception {
+ System.out.println("requestNeighbourTable");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short index = 0;
+ short expResult = 0x1A;
+ short result = testGateway.requestNeighbourTable(index, EUI64Addr);
+ if (result != expResult) {
+ fail("result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+NTABLE:00," + EUI64Addr + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of requestNodeId method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNodeId() throws Exception {
+ System.out.println("requestNodeId");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.requestNodeId(EUI64Addr);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+IDREQ:" + EUI64Addr + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of requestNodeEUI64Addr method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNodeEUI64Addr() throws Exception {
+ System.out.println("requestNodeEUI64Addr");
+ String nodeId = "1030";
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short expResult = 0x1A;
+ short result = testGateway.requestNodeEUI64Addr(EUI64Addr, nodeId);
+ if (result != expResult) {
+ fail("result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+EUIREQ:" + EUI64Addr + "," + nodeId + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of requestNodeDescriptor method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNodeDescriptor() throws Exception {
+ System.out.println("requestNodeDescriptor");
+ String nodeId = "1030";
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short expResult = 0x1A;
+ short result = testGateway.requestNodeDescriptor(EUI64Addr, nodeId);
+ if (result != expResult) {
+ fail("result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+NODEDESC:" + EUI64Addr + "," + nodeId + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of requestNodePowerDescriptor method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNodePowerDescriptor() throws Exception {
+ System.out.println("requestNodePowerDescriptor");
+ String nodeId = "1030";
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short expResult = 0x1A;
+ short result = testGateway.requestNodePowerDescriptor(EUI64Addr, nodeId);
+ if (result != expResult) {
+ fail("result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+POWERDESC:" + EUI64Addr + "," + nodeId + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of requestNodeActiveEndPoints method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNodeActiveEndPoints() throws Exception {
+ System.out.println("requestNodeActiveEndPoints");
+ String nodeId = "1030";
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short expResult = 0x1A;
+ short result = testGateway.requestNodeActiveEndPoints(EUI64Addr, nodeId);
+ if (result != expResult) {
+ fail("result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+ACTEPDESC:" + EUI64Addr + "," + nodeId + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of requestNodeEndPointSimpleDescriptor method, of class Gateway305.
+ */
+ @Test
+ public void testRequestNodeEndPointSimpleDescriptor() throws Exception {
+ System.out.println("requestNodeEndPointSimpleDescriptor");
+ short EP = 0x1A;
+ String nodeId = "1030";
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short expResult = 0x1A;
+ short result = testGateway.requestNodeEndPointSimpleDescriptor(EUI64Addr, nodeId, EP);
+ if (result != expResult) {
+ fail("result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+SIMPLEDESC:" + EUI64Addr + "," + nodeId + ",1A\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of findNodesMatchingDescriptor method, of class Gateway305.
+ */
+ @Test
+ public void testFindNodesMatchingDescriptor() throws Exception {
+ System.out.println("findNodesMatchingDescriptor");
+
+
+ String profileId = "C091";
+ String[] inClusterList = new String[]{"0002"};
+ String[] outClusterList = new String[]{"0004", "000B"};
+
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.findNodesMatchingDescriptor(profileId, inClusterList, outClusterList);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+MATCHREQ:C091,01,0002,02,0004,000B\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of annouceLocalNode method, of class Gateway305.
+ */
+ @Test
+ public void testAnnouceLocalNode() throws Exception {
+ System.out.println("annouceLocalNode");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.annouceLocalNode();
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+ANNCE\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of setSourceRoute method, of class Gateway305.
+ */
+ @Test
+ public void testSetSourceRoute() throws Exception {
+ System.out.println("setSourceRoute");
+ String destNode = "0100";
+ String[] route = new String[]{"0101", "0102"};
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.setSourceRoute(destNode, route);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+SR:0100,0101,0102\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of findRoute method, of class Gateway305.
+ */
+ @Test
+ public void testFindRoute() throws Exception {
+ System.out.println("findRoute");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.findRoute(EUI64Addr);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+FNDSR:" + EUI64Addr + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of scanNetwork method, of class Gateway305.
+ */
+ @Test
+ public void testScanNetwork() throws Exception {
+ System.out.println("scanNetwork");
+ int numHops = 02;
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.scanNetwork(numHops);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+SN:02\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of updateNetworkKey method, of class Gateway305.
+ */
+ @Test
+ public void testUpdateNetworkKey() throws Exception {
+ System.out.println("updateNetworkKey");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.updateNetworkKey();
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+KEYUPD\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of becomeTrustCenter method, of class Gateway305.
+ */
+ @Test
+ public void testBecomeTrustCenter() throws Exception {
+ System.out.println("becomeTrustCenter");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.becomeTrustCenter();
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+BECOMETC\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of becomeNetworkManager method, of class Gateway305.
+ */
+ @Test
+ public void testBecomeNetworkManager() throws Exception {
+ System.out.println("becomeNetworkManager");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.becomeNetworkManager();
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+BECOMENM\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of changeNetworkChannel method, of class Gateway305.
+ */
+ @Test
+ public void testChangeNetworkChannel_0args() throws Exception {
+ System.out.println("changeNetworkChannel");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.changeNetworkChannel();
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+CCHANGE\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of changeNetworkChannel method, of class Gateway305.
+ */
+ @Test
+ public void testChangeNetworkChannel_int() throws Exception {
+ System.out.println("changeNetworkChannel");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.changeNetworkChannel(channel);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+CCHANGE:" + String.format("%02d", channel) + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of getAddressTable method, of class Gateway305.
+ */
+ @Test
+ public void testGetAddressTable() {
+ System.out.println("getAddressTable");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ String cmdResponse1 = "\r\n"
+ + "No. | Active | ID | EUI\r\n"
+ + "00 | N | FFFF |FFFFFFFFFFFFFFFF\r\n"
+ + "01 | N | FFFF |FFFFFFFFFFFFFFFF\r\n"
+ + "02 | N | FFFF |FFFFFFFFFFFFFFFF\r\n";
+ String cmdResponse2 = "03 | N | FFFF |FFFFFFFFFFFFFFFF\r\n"
+ + "04 | N | FFFF |FFFFFFFFFFFFFFFF\r\n"
+ + "05 | N | FFFF |FFFFFFFFFFFFFFFF\r\n"
+ + OK_FRAME;
+ mi.addMessage(cmdResponse1, 10);
+ mi.addMessage(cmdResponse2, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+
+ AddressTableEntry[] result = testGateway.getAddressTable();
+ for (int i = 0; i < 6; i++) {
+ if (result[i].getIndex() != i) {
+ fail("AddressTableEntry[" + i + "].getIndex = " + result[i].getIndex());
+ } else if (result[i].getActive() != false) {
+ fail("AddressTableEntry[" + i + "].getActive = " + result[i].getActive());
+ } else if (!result[i].getID().equals("FFFF")) {
+ fail("AddressTableEntry[" + i + "].getID = " + result[i].getID());
+ } else if (!result[i].getEUI64Addr().equals("FFFFFFFFFFFFFFFF")) {
+ fail("AddressTableEntry[" + i + "].getEUI64Addr = " + result[i].getEUI64Addr());
+ }
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+ATABLE\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of setAddressTableEntry method, of class Gateway305.
+ */
+ @Test
+ public void testSetAddressTableEntry() throws Exception {
+ System.out.println("setAddressTableEntry");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short index = 01;
+
+ testGateway.setAddressTableEntry(index, nodeID, EUI64Addr);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+ASET:01," + nodeID + "," + EUI64Addr + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of getMulticastTable method, of class Gateway305.
+ */
+ @Test
+ public void testGetMulticastTable() {
+ System.out.println("getMulticastTable");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ String cmdResponse1 = "\r\n"
+ + "No. | ID | EP\r\n"
+ + "00 | 0000 | 01\r\n"
+ + "01 | 0000 | 01\r\n";
+ String cmdResponse2 = "02 | 0000 | 01\r\n"
+ + "03 | 0000 | 01\r\n"
+ + "04 | 0000 | 01\r\n"
+ + OK_FRAME;
+ String cmdResponse = "\r\n"
+ + "No. | ID | EP\r\n"
+ + "00 | 0000 | 01\r\n"
+ + "01 | 0000 | 01\r\n"
+ + "02 | 0000 | 01\r\n"
+ + "03 | 0000 | 01\r\n"
+ + "04 | 0000 | 01\r\n"
+ + OK_FRAME;
+// mi.addMessage(cmdResponse, 10);
+ mi.addMessage(cmdResponse1, 10);
+ mi.addMessage(cmdResponse2, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+
+ MulticastTableEntry[] result = testGateway.getMulticastTable();
+ for (int i = 1; i < 5; i++) {
+ if (result[i].getIndex() != i) {
+ fail("MulticastTableEntry[" + i + "].getIndex = " + result[i].getIndex());
+ } else if (!result[i].getID().equals("0000")) {
+ fail("AddressTableEntry[" + i + "].getID = " + result[i].getID());
+ } else if (result[i].getEP() != (short) 01) {
+ fail("AddressTableEntry[" + i + "].getEP = " + result[i].getEP());
+ }
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+MTABLE\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of setMulticastTableEntry method, of class Gateway305.
+ */
+ @Test
+ public void testSetMulticastTableEntry() throws Exception {
+ System.out.println("setMulticastTableEntry");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.setMulticastTableEntry((short) 01, "1234", (short) 01);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+MSET:01,1234,01\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of sendBroadcast method, of class Gateway305.
+ */
+ @Test
+ public void testSendBroadcast_int_String() throws Exception {
+ System.out.println("sendBroadcast");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.sendBroadcast((short) 01, "1234");
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+BCAST:01,1234\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of sendBroadcast method, of class Gateway305.
+ */
+ @Test
+ public void testSendBroadcast_int_byteArr() throws Exception {
+ System.out.println("sendBroadcast");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ testGateway.sendBroadcast((short) 01, "1234".getBytes(Charset.forName("ISO-8859-1")));
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+BCASTB:04,01\r1234\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+ }
+
+ /**
+ * Test of sendMessageRequest method, of class Gateway305.
+ */
+ @Test
+ public void testSendMessageRequest_String_String() throws Exception {
+ System.out.println("sendMessageRequest");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+// mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ mi.addMessage(SEQ_FRAME_FA + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short result = testGateway.sendMessageRequest(EUI64Addr, "1234");
+ if (result != (short) 0xFA) {
+ fail("recibido result: " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+UCAST:" + EUI64Addr + "=1234\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of sendMessageRequest method, of class Gateway305.
+ */
+ @Test
+ public void testSendMessageRequest_String_byteArr() throws Exception {
+ System.out.println("sendMessageRequest");
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(SEQ_FRAME_1A + OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+
+ short result = testGateway.sendMessageRequest(EUI64Addr, "1234".getBytes(Charset.forName("ISO-8859-1")));
+ if (result != 0x1A) {
+ fail("recibido result : " + result);
+ }
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+UCASTB:04," + EUI64Addr + "\r1234\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of sendMulticastBroadcast method, of class Gateway305.
+ */
+ @Test
+ public void testSendMulticastBroadcast_3args_1() throws Exception {
+ System.out.println("sendMulticastBroadcast");
+
+
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+ String ID = "1030";
+ String data = "12345";
+
+ testGateway.sendMulticastBroadcast(0, ID, data);
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+MCAST:00," + ID + "," + data + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+
+ /**
+ * Test of sendMulticastBroadcast method, of class Gateway305.
+ */
+ @Test
+ public void testSendMulticastBroadcast_3args_2() throws Exception {
+ System.out.println("sendMulticastBroadcast");
+ sp.clearMessagesWrited();
+ MessageInjector mi = new MessageInjector(sp);
+ mi.addMessage(OK_FRAME, 10);
+ Thread th = new Thread(mi);
+ th.start();
+ String ID = "1030";
+ String data = "12345";
+
+ testGateway.sendMulticastBroadcast(0, ID, data.getBytes(Charset.forName("ISO-8859-1")));
+
+ // comparamos mensaje enviado
+ String msgSent = sp.getLastMessageWrited();
+ String msgExpected = "AT+MCASTB:" + String.format("%02X", data.length()) + ",00," + ID + "\r" + data + "\r";
+ if (!msgSent.equals(msgExpected)) {
+ fail("Enviado: " + msgSent + " Esperado: " + msgExpected);
+ }
+
+ }
+}
More information about the Commit
mailing list