[zb4osgi-changeset] [scm] ZigBee 4 OSGi repository change: r405 - in /projects/zb4osgi/sandbox/howlab/telegesis-driver-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/driver/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/ src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/ 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/driver/ 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/driver/ src/test/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/
scm-notify at zb4osgi.aaloa.org
scm-notify at zb4osgi.aaloa.org
Thu Feb 2 13:18:42 CET 2012
Author: alvaro.marco
Date: Thu Feb 2 13:18:42 2012
New Revision: 405
Log:
howlab import
Added:
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/LICENSE
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/config.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.core.zigbee.telegesis.driver.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.io.serial.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/nbactions.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/pom.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/assembly/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/assembly/felix.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/AbstractDriver.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/Driver305.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/DriverFactory.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeDeviceImpl.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeNodeImpl.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/AbstractDriverMaintenanceTask.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ErrorCheckerDriverMaintenanceTask.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NeighbourFinderDriverMaintenanceTask.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NodeRegisterUpdaterDriverMaintenanceTask.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ParentFinderDriverMaintenanceTask.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ZigbeeDevicesFinderDriverMaintenanceTask.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/Activator.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/GatewayServiceTracker.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/ZigbeePublisher.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/AbstractGatewayListener.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrACK.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrActiveEndPoints.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrAddrResponse.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrEndPointDescriptor.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrNeighbourTableResponse.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterRead.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterWrited.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrSourceRoute.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/Register305.java
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/LICENSE
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/driver/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/driver/es.unizar.howlab.core.zigbee.telegesis.driver.xml
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/howlab/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/howlab/core/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/howlab/core/zigbee/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/driver/
projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/test/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/LICENSE
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/LICENSE (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/LICENSE Thu Feb 2 13:18:42 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-driver-impl/config.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/config.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/config.xml Thu Feb 2 13:18:42 2012
@@ -1,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Document : config.xml
+ Created on : 11 de agosto de 2011, 17:35
+ Author : alvaro
+ Description:
+ Purpose of the document follows.
+
+-->
+
+<root>
+ <es.unizar.howlab.core.zigbee.telegesis.driver>
+ <autostart>true</autostart><!-- Arranca el driver al crearlo -->
+
+ <ack_timeout>3000</ack_timeout><!-- Timeout para respuestas ACK -->
+ <register_read_timeout>3000</register_read_timeout><!-- Timeout para respuestas register_read -->
+ <register_write_timeout>3000</register_write_timeout><!-- Timeout para respuestas regiter_write -->
+ <zdo_response_timeout>3000</zdo_response_timeout><!-- Timeout para respuestas ZDO (ep_list, ep_descriptor) -->
+ <neighbour_response_timeout>10000</neighbour_response_timeout><!-- Timeout para respuestas de tabla de vecinos -->
+
+ <get_neighbours>true</get_neighbours><!-- Incluye la busqueda de vecinos en las tareas periódicas -->
+ <get_neighbours_frame_delay>5</get_neighbours_frame_delay><!-- Tiempo de separación entre nodos para busqueda de vecinos -->
+ <get_neighbours_recovery_period>5</get_neighbours_recovery_period> <!-- Periodo para reintentar las busquedas de vecinos fallidas -->
+ <get_neighbours_maintenance_period>60</get_neighbours_maintenance_period><!-- Periodo para actualizar los vecinos de los nodos -->
+
+ <get_parent>true</get_parent><!-- Incluye la busqueda del padre en las tareas periódicas -->
+ <get_parent_frame_delay>5</get_parent_frame_delay><!-- Tiempo de separación entre nodos para busqueda de padre -->
+ <get_parent_recovery_period>5</get_parent_recovery_period> <!-- Periodo para reintentar las busquedas de padres fallidas -->
+ <get_parent_maintenance_period>60</get_parent_maintenance_period><!-- Periodo para actualizar los padres de los nodos -->
+
+ <get_zigbee_devices>true</get_zigbee_devices><!-- Incluye la busqueda de endpoints en las tareas peiódicas -->
+ <get_zigbee_devices_frame_delay>5</get_zigbee_devices_frame_delay><!-- Tiempo de separación entre nodos para busqueda de endpoints -->
+ <get_zigbee_devices_recovery_period>5</get_zigbee_devices_recovery_period><!-- Periodo para reintentar las busquedas de endpoints fallidas -->
+
+ <update_dongle_s_registers>false</update_dongle_s_registers><!-- Actualiza la configuracion del dongle al conectarlo -->
+ <update_node_s_registers>false</update_node_s_registers><!-- Actualiza la configuracion de los nodos al detectarlos -->
+ <update_node_s_registers_frame_delay>5</update_node_s_registers_frame_delay><!-- Tiempo de separación entre nodos para escritura de registros -->
+ <update_node_s_registers_recovery_period>5</update_node_s_registers_recovery_period><!-- Periodo para reintentar las escrituras de registros fallidas -->
+
+ <s_register_password>Tormenta</s_register_password><!-- Contraseña para registros protegidos contra escritura -->
+ <s_reg_xcast_source_ep>02</s_reg_xcast_source_ep><!-- End point para mensajes enviados por el ZDO -->
+ <node_registers>
+ <address>dongle</address> <!-- Registros a escribir en el dongle -->
+ <s_registers>
+ <s_register>
+ <address>00</address>
+ <value>3FFC</value>
+ </s_register>
+ <s_register>
+ <address>02</address><!-- PID -->
+ <value>1234</value>
+ </s_register>
+ <s_register>
+ <address>09</address>
+ <value>00123400000000000000000000000000</value>
+ </s_register>
+ <s_register>
+ <address>0A</address>
+ <value>001C</value>
+ </s_register>
+ <s_register>
+ <address>0B</address>
+ <value>COO_test1</value>
+ </s_register>
+ <s_register>
+ <address>10</address>
+ <value>159A</value>
+ </s_register>
+ <s_register>
+ <address>4E</address>
+ <value>0AE1</value>
+ </s_register>
+ <s_register>
+ <address>4F</address>
+ <value>FFFF</value>
+ </s_register>
+ <s_register>
+ <address>0E</address>
+ <value>8000</value>
+ </s_register>
+ <s_register>
+ <address>0F</address>
+ <value>0006</value>
+ </s_register>
+ <s_register>
+ <address>11</address>
+ <value>0300</value>
+ </s_register>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+ <node_registers> <!-- Registros a escribir en el nodo "0011223344556677" -->
+ <address>0011223344556677</address>
+ <s_registers>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+ <node_registers> <!-- Registros a escribir en el nodo "8899aabbccddeeff" -->
+ <address>8899aabbccddeeff</address>
+ <s_registers>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+
+ </es.unizar.howlab.core.zigbee.telegesis.driver>
+
+</root>
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.core.zigbee.telegesis.driver.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.core.zigbee.telegesis.driver.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.core.zigbee.telegesis.driver.xml Thu Feb 2 13:18:42 2012
@@ -1,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Document : config.xml
+ Created on : 11 de agosto de 2011, 17:35
+ Author : alvaro
+ Description:
+ Purpose of the document follows.
+
+-->
+
+<root>
+ <es.unizar.howlab.core.zigbee.telegesis.driver>
+ <autostart>true</autostart><!-- Arranca el driver al crearlo -->
+
+ <ack_timeout>3000</ack_timeout><!-- Timeout para respuestas ACK -->
+ <register_read_timeout>3000</register_read_timeout><!-- Timeout para respuestas register_read -->
+ <register_write_timeout>3000</register_write_timeout><!-- Timeout para respuestas regiter_write -->
+ <zdo_response_timeout>3000</zdo_response_timeout><!-- Timeout para respuestas ZDO (ep_list, ep_descriptor) -->
+ <neighbour_response_timeout>10000</neighbour_response_timeout><!-- Timeout para respuestas de tabla de vecinos -->
+
+ <get_neighbours>true</get_neighbours><!-- Incluye la busqueda de vecinos en las tareas periódicas -->
+ <get_neighbours_frame_delay>5</get_neighbours_frame_delay><!-- Tiempo de separación entre nodos para busqueda de vecinos -->
+ <get_neighbours_recovery_period>5</get_neighbours_recovery_period> <!-- Periodo para reintentar las busquedas de vecinos fallidas -->
+ <get_neighbours_maintenance_period>60</get_neighbours_maintenance_period><!-- Periodo para actualizar los vecinos de los nodos -->
+
+ <get_parent>true</get_parent><!-- Incluye la busqueda del padre en las tareas periódicas -->
+ <get_parent_frame_delay>5</get_parent_frame_delay><!-- Tiempo de separación entre nodos para busqueda de padre -->
+ <get_parent_recovery_period>5</get_parent_recovery_period> <!-- Periodo para reintentar las busquedas de padres fallidas -->
+ <get_parent_maintenance_period>60</get_parent_maintenance_period><!-- Periodo para actualizar los padres de los nodos -->
+
+ <get_zigbee_devices>true</get_zigbee_devices><!-- Incluye la busqueda de endpoints en las tareas peiódicas -->
+ <get_zigbee_devices_frame_delay>5</get_zigbee_devices_frame_delay><!-- Tiempo de separación entre nodos para busqueda de endpoints -->
+ <get_zigbee_devices_recovery_period>5</get_zigbee_devices_recovery_period><!-- Periodo para reintentar las busquedas de endpoints fallidas -->
+
+ <update_dongle_s_registers>false</update_dongle_s_registers><!-- Actualiza la configuracion del dongle al conectarlo -->
+ <update_node_s_registers>false</update_node_s_registers><!-- Actualiza la configuracion de los nodos al detectarlos -->
+ <update_node_s_registers_frame_delay>5</update_node_s_registers_frame_delay><!-- Tiempo de separación entre nodos para escritura de registros -->
+ <update_node_s_registers_recovery_period>5</update_node_s_registers_recovery_period><!-- Periodo para reintentar las escrituras de registros fallidas -->
+
+ <s_register_password>Tormenta</s_register_password><!-- Contraseña para registros protegidos contra escritura -->
+ <s_reg_xcast_source_ep>02</s_reg_xcast_source_ep><!-- End point para mensajes enviados por el ZDO -->
+ <node_registers>
+ <address>dongle</address> <!-- Registros a escribir en el dongle -->
+ <s_registers>
+ <s_register>
+ <address>00</address>
+ <value>3FFC</value>
+ </s_register>
+ <s_register>
+ <address>02</address><!-- PID -->
+ <value>1234</value>
+ </s_register>
+ <s_register>
+ <address>09</address>
+ <value>00123400000000000000000000000000</value>
+ </s_register>
+ <s_register>
+ <address>0A</address>
+ <value>001C</value>
+ </s_register>
+ <s_register>
+ <address>0B</address>
+ <value>COO_test1</value>
+ </s_register>
+ <s_register>
+ <address>10</address>
+ <value>159A</value>
+ </s_register>
+ <s_register>
+ <address>4E</address>
+ <value>0AE1</value>
+ </s_register>
+ <s_register>
+ <address>4F</address>
+ <value>FFFF</value>
+ </s_register>
+ <s_register>
+ <address>0E</address>
+ <value>8000</value>
+ </s_register>
+ <s_register>
+ <address>0F</address>
+ <value>0006</value>
+ </s_register>
+ <s_register>
+ <address>11</address>
+ <value>0300</value>
+ </s_register>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+ <node_registers> <!-- Registros a escribir en el nodo "0011223344556677" -->
+ <address>0011223344556677</address>
+ <s_registers>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+ <node_registers> <!-- Registros a escribir en el nodo "8899aabbccddeeff" -->
+ <address>8899aabbccddeeff</address>
+ <s_registers>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+
+ </es.unizar.howlab.core.zigbee.telegesis.driver>
+
+</root>
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.io.serial.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.io.serial.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/es.unizar.howlab.io.serial.xml Thu Feb 2 13:18:42 2012
@@ -1,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Document : config.xml
+ Created on : June 8, 2011, 9:15 AM
+ Author : ciru
+ Description:
+ Purpose of the document follows.
+-->
+
+<config>
+
+ <connections>
+ <connection>
+ <protocol>rs232</protocol>
+ <where>/dev/ttyUSB0</where>
+ <how>19200</how>
+ <connectTime>3000</connectTime>
+ <retry>true</retry>
+ </connection>
+ <!--connection>
+ <protocol>tcp</protocol>
+ <where>192.168.0.3</where>
+ <how>10001</how>
+ <connectTime>1000</connectTime>
+ <retry>false</retry>
+ </connection
+ <connection>
+ <protocol>tcp</protocol>
+ <where>192.168.0.5</where>
+ <how>10001</how>
+ <connectTime>1000</connectTime>
+ <retry>false</retry>
+ </connection>-->
+ </connections>
+</config>
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/nbactions.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/nbactions.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/nbactions.xml Thu Feb 2 13:18:42 2012
@@ -1,0 +1,78 @@
+<?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>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-driver-impl/pom.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/pom.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/pom.xml Thu Feb 2 13:18:42 2012
@@ -1,0 +1,286 @@
+
+<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-driver-impl</artifactId>
+ <version>1.5-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>telegesis-driver-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/driver-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>
+ </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.zigbee.telegesis</groupId>
+ <artifactId>telegesis-gateway-api</artifactId>
+ <version>1.3</version>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>es.unizar.howlab.core.zigbee.telegesis</groupId>
+ <artifactId>telegesis-driver-api</artifactId>
+ <version>1.3</version>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>es.unizar.howlab.core</groupId>
+ <artifactId>easyJavaLib</artifactId>
+ <version>1.6</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.driver.impl.osgi.Activator</Bundle-Activator>
+<!-- <Embed-Transitive>true</Embed-Transitive>
+ <Embed-Dependency>*;artifactId=commons-configuration|commons-beanutils|commons-digester|commons-jxpath|mail|javax.servlet</Embed-Dependency>-->
+ <Export-Package>es.unizar.howlab.core.zigbee.telegesis.driver,es.unizar.howlab.core.zigbee.telegesis.driver.impl</Export-Package>
+ <Private-Package>es.unizar.howlab.core.zigbee.telegesis.driver.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>
+ <dependency>
+ <groupId>es.unizar.howlab.core.io.serial</groupId>
+ <artifactId>serial-gui</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>es.unizar.howlab.core.io.serial</groupId>
+ <artifactId>serial-imp</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>es.unizar.howlab.core.zigbee.telegesis</groupId>
+ <artifactId>telegesis-gateway-impl</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>bundle</type>
+ </dependency>
+ <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-driver-impl/src/main/assembly/felix.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/assembly/felix.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/assembly/felix.xml Thu Feb 2 13:18:42 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-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/AbstractDriver.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/AbstractDriver.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/AbstractDriver.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,1314 @@
+/*
+ * 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.driver.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.DriverListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.EUI64Address;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.NetworkAddress;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.NetworkInfo;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.ZigbeeNodeType;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+import es.unizar.howlab.easyjavalib.threading.Locker;
+import es.unizar.howlab.easyjavalib.xml.XMLConfiguration;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.service.cm.ManagedService;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public abstract class AbstractDriver implements Driver, ManagedService {
+ // Logger
+
+ private Log logger = LogFactory.getLog(this.getClass().getName());
+ // Gateway
+ protected final Gateway gateway;
+ // nodo conectado al gateway
+ private ZigbeeNode dongle;
+ private DriverStatus status = DriverStatus.Unknown;
+
+ public AbstractDriver(Gateway gtwy) {
+ logger.trace("AbstractDriver::AbstractDriver(gtwy=" + gtwy + ")");
+ // establecemos el gateway
+ gateway = gtwy;
+ }
+ //
+ // <editor-fold defaultstate="collapsed" desc="ESTATUS DE LA RED">
+ // parámetros de red
+ private int networkChanel;
+ private String networkPID;
+ private String networkEPID;
+ private ZigbeeNode coordinator;
+
+// @Override
+// abstract public NetworkInfo readNetworkInfo();
+ @Override
+ public NetworkInfo getNetworkInfo() {
+ logger.trace("Driver::getNetworkInfo()");
+ if (networkPID == null) {
+ return null;
+ } else {
+ return new NetworkInfo(networkChanel, networkPID, networkEPID);
+ }
+ }
+
+ /**
+ * Comprueba si el driver está unido a la red
+ * @return TRUE si el driver está unido a la red
+ */
+ protected boolean isJoinedToNetwork() {
+ return (networkChanel > 0);
+ }
+
+ /**
+ * Establece el driver como conectado a la red
+ * @param channel
+ * @param PID
+ * @param EPID
+ */
+ protected void setNetworkJoined(int channel, String PID, String EPID) {
+ logger.trace("Driver::setNetworkJoined(channel=" + channel + ", PID=" + PID + ", EPID=" + EPID + ")");
+ // comprobamos si ha cambiado algún parámetro
+ if ((channel != networkChanel)
+ || (!PID.equals(networkPID))
+ || (!EPID.equals(networkEPID))) {
+ networkChanel = channel;
+ networkPID = PID;
+ networkEPID = EPID;
+ logger.info("[ZigbeeDriver] joined to network (channel=" + channel + ", PID=" + PID + ", EPID=" + EPID + ")");
+ fireJoinNetwork(channel, PID, EPID);
+ }
+ }
+
+ /**
+ * Establece el driver como desconectado a la red
+ */
+ protected void setNetworkLeft() {
+ logger.trace("Driver::setNetworkLeft()");
+ // comprobamos si ha cambiado algún parámetro
+ if ((networkChanel != 0)
+ || (networkPID != null)
+ || (networkEPID != null)) {
+ networkChanel = 0;
+ networkPID = null;
+ networkEPID = null;
+ logger.info("[ZigbeeDriver] left network");
+ // eliminamos todos los nodos (salvo el dongle)
+ Iterator<String> it = nodes.keySet().iterator();
+ while (it.hasNext()) {
+ String EUI64Addr = it.next();
+ // comprobamos si coincide con el dongle
+ if (!dongle.getEUI64Addr().toString().equals(EUI64Addr)) {
+ it.remove();
+ }
+ }
+
+ // eliminamos el coordinador
+ coordinator = null;
+
+ // notificamos abandonamos red
+ fireLeftNetwork();
+ }
+ }
+
+ /**
+ * Establece el coordinador de la red
+ * @param node nodo a comprobar si es el coordinador
+ * @return True si el nodo es coordinador, false en otro caso
+ */
+ protected boolean checkSetCoordinator(ZigbeeNode node) {
+ logger.trace("Driver::checkSetCoordinator(node=" + node + ")");
+ if (node.getType() == ZigbeeNodeType.Coordinator) {
+ this.coordinator = node;
+ logger.info("[ZigbeeDriver] Coordinator set: " + node);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Crea el nodo asociado al dongle a partir de la dirección del nodo
+ * @param EUI64Addr Dirección del nodo
+ * @param nodeID Dirección de red del nodo
+ * @param type tipo de nodo
+ */
+ public void createDongle(String EUI64Addr, String nodeID, ZigbeeNodeType type) {
+ logger.trace("Driver::createDongle(EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", type=" + type + ")");
+
+ // creamos el dongle,
+ if (nodeID == null) {
+ dongle = createNode(new EUI64Address(EUI64Addr), type);
+ } else {
+ dongle = createNode(new EUI64Address(EUI64Addr), new NetworkAddress(nodeID), type);
+ }
+
+ // actualizamos el coordinador de la red (si fuera el caso)
+ checkSetCoordinator(dongle);
+
+
+
+ }
+ // </editor-fold>
+// @Override
+// abstract public NetworkScanInfo[] findNetworks();
+//
+// @Override
+// abstract public boolean createNetwork();
+//
+// @Override
+// abstract public boolean createNetwork(int channel, String PID);
+//
+// @Override
+// abstract public boolean createNetwork(int channel, String PID, String linkKey);
+//
+// @Override
+// abstract public boolean joinNetwork();
+//
+// @Override
+// abstract public boolean joinNetwork(String PID);
+//
+// @Override
+// abstract public boolean joinNetwork(String PID, String linkKey);
+//
+// @Override
+// abstract public boolean leaveNetwork();
+//
+// @Override
+// abstract public boolean scanNetwork();
+//
+// @Override
+// abstract public boolean leaveNetwork(ZigbeeNode node);
+ //
+ // <editor-fold defaultstate="collapsed" desc="REGISTRO DE NODOS">
+ private HashMap<String, ZigbeeNode> nodes = new HashMap<String, ZigbeeNode>();
+ private HashMap<String, String> networkAddresses = new HashMap<String, String>();
+
+ @Override
+ public ZigbeeNode getNode(String address) {
+ logger.trace("Driver::getNode(address=" + address + ")");
+
+ // comprobamos dirección
+ if (address == null) {
+ return null;
+ }
+ // limpiamos posibles caracteres no deseados
+ String addr = address.toUpperCase().replaceAll("[^0123456789ABCDEF]", "");
+
+ // comprobamos si se trata de la dirección MAC o la dirección de red
+ String MACAddr;
+ if (addr.length() == 4) {
+ MACAddr = networkAddresses.get(addr);
+ } else {
+ MACAddr = addr;
+ }
+
+ // recuperamos el nodo por la dirección MAC
+ ZigbeeNode node = nodes.get(MACAddr);
+ return node;
+
+ }
+
+ /**
+ * Actualiza la dirección de red de un nodo
+ * @param EUI64Addr Dirección MAC del nodo
+ * @param newNodeID Nueva dirección de red
+ */
+ protected void updateNetworkAddress(ZigbeeNode node, String newNodeID) {
+ logger.trace("Driver::updateNetworkAddress(node=" + node + ", newNodeID=" + newNodeID + ")");
+
+ // comprobamos si el nodo tenÃa NodeID, y la eliminamos
+ NetworkAddress oldNodeID = node.getNodeID();
+ if (oldNodeID != null) {
+ networkAddresses.remove(oldNodeID.toString());
+ }
+
+ // añadimos la nueva dirección
+ networkAddresses.put(newNodeID, node.getEUI64Addr().toString());
+
+ // actualizamos la dirección del nodo
+ ((ZigbeeNodeImpl) node).setNodeID(new NetworkAddress(newNodeID));
+
+ }
+
+ @Override
+ public ZigbeeNode[] getNodes() {
+ logger.trace("Driver::getNodes()");
+ return nodes.values().toArray(new ZigbeeNode[0]);
+ }
+
+ @Override
+ public ZigbeeNode getNetworkCoordinator() {
+ logger.trace("Driver::getCoordinator()");
+ return coordinator;
+ }
+
+ /**
+ * Recupera el nodo conectado al gateway
+ * @return ZigbeeNode
+ */
+ @Override
+ public ZigbeeNode getDongle() {
+ logger.trace("Driver::getDongle()");
+ return dongle;
+ }
+
+ /**
+ * Crea un nodo y lanza los procesos de identificación asociados
+ * @param address direccion del nodo
+ * @return Nodo creado
+ */
+ public ZigbeeNode createNode(EUI64Address address) {
+ logger.trace("Driver::createNode(address=" + address + ")");
+ // Creamos un nodo con dirección de red y tipo desconocidos
+ return createNode(address, null, ZigbeeNodeType.Unknown);
+ }
+
+ /**
+ * Crea un nodo y lanza los procesos de identificación asociados
+ * @param nodeID direccion de red del nodo
+ * @return Nodo creado
+ */
+ public ZigbeeNode createNode(NetworkAddress nodeID) {
+ logger.trace("Driver::createNode(nodeID=" + nodeID + ")");
+ // Creamos un nodo con dirección y tipo desconocidos
+ return createNode(null, nodeID, ZigbeeNodeType.Unknown);
+ }
+
+ /**
+ * Crea un nodo y lanza los procesos de identificación asociados
+ * @param address direccion del nodo
+ * @param nodeID direccion de red del nodo
+ * @return Nodo creado
+ */
+ public ZigbeeNode createNode(EUI64Address address, NetworkAddress nodeID) {
+ logger.trace("Driver::createNode(address=" + address + ", nodeID=" + nodeID + ")");
+ // Creamos un nodo con tipo desconocido
+ return createNode(address, nodeID, ZigbeeNodeType.Unknown);
+ }
+
+ /**
+ * Crea un nodo y lanza los procesos de identificación asociados
+ * @param address direccion del nodo
+ * @param type tipo de nodo
+ * @return Nodo creado
+ */
+ public ZigbeeNode createNode(EUI64Address address, ZigbeeNodeType type) {
+ logger.trace("Driver::createNode(address=" + address + ", type=" + type + ")");
+ // Creamos un nodo con dirección de red desconocida
+ return createNode(address, null, type);
+
+ }
+
+ /**
+ * Crea un nodo y lanza los procesos de identificación asociados
+ * @param nodeID direccion del nodo
+ * @param type tipo de nodo
+ * @return Nodo creado
+ */
+ public ZigbeeNode createNode(NetworkAddress nodeID, ZigbeeNodeType type) {
+ logger.trace("Driver::createNode(nodeID=" + nodeID + ", type=" + type + ")");
+ // Creamos un nodo con dirección desconocida
+ return createNode(null, nodeID, type);
+ }
+
+ /**
+ * Crea un nodo y lanza los procesos de identificación asociados
+ * @param address direccion del nodo
+ * @param nodeID direccion de red del nodo
+ * @param type tipo de nodo
+ * @return Nodo creado
+ */
+ public ZigbeeNode createNode(EUI64Address address, NetworkAddress nodeID, ZigbeeNodeType type) {
+ logger.trace("Driver::createNode(address=" + address + ", nodeID=" + nodeID + ", type=" + type + ")");
+
+ // creamos el nodo
+ ZigbeeNode newNode = new ZigbeeNodeImpl(this);
+
+ // actualizamos parámetros
+ ((ZigbeeNodeImpl) newNode).setAddress(address);
+ ((ZigbeeNodeImpl) newNode).setNodeID(nodeID);
+ ((ZigbeeNodeImpl) newNode).setType(type);
+ ((ZigbeeNodeImpl) newNode).setStatus(ZigbeeNode.NodeStatus.Ready);
+
+ // Añadimos el nodo a la lista de nodos
+ if (newNode.getEUI64Addr() != null) {
+ nodes.put(newNode.getEUI64Addr().toString(), newNode);
+ }
+
+ // guardamos la dirección de red
+ if (nodeID != null) {
+ updateNetworkAddress(newNode, nodeID.toString());
+ }
+
+ logger.info("[ZigbeeDriver] Node created: " + newNode);
+
+ // notificamos de la creación del nodo
+ fireNewNode(newNode);
+
+ // devolvemos el nodo creado
+ return newNode;
+
+ }
+
+ /**
+ * elimina un nodo del driver
+ * @param node Nodo a eliminar
+ */
+ public void removeNode(ZigbeeNode node) {
+ logger.trace("Driver::removeNode(node=" + node + ")");
+
+ // comprobamos nodo null
+ if (node == null) {
+ logger.warn("[ZigbeeDriver] RemoveNode requested for null node");
+ return;
+ }
+
+
+ // comprobamos si el nodo tiene ZigbeeDevices, y notificamos que son eliminados
+ for (ZigbeeDevice device : node.getZigbeeDevices()) {
+ fireDeviceLeft(device);
+ }
+
+ // notificamos el nodo eliminado
+ fireNodeLeft(node);
+
+ // recuperamos al dirección
+ String EUI64Addr = node.getEUI64Addr().toString();
+
+ // eliminamos el nodo de la lista
+ nodes.remove(EUI64Addr);
+
+ logger.info("[ZigbeeDriver] Node removed: " + node);
+
+
+ }
+
+ /**
+ * Crea un device y lanza los procesos de identificación asociados
+ * @param node nodo que contiene al device
+ * @param endPoint Identificador del device
+ * @return Device creado
+ */
+ protected ZigbeeDevice createDevice(ZigbeeNode node, short endPoint) {
+ logger.trace("Driver::createDevice(node=" + node + ", endPoint=" + endPoint + ")");
+
+ // creamos el device
+ ZigbeeDevice newDevice = new ZigbeeDeviceImpl(this, node, endPoint);
+
+ // añadimos el device al nodo
+ ((ZigbeeNodeImpl) node).addZigbeeDevice(newDevice);
+
+ logger.info("[ZigbeeDriver] Device created: " + newDevice);
+
+ // notificamos de la creación del device
+ fireNewDevice(newDevice);
+
+ // devolvemos el device creado
+ return newDevice;
+
+ }
+
+ /**
+ * elimina un device del driver
+ * @param device Device a eliminar
+ */
+ public void removeDevice(ZigbeeDevice device) {
+ logger.trace("Driver::removeDevice(device=" + device + ")");
+
+ // comprobamos nodo null
+ if (device == null) {
+ logger.warn("[ZigbeeDriver] RemoveDevice requested for null device");
+ return;
+ }
+
+ // recuperamos el nodo
+ ZigbeeNodeImpl node = (ZigbeeNodeImpl) device.getZigbeeNode();
+
+ // eliminamos el device del nodo
+ node.removeZigbeeDevice(device);
+
+ // notificamos device eliminado
+ fireDeviceLeft(device);
+
+ logger.info("[ZigbeeDriver] Device removed: " + device);
+
+
+ }
+
+ // </editor-fold>
+// @Override
+// abstract public boolean sendMessage(ZigbeeNode node, byte[] message);
+//
+// @Override
+// abstract public boolean sendMessage(ZigbeeDevice device, String profileID, String clusterID, byte[] message);
+//
+// @Override
+// abstract public boolean sendBroadcastMessage(byte[] message);
+//
+// @Override
+// abstract public String readRegister(ZigbeeNode node, short regAddress);
+//
+// @Override
+// abstract public boolean writeRegister(ZigbeeNode node, short regAddress, String data);
+//
+// @Override
+// abstract public boolean updateActiveEndPoints(ZigbeeNode node);
+//
+// @Override
+// abstract public boolean updateEndPointDescriptor(ZigbeeDevice device);
+//
+// @Override
+// abstract public boolean updateNeighbourTable(ZigbeeNode node);
+//
+// @Override
+// abstract public boolean init();
+//
+// @Override
+// abstract public boolean start();
+// @Override
+// abstract public void disable();
+//
+// @Override
+// abstract public Gateway getGateway();
+//
+ @Override
+ public DriverStatus getStatus() {
+ logger.trace("Driver::getStatus()");
+ return status;
+ }
+
+ /**
+ * Actualiza el status, y lanza la notificación correspondiente
+ * @param status
+ */
+ protected void setStatus(DriverStatus status) {
+ // guardamos el estado anterior y lo actualizamos
+ DriverStatus oldStatus = this.status;
+ this.status = status;
+ // comprobamos para notificar cambio de estado
+ if (oldStatus != status) {
+ fireStatusChanged(status, oldStatus);
+ }
+ }
+
+ /**
+ * Comprueba si está en un estado que permita ejecutar operaciones
+ */
+ protected boolean isEnabled() {
+ switch (status) {
+ case Unknown:
+ case Disabled:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ //
+ // <editor-fold defaultstate="collapsed" desc="CONFIGURATION">
+ /*
+ * La configuración se almacena en un fichero XML, y se accede indicando una
+ * clave raiz para el nodo a partir del cual está almacenada la
+ * configuracion:
+ * CONF_ROOT
+ */
+ private static final String CONF_ROOT = Driver.class.getPackage().getName().toLowerCase();
+ protected XMLConfiguration configuration = new XMLConfiguration(CONF_ROOT);
+ //private static final String CONF_FILENAME = Driver.class.getPackage().getName().toLowerCase() + ".xml";
+ private static final String CONF_FILENAME = CONF_ROOT + ".xml";
+ /*
+ * Nota: sobre los parámetros de configuración, se sigue la convención
+ * CONF_VARIABLE ==> define una variable de configuracion, con acceso protected o public
+ * CONV_VARIABLE_DEFAULT ==> define el valor por defecto de la variable (private)
+ * CONF_VARIABLE_KEY ==> define la clave de la variable (public static final String)
+ */
+ // Autostart del driver al crearlo
+ protected boolean CONF_AUTOSTART;
+ private static final boolean CONF_AUTOSTART_DEFAULT = false;
+ public static final String CONF_AUTOSTART_KEY = "autostart";
+ // Tiempos de espera
+ protected long CONF_ACK_TIMEOUT;
+ private static final long CONF_ACK_TIMEOUT_DEFAULT = 0x0BB8; // MAC TIMEOUT
+ public static final String CONF_ACK_TIMEOUT_KEY = "ack_timeout";
+ protected long CONF_REGISTER_READ_TIMEOUT;
+ private static final long CONF_REGISTER_READ_TIMEOUT_DEFAULT = 0x0BB8; // MAC TIMEOUT
+ public static final String CONF_REGISTER_READ_TIMEOUT_KEY = "register_read_timeout";
+ protected long CONF_REGISTER_WRITE_TIMEOUT;
+ private static final long CONF_REGISTER_WRITE_TIMEOUT_DEFAULT = 0x0BB8; // MAC TIMEOUT
+ public static final String CONF_REGISTER_WRITE_TIMEOUT_KEY = "register_write_timeout";
+ protected long CONF_ZDO_RESPONSE_TIMEOUT;
+ private static final long CONF_ZDO_RESPONSE_TIMEOUT_DEFAULT = 0x0BB8; // MAC TIMEOUT
+ public static final String CONF_ZDO_RESPONSE_TIMEOUT_KEY = "zdo_response_timeout";
+ protected long CONF_NEIGHBOUR_RESPONSE_TIMEOUT;
+ private static final long CONF_NEIGHBOUR_RESPONSE_TIMEOUT_DEFAULT = 0x0BB8; // MAC TIMEOUT
+ public static final String CONF_NEIGHBOUR_RESPONSE_TIMEOUT_KEY = "neighbour_response_timeout";
+ // Register Password
+ protected String CONF_S_REG_PASSWORD;
+ private static final String CONF_S_REG_PASSWORD_DEFAULT = "password";
+ public static final String CONF_S_REG_PASSWORD_KEY = "s_register_password";
+ // endpoint origen para mensajes enviados a endpoints
+ protected String CONF_S_REG_XCAST_SOURCE_EP;
+ private static final String CONF_S_REG_XCAST_SOURCE_EP_DEFAULT = "02";
+ public static final String CONF_S_REG_XCAST_SOURCE_EP_KEY = "s_reg_xcast_source_ep";
+ /*
+ * PARAMETROS DE CONFIGURACION DE TAREAS DE MANTENIMIENTO
+ * Los parámetros de configuracion de las tareas son en general:
+ * - Tarea activa o no (boolean)
+ * - Periodo de mantenimiento de la tarea (long, en minutos)
+ * - Periodo de reintento para tareas fallidas (long, en minutos)
+ * - Periodo de separacion entre nodos/devices (long, en segundos)
+ * - otros parámetros de la tarea
+ */
+ // recuperar Neighbours
+ protected boolean CONF_GET_NEIGHBOURS;
+ private static final boolean CONF_GET_NEIGHBOURS_DEFAULT = true;
+ public static final String CONF_GET_NEIGHBOURS_KEY = "get_neighbours";
+ protected long CONF_GET_NEIGHBOURS_FRAME_DELAY;
+ private static final long CONF_GET_NEIGHBOURS_FRAME_DELAY_DEFAULT = 10;
+ public static final String CONF_GET_NEIGHBOURS_FRAME_DELAY_KEY = "get_neighbours_frame_delay";
+ protected long CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD;
+ private static final long CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_DEFAULT = 60;
+ public static final String CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_KEY = "get_neighbours_maintenance_period";
+ protected long CONF_GET_NEIGHBOURS_RECOVERY_PERIOD;
+ private static final long CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_DEFAULT = 5;
+ public static final String CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_KEY = "get_neighbours_recovery_period";
+ // recuperar padre
+ protected boolean CONF_GET_PARENT;
+ private static final boolean CONF_GET_PARENT_DEFAULT = true;
+ public static final String CONF_GET_PARENT_KEY = "get_parent";
+ protected long CONF_GET_PARENT_FRAME_DELAY;
+ private static final long CONF_GET_PARENT_FRAME_DELAY_DEFAULT = 10;
+ public static final String CONF_GET_PARENT_FRAME_DELAY_KEY = "get_parent_frame_delay";
+ protected long CONF_GET_PARENT_MAINTENANCE_PERIOD;
+ private static final long CONF_GET_PARENT_MAINTENANCE_PERIOD_DEFAULT = 60;
+ public static final String CONF_GET_PARENT_MAINTENANCE_PERIOD_KEY = "get_parent_maintenance_period";
+ protected long CONF_GET_PARENT_RECOVERY_PERIOD;
+ private static final long CONF_GET_PARENT_RECOVERY_PERIOD_DEFAULT = 5;
+ public static final String CONF_GET_PARENT_RECOVERY_PERIOD_KEY = "get_parent_recovery_period";
+ // recuperar ZigbeeDevices
+ protected boolean CONF_GET_ZIGBEE_DEVICES;
+ private static final boolean CONF_GET_ZIGBEE_DEVICES_DEFAULT = true;
+ public static final String CONF_GET_ZIGBEE_DEVICES_KEY = "get_zigbee_devices";
+ protected long CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY;
+ private static final long CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_DEFAULT = 60;
+ public static final String CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_KEY = "get_zigbee_devices_frame_delay";
+ protected long CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD;
+ private static final long CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_DEFAULT = 5;
+ public static final String CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_KEY = "get_zigbee_devices_recovery_period";
+ // Control de error en dispositivos
+ protected boolean CONF_CHECK_ZIGBEE_ERROR;
+ private static final boolean CONF_CHECK_ZIGBEE_ERROR_DEFAULT = true;
+ public static final String CONF_CHECK_ZIGBEE_ERROR_KEY = "check_zigbee_error";
+ protected long CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY;
+ private static final long CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_DEFAULT = 10;
+ public static final String CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_KEY = "check_zigbee_error_frame_delay";
+ protected long CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD;
+ private static final long CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_DEFAULT = 5;
+ public static final String CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_KEY = "check_zigbee_error_maintenance_period";
+ protected long CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD;
+ private static final long CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_DEFAULT = 1;
+ public static final String CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_KEY = "check_zigbee_error_recovery_period";
+ // Umbrales de error para gestion de dispositivos
+ public long CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1;
+ private static final long CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_DEFAULT = 2;
+ public static final String CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_KEY = "zigbee_error_level_threshold_1";
+ public long CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2;
+ private static final long CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_DEFAULT = 3;
+ public static final String CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_KEY = "zigbee_error_level_threshold_2";
+ // actualizar la configuracion del dongle al conectarlo
+ protected boolean CONF_UPDATE_DONGLE_S_REGISTERS;
+ private static final boolean CONF_UPDATE_DONGLE_S_REGISTERS_DEFAULT = false;
+ public static final String CONF_UPDATE_DONGLE_S_REGISTERS_KEY = "update_dongle_s_registers";
+ // actualizar la configuracion de los nodos al detectarlos
+ protected boolean CONF_UPDATE_NODE_S_REGISTERS;
+ private static final boolean CONF_UPDATE_NODE_S_REGISTERS_DEFAULT = false;
+ public static final String CONF_UPDATE_NODE_S_REGISTERS_KEY = "update_node_s_registers";
+ protected long CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY;
+ private static final long CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_DEFAULT = 10;
+ public static final String CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_KEY = "update_node_s_registers_frame_delay";
+ protected long CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD;
+ private static final long CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_DEFAULT = 5;
+ public static final String CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_KEY = "update_node_s_registers_recovery_period";
+ // registros a escribir en los nodos
+ private HashMap<String, HashMap<String, String>> CONF_NODE_REGISTERS;
+ private static final String CONF_DONGLE_S_REGISTER_ADDR_ID = "dongle";
+ private static final String CONF_NODE_REGISTERS_KEY = "node_registers";
+ private static final String CONF_NODE_ADDRESS_KEY = "address";
+ private static final String CONF_S_REGISTERS_KEY = "s_registers";
+ private static final String CONF_S_REGISTER_KEY = "s_register";
+ private static final String CONF_NODE_S_REGISTERS_ADDR_KEY = "address";
+ private static final String CONF_NODE_S_REGISTERS_VALUE_KEY = "value";
+ // configuracion fija
+ protected static final int GATEWAY_INITIALIZATION_LOCK_TIME = 60000;
+
+ public void loadConfiguration() {
+ logger.trace("Driver::loadConfiguration()");
+
+ // cargamos la configuracion
+ loadConfiguration(CONF_FILENAME);
+ }
+
+ /**
+ * Carga la configuracion desde el fichero indicado
+ * @param file
+ */
+ public void loadConfiguration(String file) {
+ logger.trace(String.format("Driver::loadConfiguration(file=%s)", file));
+
+ // cargamos la configuracion
+ logger.info(String.format("[ZigbeeDriver] Loading configuration from %s", file));
+ if (!configuration.load(file)) {
+ logger.warn(String.format("[ZigbeeDriver] Error loading configuration from %s. Using defaults", file));
+ // generamos configuracion por defecto
+ saveDefaultConfiguration(file);
+ }
+
+ // establecemos la configuracion
+ CONF_AUTOSTART = configuration.getBoolean(CONF_AUTOSTART_KEY, CONF_AUTOSTART_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_AUTOSTART=%s", CONF_AUTOSTART));
+
+ CONF_ACK_TIMEOUT = configuration.getLong(CONF_ACK_TIMEOUT_KEY, CONF_ACK_TIMEOUT_DEFAULT);
+ CONF_REGISTER_READ_TIMEOUT = configuration.getLong(CONF_REGISTER_READ_TIMEOUT_KEY, CONF_REGISTER_READ_TIMEOUT_DEFAULT);
+ CONF_REGISTER_WRITE_TIMEOUT = configuration.getLong(CONF_REGISTER_WRITE_TIMEOUT_KEY, CONF_REGISTER_WRITE_TIMEOUT_DEFAULT);
+ CONF_ZDO_RESPONSE_TIMEOUT = configuration.getLong(CONF_ZDO_RESPONSE_TIMEOUT_KEY, CONF_ZDO_RESPONSE_TIMEOUT_DEFAULT);
+ CONF_NEIGHBOUR_RESPONSE_TIMEOUT = configuration.getLong(CONF_NEIGHBOUR_RESPONSE_TIMEOUT_KEY, CONF_NEIGHBOUR_RESPONSE_TIMEOUT_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_ACK_TIMEOUT=%d milisegundos", CONF_ACK_TIMEOUT));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_REGISTER_READ_TIMEOUT=%d milisegundos", CONF_REGISTER_READ_TIMEOUT));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_REGISTER_WRITE_TIMEOUT=%d milisegundos", CONF_REGISTER_WRITE_TIMEOUT));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_ZDO_RESPONSE_TIMEOUT=%d milisegundos", CONF_ZDO_RESPONSE_TIMEOUT));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_NEIGHBOUR_RESPONSE_TIMEOUT=%d milisegundos", CONF_NEIGHBOUR_RESPONSE_TIMEOUT));
+
+ CONF_S_REG_PASSWORD = configuration.getString(CONF_S_REG_PASSWORD_KEY, CONF_S_REG_PASSWORD_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_S_REG_PASSWORD=%s", CONF_S_REG_PASSWORD));
+
+ CONF_S_REG_XCAST_SOURCE_EP = configuration.getString(CONF_S_REG_XCAST_SOURCE_EP_KEY, CONF_S_REG_XCAST_SOURCE_EP_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_S_REG_XCAST_SOURCE_EP=%s", CONF_S_REG_XCAST_SOURCE_EP));
+
+ CONF_CHECK_ZIGBEE_ERROR = configuration.getBoolean(CONF_CHECK_ZIGBEE_ERROR_KEY, CONF_CHECK_ZIGBEE_ERROR_DEFAULT);
+ CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY = configuration.getLong(CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_KEY, CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_DEFAULT);
+ CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD = configuration.getLong(CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_KEY, CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_DEFAULT);
+ CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD = configuration.getLong(CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_KEY, CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_DEFAULT);
+ CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1 = configuration.getLong(CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_KEY, CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_DEFAULT);
+ CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2 = configuration.getLong(CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_KEY, CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_CHECK_ZIGBEE_ERROR=%s", CONF_CHECK_ZIGBEE_ERROR));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY=%d segundos", CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD=%d minutos", CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD=%d minutos", CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1=%d errores", CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2=%d errores", CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2));
+
+ CONF_GET_NEIGHBOURS = configuration.getBoolean(CONF_GET_NEIGHBOURS_KEY, CONF_GET_NEIGHBOURS_DEFAULT);
+ CONF_GET_NEIGHBOURS_FRAME_DELAY = configuration.getLong(CONF_GET_NEIGHBOURS_FRAME_DELAY_KEY, CONF_GET_NEIGHBOURS_FRAME_DELAY_DEFAULT);
+ CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD = configuration.getLong(CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_KEY, CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_DEFAULT);
+ CONF_GET_NEIGHBOURS_RECOVERY_PERIOD = configuration.getLong(CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_KEY, CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_NEIGHBOURS=%s", CONF_GET_NEIGHBOURS));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_NEIGHBOURS_FRAME_DELAY=%d segundos", CONF_GET_NEIGHBOURS_FRAME_DELAY));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD=%d minutos", CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_NEIGHBOURS_RECOVERY_PERIOD=%d minutos", CONF_GET_NEIGHBOURS_RECOVERY_PERIOD));
+
+ CONF_GET_PARENT = configuration.getBoolean(CONF_GET_PARENT_KEY, CONF_GET_PARENT_DEFAULT);
+ CONF_GET_PARENT_FRAME_DELAY = configuration.getLong(CONF_GET_PARENT_FRAME_DELAY_KEY, CONF_GET_PARENT_FRAME_DELAY_DEFAULT);
+ CONF_GET_PARENT_MAINTENANCE_PERIOD = configuration.getLong(CONF_GET_PARENT_MAINTENANCE_PERIOD_KEY, CONF_GET_PARENT_MAINTENANCE_PERIOD_DEFAULT);
+ CONF_GET_PARENT_RECOVERY_PERIOD = configuration.getLong(CONF_GET_PARENT_RECOVERY_PERIOD_KEY, CONF_GET_PARENT_RECOVERY_PERIOD_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_PARENT=%s", CONF_GET_PARENT));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_PARENT_FRAME_DELAY=%d segundos", CONF_GET_PARENT_FRAME_DELAY));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_PARENT_MAINTENANCE_PERIOD=%d minutos", CONF_GET_PARENT_MAINTENANCE_PERIOD));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_PARENT_RECOVERY_PERIOD=%d minutos", CONF_GET_PARENT_RECOVERY_PERIOD));
+
+ CONF_GET_ZIGBEE_DEVICES = configuration.getBoolean(CONF_GET_ZIGBEE_DEVICES_KEY, CONF_GET_ZIGBEE_DEVICES_DEFAULT);
+ CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY = configuration.getLong(CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_KEY, CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_DEFAULT);
+ CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD = configuration.getLong(CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_KEY, CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_ZIGBEE_DEVICES=%s", CONF_GET_ZIGBEE_DEVICES));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY=%d segundos", CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD=%d minutos", CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD));
+
+ CONF_UPDATE_DONGLE_S_REGISTERS = configuration.getBoolean(CONF_UPDATE_DONGLE_S_REGISTERS_KEY, CONF_UPDATE_DONGLE_S_REGISTERS_DEFAULT);
+ CONF_UPDATE_NODE_S_REGISTERS = configuration.getBoolean(CONF_UPDATE_NODE_S_REGISTERS_KEY, CONF_UPDATE_NODE_S_REGISTERS_DEFAULT);
+ CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY = configuration.getLong(CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_KEY, CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_DEFAULT);
+ CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD = configuration.getLong(CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_KEY, CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_DEFAULT);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_UPDATE_DONGLE_S_REGISTERS=%s", CONF_UPDATE_DONGLE_S_REGISTERS));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_UPDATE_NODE_S_REGISTERS=%s", CONF_UPDATE_NODE_S_REGISTERS));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY=%d segundos", CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY));
+ logger.debug(String.format("[ZigbeeDriver] Configuration: CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD=%d minutos", CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD));
+
+ CONF_NODE_REGISTERS = loadNodeRegisterConfig(configuration);
+
+ }
+
+ /**
+ * Guarda la configuracion actual en un archivo
+ * @return True si guarda la configuración, false en otro caso
+ */
+ public boolean saveCurrentConfiguration() {
+ logger.trace(String.format("Driver::saveCurrentConfiguration()"));
+
+ // recuperamos la configuracion actual
+ Dictionary properties = getCurrentConfiguration();
+
+ // la guardamos
+ return saveConfiguration(CONF_FILENAME, properties);
+
+ }
+
+ /**
+ * Guarda la configuracion actual en un archivo
+ * @param file nombre del archivo
+ * @return True si guarda la configuración, false en otro caso
+ */
+ public boolean saveCurrentConfiguration(String file) {
+ logger.trace(String.format("Driver::saveCurrentConfiguration(file=%s)", file));
+
+ // recuperamos la configuracion actual
+ Dictionary properties = getCurrentConfiguration();
+
+ // la guardamos
+ return saveConfiguration(file, properties);
+
+ }
+
+ /**
+ * Guarda la configuracion por defecto en un archivo
+ * @param file nombre del archivo
+ * @return True si guarda la configuración, false en otro caso
+ */
+ public boolean saveDefaultConfiguration(String file) {
+ logger.trace(String.format("Driver::saveDefaultConfiguration(file=%s)", file));
+
+ // recuperamos la configuración por defecto
+ Dictionary properties = getDefaultConfiguration();
+
+ // la guardamos
+ return saveConfiguration(file, properties);
+
+ }
+
+ /**
+ * Guarda la configuracion proporcionada en un archivo
+ * @param file Nombre del archivo
+ * @param properties Propiedades a guardar
+ * @return True si guarda la configuracion, false en otro caso
+ */
+ public boolean saveConfiguration(String file, Dictionary properties) {
+ logger.trace(String.format("Driver::saveConfiguration(file=%s, properties=%s)", file, properties));
+
+ logger.info(String.format("[ZigbeeDriver] Saving driver configuration to file %s", file));
+
+ // creamos una configuracion auxiliar
+ XMLConfiguration saveConf = new XMLConfiguration(CONF_ROOT);
+
+ // añadimos las propiedades
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ Object value = properties.get(key);
+ saveConf.addProperty(key, value.toString());
+ }
+
+ // guardamos el fichero
+ return saveConf.save(file);
+
+ }
+
+ /**
+ * Devuelve la configuración a aplicar a los registros del dongle
+ * @return HashMap con la lista de registros a escribir en el dongle
+ */
+ public HashMap<String, String> getDongleRegisterConfig() {
+ logger.trace("Driver::getDongleRegisterConfig()");
+
+ return CONF_NODE_REGISTERS.get(CONF_DONGLE_S_REGISTER_ADDR_ID);
+
+ }
+
+ /**
+ * Devuelve la configuración a aplicar a los registros de un nodo determinado
+ * @param EUI64Addr direccion del nodo
+ * @return HashMap con la lista de registros a escribir en el dongle
+ */
+ public HashMap<String, String> getNodeRegisterConfig(String EUI64Addr) {
+ logger.trace(String.format("Driver::getNodeRegisterConfig(EUI64Addr=%s)", EUI64Addr));
+
+ return CONF_NODE_REGISTERS.get(EUI64Addr);
+
+ }
+
+ /**
+ * Recupera la configuración a aplicar a los registros de los nodos
+ * @param conf configuración
+ * @return HashMap con la lista de registros a escribir en cada nodo
+ */
+ private HashMap<String, HashMap<String, String>> loadNodeRegisterConfig(XMLConfiguration conf) {
+ logger.trace(String.format("Driver::loadNodeRegisterConfig(conf=%s)", conf));
+
+ // Creamos el resultado
+ HashMap<String, HashMap<String, String>> registers = new HashMap<String, HashMap<String, String>>();
+
+ // recuperamos las configuraciones de los nodos
+ ArrayList<XMLConfiguration> nodeAddrList = conf.getConfigs(CONF_NODE_REGISTERS_KEY);
+
+ // Recuperamos los registros de cada nodo
+ for (int i = 0; i < nodeAddrList.size(); i++) {
+ // recuperamos la configuracion correspondiente al nodo
+ XMLConfiguration nodeConf = nodeAddrList.get(i);
+
+ String nodeAddr = nodeConf.getString(CONF_NODE_ADDRESS_KEY, null);
+ if (nodeAddr != null) { // por si hubiera algún error...
+ HashMap<String, String> registersNode = new HashMap<String, String>();
+ // recuperamos la configuracion de registros
+ XMLConfiguration regConf = nodeConf.getConfig(CONF_S_REGISTERS_KEY);
+
+ // recuperamos las direcciones y valores
+ List regAddrList = regConf.getList(CONF_NODE_S_REGISTERS_ADDR_KEY);
+ List regValueList = regConf.getList(CONF_NODE_S_REGISTERS_VALUE_KEY);
+ // componemos el resultado
+ for (int j = 0; j < regAddrList.size(); j++) {
+ String regAddr = (String) regAddrList.get(j);
+ String regValue = (String) regValueList.get(j);
+ registersNode.put(regAddr, regValue);
+ }
+ registers.put(nodeAddr, registersNode);
+ logger.debug(String.format("[ZigbeeDriver] Configuration: S_Registers Node %s = %s", nodeAddr, registersNode));
+
+ }
+
+ }
+
+ // devolvemos el resultado
+ return registers;
+
+
+ }
+
+ @Override
+ public void updated(Dictionary properties) {
+ logger.trace(String.format("Driver::updated(properties=%s)", properties));
+
+ // recorremos la configuracion
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ Object key = keys.nextElement();
+ if (CONF_AUTOSTART_KEY.equals((String) key)) {
+ CONF_AUTOSTART = (Boolean) properties.get(key);
+
+ } else if (CONF_ACK_TIMEOUT_KEY.equals((String) key)) {
+ CONF_ACK_TIMEOUT = (Long) properties.get(key);
+ } else if (CONF_REGISTER_READ_TIMEOUT_KEY.equals((String) key)) {
+ CONF_REGISTER_READ_TIMEOUT = (Long) properties.get(key);
+ } else if (CONF_REGISTER_WRITE_TIMEOUT_KEY.equals((String) key)) {
+ CONF_REGISTER_WRITE_TIMEOUT = (Long) properties.get(key);
+ } else if (CONF_ZDO_RESPONSE_TIMEOUT_KEY.equals((String) key)) {
+ CONF_ZDO_RESPONSE_TIMEOUT = (Long) properties.get(key);
+ } else if (CONF_NEIGHBOUR_RESPONSE_TIMEOUT_KEY.equals((String) key)) {
+ CONF_NEIGHBOUR_RESPONSE_TIMEOUT = (Long) properties.get(key);
+
+ } else if (CONF_S_REG_PASSWORD_KEY.equals((String) key)) {
+ CONF_S_REG_PASSWORD = (String) properties.get(key);
+ } else if (CONF_S_REG_XCAST_SOURCE_EP_KEY.equals((String) key)) {
+ CONF_S_REG_XCAST_SOURCE_EP = (String) properties.get(key);
+
+ } else if (CONF_CHECK_ZIGBEE_ERROR_KEY.equals((String) key)) {
+ CONF_CHECK_ZIGBEE_ERROR = (Boolean) properties.get(key);
+ } else if (CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_KEY.equals((String) key)) {
+ CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY = (Long) properties.get(key);
+ } else if (CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_KEY.equals((String) key)) {
+ CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD = (Long) properties.get(key);
+ } else if (CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_KEY.equals((String) key)) {
+ CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD = (Long) properties.get(key);
+ } else if (CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_KEY.equals((String) key)) {
+ CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1 = (Long) properties.get(key);
+ } else if (CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_KEY.equals((String) key)) {
+ CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2 = (Long) properties.get(key);
+
+ } else if (CONF_GET_NEIGHBOURS_KEY.equals((String) key)) {
+ CONF_GET_NEIGHBOURS = (Boolean) properties.get(key);
+ } else if (CONF_GET_NEIGHBOURS_FRAME_DELAY_KEY.equals((String) key)) {
+ CONF_GET_NEIGHBOURS_FRAME_DELAY = (Long) properties.get(key);
+ } else if (CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_KEY.equals((String) key)) {
+ CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD = (Long) properties.get(key);
+ } else if (CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_KEY.equals((String) key)) {
+ CONF_GET_NEIGHBOURS_RECOVERY_PERIOD = (Long) properties.get(key);
+
+ } else if (CONF_GET_PARENT_KEY.equals((String) key)) {
+ CONF_GET_PARENT = (Boolean) properties.get(key);
+ } else if (CONF_GET_PARENT_FRAME_DELAY_KEY.equals((String) key)) {
+ CONF_GET_PARENT_FRAME_DELAY = (Long) properties.get(key);
+ } else if (CONF_GET_PARENT_MAINTENANCE_PERIOD_KEY.equals((String) key)) {
+ CONF_GET_PARENT_MAINTENANCE_PERIOD = (Long) properties.get(key);
+ } else if (CONF_GET_PARENT_RECOVERY_PERIOD_KEY.equals((String) key)) {
+ CONF_GET_PARENT_RECOVERY_PERIOD = (Long) properties.get(key);
+
+ } else if (CONF_GET_ZIGBEE_DEVICES_KEY.equals((String) key)) {
+ CONF_GET_ZIGBEE_DEVICES = (Boolean) properties.get(key);
+ } else if (CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_KEY.equals((String) key)) {
+ CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY = (Long) properties.get(key);
+ } else if (CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_KEY.equals((String) key)) {
+ CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD = (Long) properties.get(key);
+
+ } else if (CONF_UPDATE_DONGLE_S_REGISTERS_KEY.equals((String) key)) {
+ CONF_UPDATE_DONGLE_S_REGISTERS = (Boolean) properties.get(key);
+ } else if (CONF_UPDATE_NODE_S_REGISTERS_KEY.equals((String) key)) {
+ CONF_UPDATE_NODE_S_REGISTERS = (Boolean) properties.get(key);
+ } else if (CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_KEY.equals((String) key)) {
+ CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY = (Long) properties.get(key);
+ } else if (CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_KEY.equals((String) key)) {
+ CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD = (Long) properties.get(key);
+ }
+
+ }
+
+ logger.info("[ZigbeeDriver] Configuration updated");
+ }
+
+ public Dictionary getCurrentConfiguration() {
+ logger.trace(String.format("Driver::getCurrentConfiguration()"));
+ Dictionary conf = new Hashtable<String, Object>();
+
+ conf.put(CONF_AUTOSTART_KEY, CONF_AUTOSTART);
+
+ conf.put(CONF_ACK_TIMEOUT_KEY, CONF_ACK_TIMEOUT);
+ conf.put(CONF_REGISTER_READ_TIMEOUT_KEY, CONF_REGISTER_READ_TIMEOUT);
+ conf.put(CONF_REGISTER_WRITE_TIMEOUT_KEY, CONF_REGISTER_WRITE_TIMEOUT);
+ conf.put(CONF_ZDO_RESPONSE_TIMEOUT_KEY, CONF_ZDO_RESPONSE_TIMEOUT);
+ conf.put(CONF_NEIGHBOUR_RESPONSE_TIMEOUT_KEY, CONF_NEIGHBOUR_RESPONSE_TIMEOUT);
+
+ conf.put(CONF_S_REG_PASSWORD_KEY, CONF_S_REG_PASSWORD);
+ conf.put(CONF_S_REG_XCAST_SOURCE_EP_KEY, CONF_S_REG_XCAST_SOURCE_EP);
+
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_KEY, CONF_CHECK_ZIGBEE_ERROR);
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_KEY, CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY);
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_KEY, CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD);
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_KEY, CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD);
+ conf.put(CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_KEY, CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1);
+ conf.put(CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_KEY, CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2);
+
+ conf.put(CONF_GET_NEIGHBOURS_KEY, CONF_GET_NEIGHBOURS);
+ conf.put(CONF_GET_NEIGHBOURS_FRAME_DELAY_KEY, CONF_GET_NEIGHBOURS_FRAME_DELAY);
+ conf.put(CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_KEY, CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD);
+ conf.put(CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_KEY, CONF_GET_NEIGHBOURS_RECOVERY_PERIOD);
+
+ conf.put(CONF_GET_PARENT_KEY, CONF_GET_PARENT);
+ conf.put(CONF_GET_PARENT_FRAME_DELAY_KEY, CONF_GET_PARENT_FRAME_DELAY);
+ conf.put(CONF_GET_PARENT_MAINTENANCE_PERIOD_KEY, CONF_GET_PARENT_MAINTENANCE_PERIOD);
+ conf.put(CONF_GET_PARENT_RECOVERY_PERIOD_KEY, CONF_GET_PARENT_RECOVERY_PERIOD);
+
+ conf.put(CONF_GET_ZIGBEE_DEVICES_KEY, CONF_GET_ZIGBEE_DEVICES);
+ conf.put(CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_KEY, CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY);
+ conf.put(CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_KEY, CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD);
+
+ conf.put(CONF_UPDATE_DONGLE_S_REGISTERS_KEY, CONF_UPDATE_DONGLE_S_REGISTERS);
+ conf.put(CONF_UPDATE_NODE_S_REGISTERS_KEY, CONF_UPDATE_NODE_S_REGISTERS);
+ conf.put(CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_KEY, CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY);
+ conf.put(CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_KEY, CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD);
+
+ return conf;
+
+ }
+
+ public Dictionary getDefaultConfiguration() {
+ logger.trace(String.format("Driver::getDefaultConfiguration()"));
+ Dictionary conf = new Hashtable<String, Object>();
+
+ conf.put(CONF_AUTOSTART_KEY, CONF_AUTOSTART_DEFAULT);
+
+ conf.put(CONF_ACK_TIMEOUT_KEY, CONF_ACK_TIMEOUT_DEFAULT);
+ conf.put(CONF_REGISTER_READ_TIMEOUT_KEY, CONF_REGISTER_READ_TIMEOUT_DEFAULT);
+ conf.put(CONF_REGISTER_WRITE_TIMEOUT_KEY, CONF_REGISTER_WRITE_TIMEOUT_DEFAULT);
+ conf.put(CONF_ZDO_RESPONSE_TIMEOUT_KEY, CONF_ZDO_RESPONSE_TIMEOUT_DEFAULT);
+ conf.put(CONF_NEIGHBOUR_RESPONSE_TIMEOUT_KEY, CONF_NEIGHBOUR_RESPONSE_TIMEOUT_DEFAULT);
+
+ conf.put(CONF_S_REG_PASSWORD_KEY, CONF_S_REG_PASSWORD_DEFAULT);
+ conf.put(CONF_S_REG_XCAST_SOURCE_EP_KEY, CONF_S_REG_XCAST_SOURCE_EP_DEFAULT);
+
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_KEY, CONF_CHECK_ZIGBEE_ERROR_DEFAULT);
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_KEY, CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY_DEFAULT);
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_KEY, CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD_DEFAULT);
+ conf.put(CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_KEY, CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD_DEFAULT);
+ conf.put(CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_KEY, CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1_DEFAULT);
+ conf.put(CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_KEY, CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2_DEFAULT);
+
+ conf.put(CONF_GET_NEIGHBOURS_KEY, CONF_GET_NEIGHBOURS_DEFAULT);
+ conf.put(CONF_GET_NEIGHBOURS_FRAME_DELAY_KEY, CONF_GET_NEIGHBOURS_FRAME_DELAY_DEFAULT);
+ conf.put(CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_KEY, CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD_DEFAULT);
+ conf.put(CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_KEY, CONF_GET_NEIGHBOURS_RECOVERY_PERIOD_DEFAULT);
+
+ conf.put(CONF_GET_PARENT_KEY, CONF_GET_PARENT_DEFAULT);
+ conf.put(CONF_GET_PARENT_FRAME_DELAY_KEY, CONF_GET_PARENT_FRAME_DELAY_DEFAULT);
+ conf.put(CONF_GET_PARENT_MAINTENANCE_PERIOD_KEY, CONF_GET_PARENT_MAINTENANCE_PERIOD_DEFAULT);
+ conf.put(CONF_GET_PARENT_RECOVERY_PERIOD_KEY, CONF_GET_PARENT_RECOVERY_PERIOD_DEFAULT);
+
+ conf.put(CONF_GET_ZIGBEE_DEVICES_KEY, CONF_GET_ZIGBEE_DEVICES_DEFAULT);
+ conf.put(CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_KEY, CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY_DEFAULT);
+ conf.put(CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_KEY, CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD_DEFAULT);
+
+ conf.put(CONF_UPDATE_DONGLE_S_REGISTERS_KEY, CONF_UPDATE_DONGLE_S_REGISTERS_DEFAULT);
+ conf.put(CONF_UPDATE_NODE_S_REGISTERS_KEY, CONF_UPDATE_NODE_S_REGISTERS_DEFAULT);
+ conf.put(CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_KEY, CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY_DEFAULT);
+ conf.put(CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_KEY, CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD_DEFAULT);
+
+ return conf;
+
+ }
+// </editor-fold>
+ //
+ // <editor-fold defaultstate="collapsed" desc="GESTION BLOQUEO">
+ private Locker locker = new Locker(this.getClass().getSimpleName());
+
+ @Override
+ public boolean tryLock(int milliseconds) {
+ logger.trace("Driver::tryLock(milliseconds=" + milliseconds + ")");
+ return locker.tryLock(milliseconds);
+
+ }
+
+ @Override
+ public void lock(int milliseconds) {
+ logger.trace("Driver::lock(milliseconds=" + milliseconds + ")");
+ locker.lock(milliseconds);
+
+ }
+
+ @Override
+ public boolean unlock() {
+ logger.trace("Driver::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">
+ final ArrayList<DriverListener> listeners = new ArrayList<DriverListener>();
+ final HashMap<DriverListener, Executor> executors = new HashMap<DriverListener, Executor>();
+
+ @Override
+ public void registerListener(DriverListener lstnr) {
+ synchronized (listeners) {
+ if (listeners.add(lstnr)) {
+ Executor ex = Executors.newSingleThreadExecutor();
+ executors.put(lstnr, ex);
+ }
+ }
+ }
+
+ @Override
+ public void unregisterListener(DriverListener lstnr) {
+ synchronized (listeners) {
+ if (listeners.remove(lstnr)) {
+ executors.remove(lstnr);
+ }
+ }
+ }
+
+ /**
+ * Notifies about new ZigbeeNode,
+ * @param node Node discovered
+ */
+ protected void fireNewNode(final ZigbeeNode node) {
+ logger.trace("Driver::fireNewNode(node=" + node + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.newNode(node, drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about new ZigbeeNode,
+ * @param device Node discovered
+ */
+ protected void fireNewDevice(final ZigbeeDevice device) {
+ logger.trace("Driver::fireNewDevice(device=" + device + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.newDevice(device, drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies for nodes leaving network (or disconnected)
+ * @param node Node leaving network
+ */
+ protected void fireNodeLeft(final ZigbeeNode node) {
+ logger.trace("Driver::fireNodeLeft(node=" + node + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.nodeLeft(node, drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies for devices leaving network (or disconnected)
+ * @param device Device leaving network
+ */
+ protected void fireDeviceLeft(final ZigbeeDevice device) {
+ logger.trace("Driver::fireDeviceLeft(device=" + device + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.deviceLeft(device, drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about joining network
+ * @param channel Network channel
+ * @param PANID Network PID
+ * @param EPID Network Extended PID
+ */
+ protected void fireJoinNetwork(final int channel, final String PANID, final String EPID) {
+ logger.trace("Driver::fireJoinNetwork(channel=" + channel + ", PANID=" + PANID + ", EPID=" + EPID + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.joinNetwork(channel, PANID, EPID, drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about leaving network
+ */
+ public void fireLeftNetwork() {
+ logger.trace("Driver::fireLeftNetwork()");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.leftNetwork(drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+
+ }
+
+ /**
+ * Notifies about status changed on a Driver,
+ * @param status current status
+ * @param oldStatus previous status
+ */
+ protected void fireStatusChanged(final DriverStatus status, final DriverStatus oldStatus) {
+ logger.trace("Driver::fireStatusChanged(status=" + status + ", oldStatus=" + oldStatus + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final Driver drv = this;
+ while (it.hasNext()) {
+ final DriverListener lstnr = (DriverListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.statusChanged(status, oldStatus, drv);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+ // </editor-fold>
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/Driver305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/Driver305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/Driver305.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,2109 @@
+/*
+ * 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.driver.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrACK;
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.maintenance.AbstractDriverMaintenanceTask;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.maintenance.ErrorCheckerDriverMaintenanceTask;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.maintenance.NeighbourFinderDriverMaintenanceTask;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.maintenance.NodeRegisterUpdaterDriverMaintenanceTask;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.maintenance.ParentFinderDriverMaintenanceTask;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.maintenance.ZigbeeDevicesFinderDriverMaintenanceTask;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrActiveEndPoints;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrEndPointDescriptor;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrNeighbourTableResponse;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrRegisterRead;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrRegisterWrited;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.GtwyLstnrSourceRoute;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.Register305;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.EUI64Address;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.NetworkAddress;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.NetworkInfo;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.NetworkScanInfo;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.ZigbeeNodeType;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.ZigbeeDeviceType;
+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.util.NeighbourTableEntry;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.NetworkInformation;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.NetworkJoinedInfo;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.util.PANScanResult;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class Driver305 extends AbstractDriver implements Driver, GatewayListener {
+
+ private final String SYNC_OPS = "SYNC"; // objeto referencia para exclusión mutua entre operaciones (synchronized(SYNC_COMMAND) { ... })
+ // flag para llevar control de mensaje enviado a endPoint (cambiada configuración de registros)
+ private boolean endPointMessageSent;
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ /**
+ * Driver constructor.
+ * Nota: antes de poder utilizarlo, hay que llamar a la función init(), que
+ * establecera el registro del gateway
+ * @param gtwy Gateway conectado
+ */
+ public Driver305(Gateway gtwy) {
+ super(gtwy);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ZigbeeDriver on %s", gateway.getDongleAddress());
+ }
+ // <editor-fold defaultstate="collapsed" desc="NETWORK CONTROL">
+
+ @Override
+ public NetworkInfo readNetworkInfo() {
+ logger.trace("Driver305::readNetworkInfo()");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return null;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ logger.info(String.format("[ZigbeeDriver] Retrieving network information from dongle"));
+ // consultamos al gateway la información de la red
+ NetworkInformation ni = gateway.getNetworkInformation();
+ if (ni != null) {
+ // adaptamos la respuesta al tipo de dato de retorno
+ NetworkInfo nwkI = new NetworkInfo(ni.getChannel(), ni.getPID(), ni.getEPID());
+
+ return nwkI;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public NetworkScanInfo[] findNetworks() {
+ logger.trace("Driver305::findNetworks()");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return null;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ // consultamos al gateway la información de la red
+ PANScanResult[] psr;
+ try {
+ logger.info(String.format("[ZigbeeDriver] Performing find network"));
+ psr = gateway.scanForActivePANs();
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error find network. %s", ex.getErrorMessage()), ex);
+ return null;
+ }
+ if (psr == null) {
+ return null;
+ }
+ logger.info(String.format("[ZigbeeDriver] Network scan: found %d networks", psr.length));
+ // convertimos el resultado al tipo de retorno
+ NetworkScanInfo[] nsi = new NetworkScanInfo[psr.length];
+ for (int i = 0; i < psr.length; i++) {
+ PANScanResult psri = psr[i];
+ nsi[i] = new NetworkScanInfo(psri.getChannel(), psri.getPANID(), psri.getEPID(), psri.getProfile(), psri.getJoinPermission());
+ }
+
+ // devolvemos el resultado
+ return nsi;
+ }
+ }
+
+ @Override
+ public boolean createNetwork() {
+ logger.trace("Driver305::createNetwork()");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot create network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ // solicitamos la creación de la red
+ try {
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to create network"));
+ NetworkJoinedInfo nji = gateway.createNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Created network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error create network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean createNetwork(String PID) {
+ logger.trace("Driver305::createNetwork(PID=" + PID + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot create network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong PID provided: " + PID);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // Limpiamos la link key
+ if (!clearLinkKey()){
+ return false;
+ }
+ // Establecemos el preferred PANID
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing Preferred PAN_ID %s", strPID));
+ gateway.writeRegister(Register305.PREFERRED_PAN_ID.getAddress(), strPID);
+ // solicitamos la creación de la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to create network"));
+ NetworkJoinedInfo nji = gateway.createNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Created network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error create network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+
+ }
+ }
+
+ @Override
+ public boolean createNetwork(int channel, String PID) {
+ logger.trace("Driver305::createNetwork(channel=" + channel + ", PID=" + PID + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot create network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong PID provided: " + PID);
+ return false;
+ }
+
+ // comprobamos canal
+ String strChannel = checkChannel(channel);
+ if (strChannel == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong channel provided: " + channel);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // Establecemos el preferred PANID
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing Preferred PAN_ID %s", strPID));
+ gateway.writeRegister(Register305.PREFERRED_PAN_ID.getAddress(), strPID);
+ // establecemos la máscara de canales
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing CHANNEL_MASK %s", strChannel));
+ gateway.writeRegister(Register305.CHANNEL_MASK.getAddress(), strChannel);
+ // Limpiamos la LinkKey
+ if (!clearLinkKey()){
+ return false;
+ }
+ // solicitamos la creación de la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to create network"));
+ NetworkJoinedInfo nji = gateway.createNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Created network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error create network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+
+ }
+ }
+
+ @Override
+ public boolean createNetwork(String PID, String linkKey) {
+ logger.trace("Driver305::createNetwork(PID=" + PID + ", linkKey=" + linkKey + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot create network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong PID provided: " + PID);
+ return false;
+ }
+ // comprobamos la clave proporcionada
+ String strLinkKey = checkLinkKey(linkKey);
+ if (strLinkKey == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong LinkKey provided: " + linkKey);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing Preferred PAN_ID %s", strPID));
+ gateway.writeRegister(Register305.PREFERRED_PAN_ID.getAddress(), strPID);
+ // establecemos la testLinkKey corregida
+ if (!setLinkKey(strLinkKey)){
+ return false;
+ }
+ // solicitamos la creación de la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to create network"));
+ NetworkJoinedInfo nji = gateway.createNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Created network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error create network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean createNetwork(int channel, String PID, String linkKey) {
+ logger.trace("Driver305::createNetwork(channel=" + channel + ", PID=" + PID + ", linkKey=" + linkKey + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot create network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong PID provided: " + PID);
+ return false;
+ }
+ // comprobamos canal
+ String strChannel = checkChannel(channel);
+ if (strChannel == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong channel provided: " + channel);
+ return false;
+ }
+
+ // comprobamos la clave proporcionada
+ String strLinkKey = checkLinkKey(linkKey);
+ if (strLinkKey == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong LinkKey provided: " + linkKey);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing Preferred PAN_ID %s", strPID));
+ gateway.writeRegister(Register305.PREFERRED_PAN_ID.getAddress(), strPID);
+ // establecemos la máscara de canales
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing CHANNEL_MASK %s", strChannel));
+ gateway.writeRegister(Register305.CHANNEL_MASK.getAddress(), strChannel);
+ // establecemos la testLinkKey corregida
+ if (!setLinkKey(strLinkKey)){
+ return false;
+ }
+ // solicitamos la creación de la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to create network"));
+ NetworkJoinedInfo nji = gateway.createNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Created network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error create network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Estalece la configuracion de LinkKey para el gateway, e indica que se usa
+ * @param linkKey Clave de red
+ * @return True si la establece, false en otro caso
+ */
+ private boolean setLinkKey(String linkKey) {
+ logger.trace("Driver305::setLinkKey(linkKey=" + linkKey + ")");
+
+ String donglePassword = ((ZigbeeNodeImpl) this.getDongle()).getRegisterPassword();
+
+ try {
+ // establecemos la testLinkKey corregida
+ logger.debug(String.format("[ZigbeeDriver] Set LinkKey: writing TRUST_CENTRE_LINK_KEY %s", linkKey));
+ gateway.writeRegister(Register305.TRUST_CENTRE_LINK_KEY.getAddress(), linkKey, CONF_S_REG_PASSWORD);
+
+ // indicamos que queremos utilizar la linkKey escribiendo el registro S0A
+ String regData = "001C"; // 0000 0000 0001 1100
+ logger.debug(String.format("[ZigbeeDriver] Set LinkKey: writing Main Functon %s", regData));
+ gateway.writeRegister(Register305.MAIN_FUNCTION.getAddress(), regData, CONF_S_REG_PASSWORD);
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error stabilishing LinKey. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+
+ return true;
+
+
+ }
+
+ /**
+ * Borra la LinkKey para el gateway, e indica que se no usa
+ * @return True si la establece, false en otro caso
+ */
+ private boolean clearLinkKey() {
+ logger.trace("Driver305::clearLinkKey()");
+
+ String donglePassword = ((ZigbeeNodeImpl) this.getDongle()).getRegisterPassword();
+ String linkKey = "00000000000000000000000000000000";
+
+ try {
+ // establecemos la testLinkKey corregida
+ logger.debug(String.format("[ZigbeeDriver] Set LinkKey: clearing TRUST_CENTRE_LINK_KEY %s", linkKey));
+ gateway.writeRegister(Register305.TRUST_CENTRE_LINK_KEY.getAddress(), linkKey, CONF_S_REG_PASSWORD);
+
+ // indicamos que NO queremos utilizar la linkKey escribiendo el registro S0A
+ String regData = "0000"; // 0000 0000 0000 0000
+ logger.debug(String.format("[ZigbeeDriver] Set LinkKey: writing Main Functon %s", regData));
+ gateway.writeRegister(Register305.MAIN_FUNCTION.getAddress(), regData, CONF_S_REG_PASSWORD);
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error stabilishing LinKey. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+
+ return true;
+
+
+ }
+
+ @Override
+ public boolean joinNetwork() {
+ logger.trace("Driver305::joinNetwork()");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot join network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos unirse a la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to join network"));
+ NetworkJoinedInfo nji = gateway.joinNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Joined network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error join network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean joinNetwork(String PID) {
+ logger.trace("Driver305::joinNetwork(PID=" + PID + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot join network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error join network. Wrong PID provided: " + PID);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // Limpiamos la LinkKey
+ if (!clearLinkKey()){
+ return false;
+ }
+ // Establecemos el preferred PANID
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing Preferred PAN_ID %s", strPID));
+ gateway.writeRegister(Register305.PREFERRED_PAN_ID.getAddress(), strPID);
+ // solicitamos unirse a la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to join network"));
+ NetworkJoinedInfo nji = gateway.joinNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Joined network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error join network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean joinNetwork(int channel, String PID) {
+ logger.trace("Driver305::joinNetwork(channel=" + channel + ", PID=" + PID + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot join network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos canal
+ String strChannel = checkChannel(channel);
+ if (strChannel == null) {
+ logger.warn("[ZigbeeDriver] Error join network. Wrong channel provided: " + channel);
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error join network. Wrong PID provided: " + PID);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // Limpiamos la LinkKey
+ if (!clearLinkKey()){
+ return false;
+ }
+ // solicitamos unirse a la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to join network"));
+ NetworkJoinedInfo nji = gateway.joinNetwork(channel, PID);
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Joined network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error join network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean joinNetwork(String PID, String linkKey) {
+ logger.trace("Driver305::joinNetwork(PID=" + PID + ", linkKey=" + linkKey + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot join network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error join network. Wrong PID provided: " + PID);
+ return false;
+ }
+
+ // comprobamos la clave proporcionada
+ String strLinkKey = checkLinkKey(linkKey);
+ if (strLinkKey == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong LinkKey provided: " + linkKey);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // Establecemos el preferred PANID
+ logger.debug(String.format("[ZigbeeDriver] Network create: writing Preferred PAN_ID %s", strPID));
+ gateway.writeRegister(Register305.PREFERRED_PAN_ID.getAddress(), strPID);
+ // establecemos la testLinkKey corregida
+ if (!setLinkKey(strLinkKey)){
+ return false;
+ }
+ // solicitamos unirse a la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to join network"));
+ NetworkJoinedInfo nji = gateway.joinNetwork();
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Joined network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error join network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean joinNetwork(int channel, String PID, String linkKey) {
+ logger.trace("Driver305::joinNetwork(channel=" + channel + ", PID=" + PID + ", linkKey=" + linkKey + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot join network while joined to another network.");
+ return false;
+ }
+
+ // comprobamos canal
+ String strChannel = checkChannel(channel);
+ if (strChannel == null) {
+ logger.warn("[ZigbeeDriver] Error join network. Wrong channel provided: " + channel);
+ return false;
+ }
+
+ // comprobamos el PANID
+ String strPID = checkHex4String(PID);
+ if (strPID == null) {
+ logger.warn("[ZigbeeDriver] Error join network. Wrong PID provided: " + PID);
+ return false;
+ }
+
+ // comprobamos la clave proporcionada
+ String strLinkKey = checkLinkKey(linkKey);
+ if (strLinkKey == null) {
+ logger.warn("[ZigbeeDriver] Error create network. Wrong LinkKey provided: " + linkKey);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // establecemos la testLinkKey corregida
+ if (!setLinkKey(strLinkKey)){
+ return false;
+ }
+ // solicitamos unirse a la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to join network"));
+ NetworkJoinedInfo nji = gateway.joinNetwork(channel, PID);
+ if (nji == null) {
+ return false;
+ } else {
+ logger.info("[ZigbeeDriver] Joined network: " + nji.toString());
+ setNetworkJoined(nji.getChannel(), nji.getPANID(), nji.getEPID());
+ return true;
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error join network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean leaveNetwork() {
+ logger.trace("Driver305::leaveNetwork()");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot leave network (not joined to any network)");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos abandonar la red
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to leave network"));
+ gateway.leaveNetwork();
+ setNetworkLeft();
+ return true;
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error leave network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean scanNetwork() {
+ logger.trace("Driver305::scanNetwork()");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos que el dongle es un FFD
+ switch (getDongle().getType()) {
+ case EndDevice:
+ case SleepyEndDevice:
+ case MobileEndDevice:
+ logger.warn("[ZigbeeDriver] Dongle is not a FFD, network scan not launched");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) { // sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos escanear la red completa (numhops = 0)
+ logger.info(String.format("[ZigbeeDriver] Requesting dongle to scan network for nodes"));
+ gateway.scanNetwork(0);
+ return true;
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error scan network. %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public boolean leaveNetwork(ZigbeeNode node) {
+ logger.trace("Driver305::leaveNetwork(node=" + node + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot request node leaving network if not joined to a network.");
+ return false;
+ }
+
+ // comprobamos si el nodo pertenece al driver
+ String EUI64Addr = node.getEUI64Addr().toString();
+ if (getNode(EUI64Addr) == null) {
+ logger.warn("[ZigbeeDriver] Provided node does not belong to network.");
+ return false;
+
+ }
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos el listener para esperar el ACK del mensaje
+ GtwyLstnrACK lstnr = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos abandonar la red
+ logger.info(String.format("[ZigbeeDriver] Requesting node %s to leave network", node));
+ seqNumber = gateway.leaveNetworkRequest(EUI64Addr);
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error requesting node %s leave network: %s", node, ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+
+ // Comprobamos el resultado despues del bloque de sincronización
+ if (lstnr.waitForACK(seqNumber, CONF_ACK_TIMEOUT)) {
+ // eliminamos el nodo
+ removeNode(node);
+
+ return true;
+
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error requesting node %s leave network (ACK TIMEOUT)", node));
+ return false;
+ }
+
+ }
+
+ @Override
+ public boolean sendMessage(ZigbeeNode node, byte[] message) {
+ logger.trace("Driver305::sendMessage(node=" + node + ", message=" + message + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot send messages if not joined to a network.");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos el listener para esperar el ACK del mensaje
+ GtwyLstnrACK lstnr = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ if (endPointMessageSent) { // restablecemos la configuración por defecto de telegesis
+ // Establecemos el profileID por defecto de telegesis
+ logger.debug(String.format("[ZigbeeDriver] Writing PROFILE_ID_FOR_XCASTS=%s on dongle", Register305.PROFILE_ID_FOR_XCASTS.getDefaultValue()));
+ gateway.writeRegister(Register305.PROFILE_ID_FOR_XCASTS.getAddress(), Register305.PROFILE_ID_FOR_XCASTS.getDefaultValue());
+ // Establecemos el clusterID por defecto de telegesis
+ logger.debug(String.format("[ZigbeeDriver] Writing CLUSTER_ID_FOR_XCASTS=%s on dongle", Register305.CLUSTER_ID_FOR_XCASTS.getDefaultValue()));
+ gateway.writeRegister(Register305.CLUSTER_ID_FOR_XCASTS.getAddress(), Register305.CLUSTER_ID_FOR_XCASTS.getDefaultValue());
+ // Establecemos el SourceDestEP por defecto de telegesis
+ logger.debug(String.format("[ZigbeeDriver] Writing SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS=%s on dongle", Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getDefaultValue()));
+ gateway.writeRegister(Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getAddress(), Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getDefaultValue());
+ // borramos el flag de configuración cambiada
+ endPointMessageSent = false;
+ }
+ // solicitamos enviar el mensaje
+ logger.info(String.format("[ZigbeeDriver] message sent to node %s", node));
+ seqNumber = gateway.sendMessageRequest(node.getEUI64Addr().toString(), message);
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error sending message to node %s: %s", node, ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+
+ // después del bloque de sincronización, comprobamos la correcta recepción del mensaje
+ // esto lo hacemos asà para no bloquear todo el driver mientras se espera la respuesta
+ // del ACK, y devolvemos el resultado de la espera
+ return lstnr.waitForACK(seqNumber, CONF_ACK_TIMEOUT);
+
+ }
+
+ @Override
+ public boolean sendMessage(ZigbeeDevice device, String profileID, String clusterID, byte[] message) {
+ logger.trace("Driver305::sendMessage(device=" + device + ", profileID=" + profileID + ", clusterID=" + clusterID + ", message=" + message + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot send messages if not joined to a network.");
+ return false;
+ }
+
+ // comprobamos profileID == null
+ if (profileID == null) {
+ profileID = device.getProfileId();
+ }
+
+ // componemos EndPoint
+ String strSourceDestEP = String.format("%s%02X", CONF_S_REG_XCAST_SOURCE_EP, device.getEndPoint());
+
+ // comprobamos profileID
+ String strProfileID = checkHex4String(profileID);
+ if (strProfileID == null) {
+ logger.warn("[ZigbeeDriver] Error sending message. Wrong profileID provided: " + profileID);
+ return false;
+ }
+
+ // comprobamos el ClusterID
+ String strClusterID = checkHex4String(clusterID);
+ if (strClusterID == null) {
+ logger.warn("[ZigbeeDriver] Error sending message. Wrong clusterID provided: " + clusterID);
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos el listener para esperar el ACK del mensaje
+ GtwyLstnrACK lstnr = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // Establecemos el profileID
+ logger.debug(String.format("[ZigbeeDriver] Writing PROFILE_ID_FOR_XCASTS=%s on dongle", strProfileID));
+ gateway.writeRegister(Register305.PROFILE_ID_FOR_XCASTS.getAddress(), strProfileID);
+ // Establecemos el clusterID
+ logger.debug(String.format("[ZigbeeDriver] Writing CLUSTER_ID_FOR_XCASTS=%s on dongle", strClusterID));
+ gateway.writeRegister(Register305.CLUSTER_ID_FOR_XCASTS.getAddress(), strClusterID);
+ // Establecemos el SourceDestEP
+ logger.debug(String.format("[ZigbeeDriver] Writing SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS=%s on dongle", strSourceDestEP));
+ gateway.writeRegister(Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getAddress(), strSourceDestEP);
+
+ // marcamos flag de configuracion cambiada
+ endPointMessageSent = true;
+
+ // solicitamos enviar el mensaje
+ logger.info(String.format("[ZigbeeDriver] Sending message to device %s", device));
+ seqNumber = gateway.sendMessageRequest(device.getZigbeeNode().getEUI64Addr().toString(), message);
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error sending message to device %s: %s", device, ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+
+ // después del bloque de sincronización, comprobamos la correcta recepción del mensaje
+ // esto lo hacemos asà para no bloquear todo el driver mientras se espera la respuesta
+ // del ACK, y devolvemos el resultado de la espera
+ return lstnr.waitForACK(seqNumber, CONF_ACK_TIMEOUT);
+
+ }
+
+ @Override
+ public boolean sendBroadcastMessage(byte[] message) {
+ logger.trace("Driver305::sendBroadcastMessage(message=" + message + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot send messages if not joined to a network.");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ if (endPointMessageSent) { // restablecemos la configuración por defecto de telegesis
+ // Establecemos el profileID por defecto de telegesis
+ logger.debug(String.format("[ZigbeeDriver] Writing PROFILE_ID_FOR_XCASTS=%s on dongle", Register305.PROFILE_ID_FOR_XCASTS.getDefaultValue()));
+ gateway.writeRegister(Register305.PROFILE_ID_FOR_XCASTS.getAddress(), Register305.PROFILE_ID_FOR_XCASTS.getDefaultValue());
+ // Establecemos el clusterID por defecto de telegesis
+ logger.debug(String.format("[ZigbeeDriver] Writing CLUSTER_ID_FOR_XCASTS=%s on dongle", Register305.CLUSTER_ID_FOR_XCASTS.getDefaultValue()));
+ gateway.writeRegister(Register305.CLUSTER_ID_FOR_XCASTS.getAddress(), Register305.CLUSTER_ID_FOR_XCASTS.getDefaultValue());
+ // Establecemos el SourceDestEP por defecto de telegesis
+ logger.debug(String.format("[ZigbeeDriver] Writing SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS=%s on dongle", Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getDefaultValue()));
+ gateway.writeRegister(Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getAddress(), Register305.SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS.getDefaultValue());
+ // borramos el flag de configuración cambiada
+ endPointMessageSent = false;
+ }
+ // solicitamos enviar el mensaje con numHops = 0 (todos)
+ logger.info("[ZigbeeDriver] Sending broadcast message");
+ gateway.sendBroadcast(0, message);
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error sending broadcast: %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+
+ // devolvemos OK
+ return true;
+ }
+
+ @Override
+ public String readRegister(ZigbeeNode node, short regAddress) {
+ logger.trace("Driver305::readRegister(node=" + node + ", regAddress=" + regAddress + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return null;
+ }
+
+ // comprobamos nodo != null
+ if (node == null) {
+ logger.debug("[ZigbeeDriver] llamada a read register con node = null");
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // comprobamos si se trata del dongle
+ if (node.equals(getDongle())) {
+ try {
+ logger.info(String.format("[ZigbeeDriver] Reading register %02X on dongle", regAddress));
+ String regData = gateway.readRegister(regAddress);
+ return regData;
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error reading local %02X register: %s", regAddress, ex), ex);
+ return null;
+ }
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot read remote registers if not joined to a network.");
+ return null;
+ }
+
+ // creamos los listeners para esperar el ACK del mensaje y la lectura del registro
+ GtwyLstnrRegisterRead lstnrRead = new GtwyLstnrRegisterRead(gateway);
+ GtwyLstnrACK lstnrACK = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos leer el registro
+ logger.info(String.format("[ZigbeeDriver] Requesting reading register %02X on node %s", regAddress, node));
+ seqNumber = gateway.readRemoteRegisterRequest(node.getEUI64Addr().toString(), regAddress);
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error reading %02X register on node %s: %s", regAddress, node, ex.getErrorMessage()), ex);
+ lstnrACK.clearListener();
+ lstnrRead.clearListener();
+ return null;
+ }
+ }
+
+ // Esperamos el ACK del nodo, y en caso de error, devolvemos null
+ if (!lstnrACK.waitForACK(seqNumber, CONF_ACK_TIMEOUT)) {
+ logger.warn(String.format("[ZigbeeDriver] Error while reading register %02X on node %s (NACK or timeout)", regAddress, node));
+ lstnrRead.clearListener();
+ return null;
+ }
+
+ // Esperamos el resultado de la operación de lectura
+ if (lstnrRead.waitForRegisterReaded(node.getEUI64Addr().toString(), regAddress, CONF_REGISTER_READ_TIMEOUT)) {
+ logger.info(String.format("[ZigbeeDriver] Register %02X on node %s readed ", regAddress, node));
+ return lstnrRead.getRegisterData();
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error while reading register %02X on node %s. Error: %s", regAddress, node, lstnrRead.getErrorMessage()));
+ return null;
+ }
+
+ }
+
+ @Override
+ public boolean writeRegister(ZigbeeNode node, short regAddress, String data) {
+ logger.trace("Driver305::writeRegister(node=" + node + ", regAddress=" + regAddress + ", data=" + data + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos nodo != null
+ if (node == null) {
+ logger.debug("[ZigbeeDriver] llamada a write register con node = null");
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ Register305 register = Register305.fromByte(regAddress);
+
+ // comprobamos si se trata del dongle
+ if (node.equals(getDongle())) {
+ try {
+ // comprobamos si hace falta contraseña
+ if (register.requiresPassword()) {
+ logger.info(String.format("[ZigbeeDriver] Requesting writing password protected register %02X on dongle", regAddress));
+ gateway.writeRegister(regAddress, data, ((ZigbeeNodeImpl) node).getRegisterPassword());
+ } else {
+ logger.info(String.format("[ZigbeeDriver] Requesting writing register %02X on dongle", regAddress));
+ gateway.writeRegister(regAddress, data);
+ }
+ return true;
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error writing local %02X register: %s", regAddress, ex), ex);
+ return false;
+ }
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot write remote registers if not joined to a network.");
+ return false;
+ }
+
+ // creamos los listeners para esperar el ACK del mensaje y la escritura del registro
+ GtwyLstnrRegisterWrited lstnrWrite = new GtwyLstnrRegisterWrited(gateway);
+ GtwyLstnrACK lstnrACK = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // comprobamos si hace falta contraseña
+ if (register.requiresPassword()) {
+ // solicitamos escribir el registro conn contraseña
+ logger.info(String.format("[ZigbeeDriver] Requesting writing password protected register %02X on node %s", regAddress, node));
+ seqNumber = gateway.writeRemoteRegisterRequest(node.getEUI64Addr().toString(), regAddress, data, ((ZigbeeNodeImpl) node).getRegisterPassword());
+ } else {
+ // solicitamos escribir el registro sin contraseña
+ logger.info(String.format("[ZigbeeDriver] Requesting writing register %02X on node %s", regAddress, node));
+ seqNumber = gateway.writeRemoteRegisterRequest(node.getEUI64Addr().toString(), regAddress, data);
+ }
+
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error writing %02X register on node %s: %s", regAddress, node, ex.getErrorMessage()), ex);
+ lstnrACK.clearListener();
+ lstnrWrite.clearListener();
+ return false;
+ }
+ }
+
+ // Esperamos el ACK del nodo, y en caso de error, devolvemos false
+ if (!lstnrACK.waitForACK(seqNumber, CONF_ACK_TIMEOUT)) {
+ logger.warn(String.format("[ZigbeeDriver] Error while writing register %02X on node %s (NACK or timeout)", regAddress, node));
+ lstnrWrite.clearListener();
+ return false;
+ }
+
+ // Esperamos el resultado de la operación de escritura
+ if (lstnrWrite.waitForRegisterWrited(node.getEUI64Addr().toString(), CONF_REGISTER_WRITE_TIMEOUT)) {
+ logger.info(String.format("[ZigbeeDriver] Register %02X on node %s writed", regAddress, node));
+ return true;
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error while writing register %02X on node %s. Error: %s ", regAddress, node, lstnrWrite.getErrorMessage()));
+ return false;
+
+ }
+
+ }
+
+ // </editor-fold>
+ //
+ // <editor-fold defaultstate="collapsed" desc="NODE DISCOVERY">
+ @Override
+ public boolean updateActiveEndPoints(ZigbeeNode node) {
+ logger.trace("Driver305::requestActiveEndPoints(node=" + node + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si es el dongle
+ if (!node.equals(getDongle())) {
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot access remote devices if not joined to a network.");
+ return false;
+ }
+ }
+
+ // direccion del nodo sobre el que se consulta
+ NetworkAddress nodeID = node.getNodeID();
+ if (nodeID == null) {
+ logger.warn("[ZigbeeDriver] Cannot perform ZDO request for unknown NodeID.");
+ return false;
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos los listeners para esperar el ACK del mensaje y la lista de endPoints
+ GtwyLstnrActiveEndPoints lstnrEPList = new GtwyLstnrActiveEndPoints(gateway);
+ GtwyLstnrACK lstnrACK = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ // direccion del nodo al que se realiza la consulta: dongle
+ String consultingNodeAddr = this.getDongle().getEUI64Addr().toString();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos la lista de endPoints
+ logger.info(String.format("[ZigbeeDriver] Requesting active end points on node %s", node));
+ seqNumber = gateway.requestNodeActiveEndPoints(consultingNodeAddr, nodeID.toString());
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error requesting active end points on node %s: %s", node, ex.getErrorMessage()), ex);
+ lstnrACK.clearListener();
+ lstnrEPList.clearListener();
+ return false;
+ }
+ }
+
+ // Esperamos el ACK del nodo, y en caso de error, devolvemos false
+ if (!lstnrACK.waitForACK(seqNumber, CONF_ACK_TIMEOUT)) {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting active EndPoints on node %s (NACK or timeout)", node));
+ lstnrEPList.clearListener();
+ return false;
+ }
+
+ // Esperamos el resultado de la consulta de endPoints
+ if (lstnrEPList.waitForActiveEndPoints(nodeID.toString(), CONF_ZDO_RESPONSE_TIMEOUT)) {
+ short[] EPList = lstnrEPList.getEndPointList();
+ // comprobamos los device del nodo
+ for (int i = 0; i < EPList.length; i++) {
+ ZigbeeDevice device = node.getZigbeeDevice(EPList[i]);
+ // si no existe lo creamos
+ if (device == null) {
+ device = createDevice(node, EPList[i]);
+ }
+ }
+ logger.info(String.format("[ZigbeeDriver] EndPoints node %s updated", node));
+ return true;
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting active EndPoints on node %s. Error: %s ", node, lstnrEPList.getErrorMessage()));
+ return false;
+ }
+
+ }
+
+ @Override
+ public boolean updateEndPointDescriptor(ZigbeeDevice device) {
+ logger.trace("Driver305::requestEndPointDescriptor(device=" + device + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+
+ // comprobamos si es el dongle
+ if (!device.getZigbeeNode().equals(getDongle())) {
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot access remote devices if not joined to a network.");
+ return false;
+ }
+ }
+
+ // direccion del nodo sobre el que se consulta
+ NetworkAddress nodeID = device.getZigbeeNode().getNodeID();
+ if (nodeID == null) {
+ logger.warn("[ZigbeeDriver] Cannot perform ZDO request for unknown NodeID.");
+ return false;
+ }
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos los listeners para esperar el ACK del mensaje y el descriptor del device
+ GtwyLstnrEndPointDescriptor lstnrEP = new GtwyLstnrEndPointDescriptor(gateway);
+ GtwyLstnrACK lstnrACK = new GtwyLstnrACK(gateway);
+
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ // direccion del nodo al que se realiza la consulta: dongle
+ String consultingNodeAddr = this.getDongle().getEUI64Addr().toString();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos el decriptor del endPoint
+ logger.info(String.format("[ZigbeeDriver] Requesting end point descriptor for device %s", device));
+ seqNumber = gateway.requestNodeEndPointSimpleDescriptor(consultingNodeAddr, nodeID.toString(), device.getEndPoint());
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error requesting descriptor for device %s: %s", device, ex.getErrorMessage()), ex);
+ lstnrACK.clearListener();
+ lstnrEP.clearListener();
+ return false;
+ }
+ }
+
+ // Esperamos el ACK del nodo, y en caso de error, devolvemos false
+ if (!lstnrACK.waitForACK(seqNumber, CONF_ACK_TIMEOUT)) {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting EndPoint descriptor on device %s (NACK or timeout)", device));
+ lstnrEP.clearListener();
+ return false;
+ }
+
+ // Esperamos el resultado de la operación
+ if (lstnrEP.waitForEndPointSimpleDescriptor(nodeID.toString(), device.getEndPoint(), CONF_ZDO_RESPONSE_TIMEOUT)) {
+ ZigbeeDevice auxDevice = lstnrEP.getEndPointDescriptor();
+ // actualizamos el device
+ ((ZigbeeDeviceImpl) device).setProfileID(auxDevice.getProfileId());
+ ((ZigbeeDeviceImpl) device).setDeviceID(auxDevice.getDeviceId());
+ ((ZigbeeDeviceImpl) device).setInClusterList(auxDevice.getInClusterList());
+ ((ZigbeeDeviceImpl) device).setOutClusterList(auxDevice.getOutClusterList());
+ logger.info(String.format("[ZigbeeDriver] EndPoint descriptor on device %s updated", device));
+ // devolvemos resultado OK
+ return true;
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting EndPoint descriptor on device %s. Error: %s", device, lstnrEP.getErrorMessage()));
+ return false;
+ }
+
+ }
+
+ @Override
+ public boolean updateNeighbourTable(ZigbeeNode node) {
+ logger.trace("Driver305::updateNeighbourTable(node=" + node + ")");
+
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot retreive neighbours if not joined to a network.");
+ return false;
+ }
+
+ // creamos el listener para almacenar resultados de busqueda
+ GtwyLstnrNeighbourTableResponse lstnrNTR = null;
+ // creamos un bucle para recuperar la tabla, usando una variable de control
+ boolean done = false;
+ int nextIndex = 0;
+ while (!done) {
+ // recuperamos el siguiente grupo de vecinos
+ lstnrNTR = launchNeighbourTableRequest(node, nextIndex);
+
+ // comprobamos resultado
+ if (lstnrNTR != null) {
+ NeighbourTableEntry[] table = lstnrNTR.getNeighbourTable();
+ int tableLength = lstnrNTR.getNeighbourTableLength();
+ // Recorremos la tabla de vecinos
+ for (int i = 0; i < table.length; i++) {
+ NeighbourTableEntry nte = table[i];
+ // recuperamos el vecino
+ ZigbeeNode neighbour = getNode(nte.getEUI64Addr());
+ // si no existe, lo creamos
+ if (neighbour == null) {
+ EUI64Address nAddress = new EUI64Address(nte.getEUI64Addr());
+ NetworkAddress nNodeID = new NetworkAddress(nte.getID());
+ ZigbeeNodeType nType = ZigbeeNodeType.fromZigbeeDeviceType(nte.getType());
+ neighbour = createNode(nAddress, nNodeID, nType);
+ }
+
+ // guardamos el vecino
+ ((ZigbeeNodeImpl) node).addNode(neighbour); //TODO: incluir LQI
+
+ // calculamos el siguiente Ãndice de la tabla para comparar
+ // con la longitud de la tabla
+ nextIndex = nte.getIndex() + 1;
+ }
+
+ // comprobamos si hay que consultar más nodos
+ if (nextIndex == tableLength) {
+ done = true;
+ }
+
+ } else { //if (lstnrNTR != null)
+ // devolvemos error
+ return false;
+ }
+ }
+
+ // devolvemos OK, ya que si ha habido un error antes, habremos abandonado ya
+ logger.info(String.format("[ZigbeeDriver] Neighbours on node %s updated", node));
+ return true;
+
+ }
+
+ /**
+ * Lanza una consulta de la tabla de vecinos de un nodo, a partir de un indice determinado
+ * @param node Nodo para consultar vecinos
+ * @param startIndex Ãndice de acceso a la tabla de vecinos
+ * @return el GtwyLstnrNeighbourTableResponse usado para esperar la
+ * respuesta si la busqueda se ha realizado correctamente, o null en otro
+ * caso. Elegimos este tipo de retorno porque ya almacena la tabla de
+ * vecinos recuperada y la longitud total
+ */
+ private GtwyLstnrNeighbourTableResponse launchNeighbourTableRequest(ZigbeeNode node, int startIndex) {
+ logger.trace("Driver305::launchNeighbourTableRequest(node=" + node + ", startIndex=" + startIndex + ")");
+
+ // comprobamos si estamos unidos a la red
+ if (getNetworkInfo() == null) {
+ return null;
+ }
+
+ // direccion del nodo sobre el que se consulta
+ NetworkAddress nodeID = node.getNodeID();
+ if (nodeID == null) {
+ logger.warn("[ZigbeeDriver] Cannot perform ZDO request for unknown NodeID.");
+ return null;
+ }
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos los listeners para esperar el ACK del mensaje y la tabla de vecinos
+ GtwyLstnrNeighbourTableResponse lstnrNTR = new GtwyLstnrNeighbourTableResponse(gateway);
+ GtwyLstnrACK lstnrACK = new GtwyLstnrACK(gateway);
+ // seqNumber para comprobar envÃo del mensaje
+ short seqNumber;
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos la tabla de vecinos
+ logger.info(String.format("[ZigbeeDriver] Requesting Neighbour table for node %s (starting index %d)", node, startIndex));
+ seqNumber = gateway.requestNeighbourTable((short) startIndex, node.getEUI64Addr().toString());
+
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error requesting neighbour table for node %s: %s", node, ex.getErrorMessage()), ex);
+ lstnrACK.clearListener();
+ lstnrNTR.clearListener();
+ return null;
+ }
+ }
+
+ // Esperamos el ACK del nodo, y en caso de error, devolvemos false
+ if (!lstnrACK.waitForACK(seqNumber, CONF_ACK_TIMEOUT)) {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting neighbours on node %s (NACK or timeout)", node));
+ lstnrNTR.clearListener();
+ return null;
+ }
+
+ // Esperamos el resultado de la operación
+ if (lstnrNTR.waitForNeighbourTableResponse(nodeID.toString(), CONF_NEIGHBOUR_RESPONSE_TIMEOUT)) {
+ // devolvemos el listener
+ return lstnrNTR;
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting neighbours on node %s. Error: %s", node, lstnrNTR.getErrorMessage()));
+ return null;
+ }
+
+ }
+
+ @Override
+ public boolean findRoute(ZigbeeNode node) {
+ logger.trace("Driver305::findRoute(node=" + node + ")");
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ return false;
+ }
+
+ // comprobamos si es el dongle
+ if (!node.equals(getDongle())) {
+ // comprobamos si estamos unidos a la red
+ if (!isJoinedToNetwork()) {
+ logger.warn("[ZigbeeDriver] Cannot access remote devices if not joined to a network.");
+ return false;
+ }
+ }
+
+ // comprobamos el bloqueo del driver
+ checkLock();
+
+ // creamos el listener para esperar la ruta
+ GtwyLstnrSourceRoute lstnrSR = new GtwyLstnrSourceRoute(gateway);
+ // recuperamos la direccion del nodo
+ String EUI64Addr = node.getEUI64Addr().toString();
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+ try {
+ // solicitamos al gateway la la busqueda de la ruta
+ logger.info(String.format("[ZigbeeDriver] Requesting find route for node %s", node));
+ gateway.findRoute(EUI64Addr);
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error requesting source route on node %s: %s", node, ex.getErrorMessage()), ex);
+ lstnrSR.clearListener();
+ return false;
+ }
+
+ }
+
+ // Esperamos respuesta del nodo, y en caso de error, devolvemos false
+ if (lstnrSR.waitForSourceRoute(EUI64Addr, CONF_ZDO_RESPONSE_TIMEOUT)) {
+ return true;
+ } else {
+ logger.warn(String.format("[ZigbeeDriver] Error while requesting source route on node %s (Timeout)", node));
+ return false;
+ }
+
+ /*
+ * Nota: no actualizamos la ruta, ya que el driver actualiza
+ * automáticamente las rutas cuando se recibe el mensaje. usamos el
+ * listener unicamente para controlar la notificacion
+ */
+
+
+ }
+ // </editor-fold>
+//
+ // <editor-fold defaultstate="collapsed" desc="DRIVER CONTROL">
+// Procedimientos autonomos controlados por el driver
+ AbstractDriverMaintenanceTask errorChecker;
+ AbstractDriverMaintenanceTask neighbourFinder;
+ AbstractDriverMaintenanceTask registerWriter;
+ AbstractDriverMaintenanceTask devicesFinder;
+ AbstractDriverMaintenanceTask parentFinder;
+
+ @Override
+ public void disable() {
+ logger.trace("Driver305::disable()");
+
+ // desregistramos como listener del gateway
+ gateway.unregisterListener(this);
+
+ // actualizamos el estado
+ setStatus(DriverStatus.Disabled);
+
+ logger.info(String.format("[ZigbeeDriver] Driver disabled"));
+
+ }
+
+ @Override
+ public boolean init() {
+ logger.trace("Driver305::init()");
+
+ // comprobamos que tenemos gateway
+ if (gateway == null) {
+ logger.warn(String.format("[ZigbeeDriver] Cannot initialize driver: null gateway"));
+ return false;
+ }
+
+ logger.info(String.format("[ZigbeeDriver] Initializing driver..."));
+ // actualizamos el estado
+ this.setStatus(DriverStatus.Initializing);
+
+ // cargamos la configuracion
+ this.loadConfiguration();
+
+ // Bloqueamos el gateway durante el tiempo de inicializacion
+ gateway.lock(GATEWAY_INITIALIZATION_LOCK_TIME);
+
+ synchronized (SYNC_OPS) {// sincronizamos para evitar solape de comandos
+
+ // consultamos la información de la red
+ NetworkInformation ni = gateway.getNetworkInformation();
+ String dongleNodeID = null;
+ ZigbeeNodeType dongleType = ZigbeeNodeType.Unknown;
+ if (ni != null) {
+ // establecemos la información de la red
+ setNetworkJoined(ni.getChannel(), ni.getPID(), ni.getEPID());
+
+ dongleType = ZigbeeNodeType.fromZigbeeDeviceType(ni.getDeviceType());
+
+ // consultamos el nodeID del dongle
+ try {
+ dongleNodeID = gateway.readRegister(Register305.LOCAL_NODEID.getAddress());
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error initializing driver, error requesting dongle nodeID: %s", ex.getErrorMessage()), ex);
+ }
+ }
+
+
+ //creamos el dongle
+ createDongle(gateway.getDongleAddress(), dongleNodeID, dongleType);
+
+ // establecemos la configuracion de registros del dongle
+ if (CONF_UPDATE_DONGLE_S_REGISTERS) {
+ logger.info(String.format("[ZigbeeDriver] writing register to dongle..."));
+ // recuperamos los registros
+ HashMap<String, String> dongleRegisters = getDongleRegisterConfig();
+ Iterator it = dongleRegisters.keySet().iterator();
+ while (it.hasNext()) {
+ try {
+ // recuperamos el registro
+ String regStrAddr = (String) it.next();
+ short regAddr = (short) Integer.parseInt(regStrAddr, 16);
+ String regValue = dongleRegisters.get(regStrAddr);
+ Register305 reg = Register305.fromByte(regAddr);
+ if (reg.isWritable()) {
+ if (reg.requiresPassword()) {
+ gateway.writeRegister(regAddr, regValue, CONF_S_REG_PASSWORD);
+ } else {
+ gateway.writeRegister(regAddr, regValue);
+ }
+ }
+ } catch (TelegesisErrorException ex) {
+ logger.warn(String.format("[ZigbeeDriver] Error initializing driver: %s", ex.getErrorMessage()), ex);
+ return false;
+ }
+ }
+ }
+
+ // registramos el listener
+ gateway.registerListener(this);
+
+ // actualizamos estado del driver
+ this.setStatus(DriverStatus.Ready);
+
+ // liberamos bloqueo del gateway
+ gateway.unlock();
+
+ // comprobamos si hay que arrancar el driver
+ if (CONF_AUTOSTART) {
+ start();
+ }
+
+ // devolvemos OK
+ return true;
+
+ }
+
+ }
+
+ @Override
+ public boolean start() {
+ logger.trace("Driver305::start()");
+
+ logger.info(String.format("[ZigbeeDriver] Driver starting..."));
+
+ // comprobamos el estado del driver
+ if (!isEnabled()) {
+ logger.warn(String.format("[ZigbeeDriver] Cannot start driver (disabled)"));
+ return false;
+ }
+
+ // Comprobacion de errores de nodo
+ if (CONF_CHECK_ZIGBEE_ERROR) {
+ logger.info(String.format("[ZigbeeDriver] Launching ErrorChecker driver maintenance task..."));
+ // creamos el comprobador de errores
+ errorChecker = new ErrorCheckerDriverMaintenanceTask();
+ errorChecker.setFrameDelay(CONF_CHECK_ZIGBEE_ERROR_FRAME_DELAY);
+ errorChecker.setMaintenanceTime(CONF_CHECK_ZIGBEE_ERROR_MAINTENANCE_PERIOD);
+ errorChecker.setRecoveryTime(CONF_CHECK_ZIGBEE_ERROR_RECOVERY_PERIOD);
+ errorChecker.start(this);
+ }
+ // buscador de vecinos
+ if (CONF_GET_NEIGHBOURS) {
+ // creamos el buscador de vecinos de los nodos
+ logger.info(String.format("[ZigbeeDriver] Launching NeighbourFinder driver maintenance task..."));
+ neighbourFinder = new NeighbourFinderDriverMaintenanceTask();
+ neighbourFinder.setFrameDelay(CONF_GET_NEIGHBOURS_FRAME_DELAY);
+ neighbourFinder.setMaintenanceTime(CONF_GET_NEIGHBOURS_MAINTENANCE_PERIOD);
+ neighbourFinder.setRecoveryTime(CONF_GET_NEIGHBOURS_RECOVERY_PERIOD);
+ neighbourFinder.start(this);
+ }
+ // buscador de padres
+ if (CONF_GET_PARENT) {
+ // creamos el buscador de padres de los nodos
+ logger.info(String.format("[ZigbeeDriver] Launching ParentFinder driver maintenance task..."));
+ parentFinder = new ParentFinderDriverMaintenanceTask();
+ parentFinder.setFrameDelay(CONF_GET_PARENT_FRAME_DELAY);
+ parentFinder.setMaintenanceTime(CONF_GET_PARENT_MAINTENANCE_PERIOD);
+ parentFinder.setRecoveryTime(CONF_GET_PARENT_RECOVERY_PERIOD);
+ parentFinder.start(this);
+ }
+ // configurador de registros
+ if (CONF_UPDATE_NODE_S_REGISTERS) {
+ // creamos el configurador de registros de los nodos
+ logger.info(String.format("[ZigbeeDriver] Launching RegisterWriter driver maintenance task..."));
+ registerWriter = new NodeRegisterUpdaterDriverMaintenanceTask();
+ registerWriter.setFrameDelay(CONF_UPDATE_NODE_S_REGISTERS_FRAME_DELAY);
+ registerWriter.setRecoveryTime(CONF_UPDATE_NODE_S_REGISTERS_RECOVERY_PERIOD);
+ registerWriter.start(this);
+ }
+ // buscador de endpoints
+ if (CONF_GET_ZIGBEE_DEVICES) {
+ // creamos el buscador de enpoints de los nodos
+ logger.info(String.format("[ZigbeeDriver] Launching DevicesFinder driver maintenance task..."));
+ devicesFinder = new ZigbeeDevicesFinderDriverMaintenanceTask();
+ devicesFinder.setFrameDelay(CONF_GET_ZIGBEE_DEVICES_FRAME_DELAY);
+ devicesFinder.setRecoveryTime(CONF_GET_ZIGBEE_DEVICES_RECOVERY_PERIOD);
+ devicesFinder.start(this);
+ }
+
+ logger.info(String.format("[ZigbeeDriver] Driver started."));
+
+ // actualizamos el estado
+ setStatus(DriverStatus.Running);
+
+ // devolvemos OK
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ logger.trace("Driver::stop()");
+
+ // establecemos el estado a stopping, y eso hará que el driver se pare
+ this.setStatus(DriverStatus.Stopping);
+ logger.info(String.format("[ZigbeeDriver] Driver stopping..."));
+
+ // paramos las tareas en segundo plano
+ launchStoppingMaintenanceTasks();
+
+ return true;
+
+ }
+
+ protected void launchStoppingMaintenanceTasks() {
+ logger.trace("Driver::launchStoppingMaintenanceTasks()");
+
+ // creamos la tarea para parar las tareas
+ Runnable target = new Runnable() {
+
+ @Override
+ public void run() {
+ // control de errores
+ if (errorChecker != null) {
+ logger.info("[ZigbeeDriver] Stopping errorChecker maintenance task");
+ errorChecker.stop();
+ logger.info("[ZigbeeDriver] errorChecker stopped");
+ }
+ // buscador de vecinos
+ if (neighbourFinder != null) {
+ logger.info("[ZigbeeDriver] Stopping neighbourFinder maintenance task");
+ neighbourFinder.stop();
+ logger.info("[ZigbeeDriver] neighbourFinder stopped");
+ }
+ // buscador de padres
+ if (parentFinder != null) {
+ logger.info("[ZigbeeDriver] Stopping parentFinder maintenance task");
+ parentFinder.stop();
+ logger.info("[ZigbeeDriver] parentFinder stopped");
+ }
+ // configurador de registros
+ if (registerWriter != null) {
+ logger.info("[ZigbeeDriver] Stopping registerWriter maintenance task");
+ registerWriter.stop();
+ logger.info("[ZigbeeDriver] registerWriter stopped");
+ }
+ // buscador de endpoints
+ if (devicesFinder != null) {
+ logger.info("[ZigbeeDriver] Stopping devicesFinder maintenance task");
+ devicesFinder.stop();
+ logger.info("[ZigbeeDriver] devicesFinder stopped");
+ }
+
+ // establecemos el estado a ready
+ setStatus(DriverStatus.Ready);
+ }
+ };
+ // lanzamos la tarea
+ Thread th = new Thread(target);
+ th.start();
+ }
+
+ @Override
+ public Gateway getGateway() {
+ return gateway;
+ }
+
+ // </editor-fold>
+
+ /**
+ * Comprueba que la cadena proporcionada es válida, y devuelve una cadena
+ * adecuada para utilizar con el gateway de Telegesis
+ * @param hex4String cadena a comprobar
+ * @return cadena a utilizar o null si no es válida
+ */
+ private String checkHex4String(String hex4String) {
+ logger.trace("Driver305::checkHex4String(hex4String=" + hex4String + ")");
+ // comprobamos que es una cadena hexadecimal
+ String testHex4String = hex4String.toUpperCase().replace("[^0123456789ABCDEF]", "");
+ if (!testHex4String.equals(hex4String.toUpperCase())) {
+ return null;
+ }
+
+ // comprobamos longitud
+ if (testHex4String.length() != 4) {
+ return null;
+ }
+
+ // devolvemos el valor formateado
+ return testHex4String;
+ }
+
+ /**
+ * Comprueba que el canal proporcionado es válido, y devuelve una cadena
+ * adecuada para utilizar con el gateway de Telegesis
+ * @param channel Canal a comprobar
+ * @return Channel mask a utilizar o null si no es válido
+ */
+ private String checkChannel(int channel) {
+ logger.trace("Driver305::checkChannel(channel=" + channel + ")");
+ if ((channel < 11) || (channel > 26)) {
+ return null;
+ }
+ int channelMask = (1 << (channel - 11)); // desplazamos el 1 tantas veces como el número de canal
+ String strChannelMask = String.format("%04X", channelMask);
+
+ // devolvemos el valor formateado
+ return strChannelMask;
+ }
+
+ /**
+ * Comprueba que la LinkKey proporcionada es válida, y devuelve una cadena
+ * adecuada para utilizar con el gateway de Telegesis
+ * @param linkKey Link Key a comprobar
+ * @return linkKey a utilizar o null si no es válida
+ */
+ private String checkLinkKey(String linkKey) {
+ logger.trace("Driver305::checkLinkKey(linkKey=" + linkKey + ")");
+ // comprobamos la clave proporcionada
+ String testLinkKey = "";
+ if (linkKey.length() == 32) {
+ // se debe tratar de una clave hexadecimal, comprobamos caracteres no validos
+ testLinkKey = linkKey.toUpperCase().replace("[^0123456789ABCDEF]", "0");
+ if (!testLinkKey.equals(linkKey.toUpperCase())) {
+ return null;
+ }
+ } else { // consideramos una clave textual
+ if (linkKey.length() > 16) { // clave textual: truncada
+ logger.warn("[ZigbeeDriver] provided link key (" + linkKey + ") is too long, truncating to 16 first characters");
+ }
+ byte[] strCodes = linkKey.getBytes(Charset.forName("ISO-8859-1"));
+ // no modificamos la cadena, porque sólo recorreremos 16 bytes
+ for (int i = 0; i < 16; i++) {
+ String hexCode;
+ if (i <= strCodes.length) {
+ hexCode = String.format("%02X", strCodes[i]);
+ } else {
+ hexCode = "00";
+ }
+ // acumulamos la cadena
+ testLinkKey = testLinkKey + hexCode;
+ }
+ }
+ // devolvemos el valor formateado
+ return testLinkKey;
+ }
+
+ // </editor-fold>
+ //
+
+ // <editor-fold defaultstate="collapsed" desc="GATEWAY LISTENER">
+ @Override
+ public void acknowledgement(short seqNumber, boolean wasACK, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void routeRecordReceived(String EUI64Addr, int numHops, String[] route, Gateway gtwy) {
+ logger.trace("Driver305::routeRecordReceived(EUI64Addr=" + EUI64Addr + ", numHops=" + numHops + ", route=" + route + ", gtwy=" + gtwy + ")");
+
+ logger.info(String.format("[ZigbeeDriver] Route record received for address %s", EUI64Addr));
+
+ // recuperamos el nodo
+ ZigbeeNode node = getNode(EUI64Addr);
+ // si el nodo no existe lo creamos
+ if (node == null) {
+ node = createNode(new EUI64Address(EUI64Addr));
+ }
+
+ // recuperamos los nodos de la ruta
+ ZigbeeNode[] nodeRoute = new ZigbeeNode[route.length];
+ for (int i = 0; i < route.length; i++) {
+ String nodeId = route[i];
+ ZigbeeNode routeNode = getNode(nodeId);
+ // si el nodo no existe NO solicitamos la creación
+// if (routeNode == null) {
+// routeNode = createNode(new NetworkAddress(nodeId));
+// }
+ nodeRoute[i] = routeNode;
+ }
+
+ // guardamos la ruta del nodo
+ ((ZigbeeNodeImpl) node).setRoute(nodeRoute);
+
+ }
+
+ @Override
+ public void broadcastMessageReceived(String EUI64Addr, byte[] message, Gateway gtwy) {
+ logger.trace("Driver305::broadcastMessageReceived(EUI64Addr=" + EUI64Addr + ", message=" + message + ", gtwy=" + gtwy + ")");
+
+ logger.info(String.format("[ZigbeeDriver] Received broadcast message from address %s (%d num bytes)", EUI64Addr, message.length));
+
+ // recuperamos el nodo
+ ZigbeeNode node = getNode(EUI64Addr);
+ // si el nodo no está registrado, lo creamos
+ if (node == null) {
+ node = createNode(new EUI64Address(EUI64Addr));
+ }
+
+ // notificamos al nodo la recepción del mensaje
+ ((ZigbeeNodeImpl) node).receiveMessage(message);
+
+ }
+
+ @Override
+ public void messageReceived(String EUI64Addr, byte[] message, String type, Gateway gtwy) {
+ logger.trace("Driver305::messageReceived(EUI64Addr=" + EUI64Addr + ", message=" + message + ", type=" + type + ", gtwy=" + gtwy + ")");
+
+ logger.info(String.format("[ZigbeeDriver] Received message from address %s (%d num bytes)", EUI64Addr, message.length));
+ // recuperamos el nodo
+ ZigbeeNode node = getNode(EUI64Addr);
+
+ // si el nodo no está registrado, lo creamos
+ if (node == null) {
+ node = createNode(new EUI64Address(EUI64Addr));
+ }
+ // notificamos al nodo la recepción del mensaje
+ ((ZigbeeNodeImpl) node).receiveMessage(message);
+
+ }
+
+ @Override
+ public void endpointMessageReceived(String EUI64Addr, String nodeID, short sourceEP, short destEP, String profileID, String clusterID, byte[] payload, Gateway gtwy) {
+ logger.trace("Driver305::endpointMessageReceived(EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", sourceEP=" + sourceEP + ", destEP=" + destEP + ", profileID=" + profileID + ", payload=" + payload + ", gtwy=" + gtwy + ")");
+
+ logger.info(String.format("[ZigbeeDriver] Received End point message from address %s (%d num bytes)", EUI64Addr, payload.length));
+
+ // recuperamos el nodo
+ ZigbeeNode node = getNode(EUI64Addr);
+ // si el nodo no existe lo creamos
+ if (node == null) {
+ node = createNode(new EUI64Address(EUI64Addr));
+ }
+
+ // recuperamos el device
+ ZigbeeDevice device = node.getZigbeeDevice(sourceEP);
+ // si no existe lo creamos
+ if (device == null) {
+ device = createDevice(node, sourceEP);
+ }
+
+ // notificamos al device la recepción del mensaje
+ ((ZigbeeDeviceImpl) device).receiveMessage(profileID, clusterID, payload);
+
+ }
+
+ @Override
+ public void nodeAnnounce(ZigbeeDeviceType type, String EUI64Addr, String nodeID, int RSSI, short LQI, Gateway gtwy) {
+ logger.trace("Driver305::nodeAnnounce(type=" + type + ", EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", RSSI=" + RSSI + ", LQI=" + LQI + ", gtwy=" + gtwy + ")");
+
+ logger.info(String.format("[ZigbeeDriver] Node announce (type: %s) from address %s, nodeID: %s (RSSI: %d, LQI: %02X)", type, EUI64Addr, nodeID, RSSI, LQI));
+
+ // recuperamos el nodo
+ ZigbeeNode node = getNode(EUI64Addr);
+ // obtenemos el tipo correspondiente al nodo
+ ZigbeeNodeType ndType = ZigbeeNodeType.fromZigbeeDeviceType(type);
+ // si no existe, lo creamos
+ if (node == null) {
+ node = createNode(new EUI64Address(EUI64Addr), new NetworkAddress(nodeID), ndType);
+ }
+
+ // actualizamos tipo de nodo
+ ((ZigbeeNodeImpl) node).setType(ndType);
+
+ // actualizamos RSSI
+ ((ZigbeeNodeImpl) node).setRSSI(RSSI);
+
+ // actualizamos LQI
+ ((ZigbeeNodeImpl) node).setLQI(LQI);
+
+ // actualizamos el coordinador de la red (si fuera el caso)
+ checkSetCoordinator(node);
+
+ // actualizamos la dirección de red
+ updateNetworkAddress(node, nodeID);
+
+ }
+
+ @Override
+ public void newNode(String EUI64Addr, String nodeID, String parentID, Gateway gtwy) {
+ logger.trace("Driver305::newNode(EUI64Addr=" + EUI64Addr + ", nodeID=" + nodeID + ", parentID=" + parentID + ", gtwy=" + gtwy + ")");
+
+ // loggeamos el mensaje
+ logger.info(String.format("[ZigbeeDriver] New node %s is attempting to join network with nodeId=%s at parentId=%s", EUI64Addr, nodeID, parentID));
+
+ // comprobamos si existiera el nodo para actualizar el padre
+ ZigbeeNode node = getNode(EUI64Addr);
+ // si no existe, abandonamos, no creamos el nodo
+ if (node == null) {
+ return;
+ }
+
+ // actualizamos la dirección de red
+ updateNetworkAddress(node, nodeID);
+
+ // recuperamos el padre
+ ZigbeeNode parent = getNode(parentID);
+ // si no existe, abandonamos
+ if (parent == null) {
+ return;
+ }
+ // actualizamos el padre
+ ((ZigbeeNodeImpl) node).setParent(parent);
+
+
+ }
+
+ @Override
+ public void leftPAN(Gateway gtwy) {
+ logger.trace("Driver305::leftPAN()");
+ // establecemos abandono de red
+ setNetworkLeft();
+ }
+
+ @Override
+ public void joinedPan(int channel, String PID, String EPID, Gateway gtwy) {
+ logger.trace("Driver305::joinedPAN(channel=" + channel + ", PID=" + PID + ", EPID=" + EPID + ", gtwy=" + gtwy + ")");
+ // establecemos incorporación a la red
+ setNetworkJoined(channel, PID, EPID);
+ }
+
+ @Override
+ public void registerWrited(String nodeID, String EUI64Addr, short errorCode, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void registerReaded(String nodeID, String EUI64Addr, short register, short errorCode, String data, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void addrResponse(short errorCode, String nodeID, String EUI64Addr, Gateway gtwy) {
+ logger.trace("Driver305::addrResponse(errorCode=" + errorCode + ", nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + ", gtwy=" + gtwy + ")");
+
+ // comprobamos errorCode
+ if (errorCode != 0) {
+ // abandonamos
+ return;
+ }
+
+ // recuperamos el nodo
+ ZigbeeNode node = getNode(EUI64Addr);
+ // si no existe, lo creamos
+ if (node == null) {
+ node = createNode(new EUI64Address(EUI64Addr), new NetworkAddress(nodeID));
+ }
+ // actualizamos la dirección de red
+ updateNetworkAddress(node, nodeID);
+
+ }
+
+ @Override
+ public void neighbourTableResponse(String nodeID, short errorCode, int tableLength, NeighbourTableEntry[] table, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void nodeDescriptorResponse(String nodeID, short errorCode, Map descriptor, Gateway gtwy) {
+ logger.trace("Driver305::nodeDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", descriptor=" + descriptor + ", gtwy=" + gtwy + ")");
+ // TODO: convertir en función con GtwyLstnr, acumular en atributos del nodo
+ }
+
+ @Override
+ public void powerDescriptorResponse(String nodeID, short errorCode, String descriptor, Gateway gtwy) {
+ logger.trace("Driver305::powerDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", descriptor=" + descriptor + ", gtwy=" + gtwy + ")");
+ // TODO: convertir en función con GtwyLstnr, acumular en atributos del nodo
+ }
+
+ @Override
+ public void nodeActiveEPResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void nodeEndPointSimpleDescriptorResponse(String nodeID, short errorCode, short EP, String ProfileID, String DeviceID, String[] inClusterList, String[] outClusterList, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void nodeMatchingDescriptorResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ logger.trace("Driver305::nodeMatchingDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", EPList=" + EPList + ", gtwy=" + gtwy + ")");
+ // TODO: convertir en función con GtwyLstnr
+ }
+
+ @Override
+ public void unhandledCommand(String command, String[] parameters, Gateway gtwy) {
+ // ignoramos
+ }
+
+ @Override
+ public void unknownMessage(String message, Gateway gtwy) {
+ // ignoramos
+ }
+ // </editor-fold>
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/DriverFactory.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/DriverFactory.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/DriverFactory.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,48 @@
+/*
+ * 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.driver.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class DriverFactory {
+
+ /**
+ * Creates a driver operating the provided gateway, checking communication
+ * to determine right implementation
+ * @param gtwy Gateway to be used by the driver
+ * @return Driver or null if error or not supported Gateway
+ */
+ public static Driver createDriver(Gateway gtwy) {
+
+ // comprobamos para todas las implementaciones soportadas
+ Driver testDrvr;
+
+ // comprobamos version R305X
+ testDrvr = new Driver305(gtwy);
+ if (testDrvr.init()){
+ return testDrvr;
+ }
+
+ // no es un driver valido
+ return null;
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeDeviceImpl.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeDeviceImpl.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeDeviceImpl.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,378 @@
+/*
+ * 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.driver.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDeviceListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class ZigbeeDeviceImpl implements ZigbeeDevice {
+
+ short endPoint;
+ String profileID;
+ String deviceID;
+ ArrayList<String> inClusterList = new ArrayList<String>();
+ ArrayList<String> outClusterList = new ArrayList<String>();
+ final ZigbeeNode node;
+ final Driver driver;
+ private DeviceStatus status = DeviceStatus.Unknown;
+ // Relaciones entre nodos
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public ZigbeeDeviceImpl(Driver driver, ZigbeeNode node, short endPoint) {
+ logger.trace("ZigbeeDeviceImpl::ZigbeeDeviceImpl(driver=" + driver + ", node=" + node + ", endPoint=" + endPoint + ")");
+ this.driver = driver;
+ this.node = node;
+ this.endPoint = endPoint;
+ }
+
+ @Override
+ public boolean discover() {
+ logger.trace("ZigbeeDeviceImpl::discover()");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(DeviceStatus.Discovering);
+
+ // lanzamos la consulta del descriptor del end point
+ boolean requestResult = driver.updateEndPointDescriptor(this);
+
+ // actualizamos el estado
+ setStatus(DeviceStatus.Ready);
+
+ // comprobamos error
+ if (requestResult) {
+ resetErrorCount();
+ } else {
+ addErrorCount();
+ }
+
+ // devolvemos el resultado
+ return requestResult;
+
+ }
+
+ }
+
+ /**
+ * Lanza un proceso de recovery en el device
+ * @return True si finaliza el proceso correctamente, false en otro caso
+ */
+ @Override
+ public boolean recover() {
+ logger.trace("ZigbeeDeviceImpl::recover()");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(DeviceStatus.Recovering);
+
+ //TODO: definir proceso de recovery en el device, de momento restablecemos la cuenta de errores
+
+ boolean recovered = true;
+
+ // comprobamos resultado del recovery
+ if (recovered) {
+ resetErrorCount(); // esto actualiza el estado
+ } else {
+ addErrorCount(); // esto actualiza el estado
+ }
+
+ // devolvemos resultado
+ return recovered;
+
+ }
+
+ }
+
+ /**
+ * Lanza un proceso de descubrimiento asÃncrono del device
+ */
+ public void launchDiscovery() {
+ logger.trace("ZigbeeDeviceImpl::launchDiscovery()");
+ final ZigbeeDeviceImpl device = this;
+ // creamos tarea a ejecutar
+ Runnable target = new Runnable() {
+
+ @Override
+ public void run() {
+ // lanzamos el proceso de descubrimiento
+ device.discover();
+ }
+ };
+ // creamos el hilo y lo arracamos
+ Thread th = new Thread(target, "Discovery task for device " + this);
+ th.start();
+ }
+
+ /**
+ * Actualiza el status, y lanza la notificación correspondiente
+ * @param status
+ */
+ public void setStatus(DeviceStatus status) {
+ logger.trace(String.format("ZigbeeDeviceImpl::setStatus(status=%s)", status));
+ // guardamos el estado anterior y lo actualizamos
+ DeviceStatus oldStatus = this.status;
+ this.status = status;
+ // comprobamos para notificar cambio de estado
+ if (oldStatus != status) {
+ fireStatusChanged(status, oldStatus);
+ }
+ }
+
+ public void setProfileID(String profileID) {
+ logger.trace(String.format("ZigbeeDeviceImpl::setProfileID(profileID=%s)", profileID));
+ this.profileID = profileID;
+ }
+
+ public void setDeviceID(String deviceID) {
+ logger.trace(String.format("ZigbeeDeviceImpl::setDeviceID(deviceID=%s)", deviceID));
+ this.deviceID = deviceID;
+ }
+
+ public void setInClusterList(String[] inCluster) {
+ if (inCluster == null) {
+ logger.trace(String.format("ZigbeeDeviceImpl::setInClusterList(inCluster=%s)", inCluster));
+ } else {
+ logger.trace(String.format("ZigbeeDeviceImpl::setInClusterList(inCluster.length=%d)", inCluster.length));
+ }
+ inClusterList.clear();
+ if (inCluster != null) {
+ inClusterList.addAll(Arrays.asList(inCluster));
+ }
+ }
+
+ public void setOutClusterList(String[] outCluster) {
+ if (outCluster == null) {
+ logger.trace(String.format("ZigbeeDeviceImpl::setInClusterList(inCluster=%s)", outCluster));
+ } else {
+ logger.trace(String.format("ZigbeeDeviceImpl::setInClusterList(inCluster.length=%d)", outCluster.length));
+ }
+ outClusterList.clear();
+ if (outCluster != null) {
+ outClusterList.addAll(Arrays.asList(outCluster));
+ }
+ }
+
+ @Override
+ public short getEndPoint() {
+ return endPoint;
+ }
+
+ @Override
+ public String getProfileId() {
+ return profileID;
+ }
+
+ @Override
+ public String getDeviceId() {
+ return deviceID;
+ }
+
+ @Override
+ public String[] getInClusterList() {
+ return inClusterList.toArray(new String[0]);
+ }
+
+ @Override
+ public String[] getOutClusterList() {
+ return outClusterList.toArray(new String[0]);
+ }
+
+ @Override
+ public ZigbeeNode getZigbeeNode() {
+ return node;
+ }
+
+ @Override
+ public DeviceStatus getStatus() {
+ return status;
+ }
+
+ @Override
+ public boolean sendMessage(String profileID, String clusterID, byte[] message) {
+ logger.trace(String.format("ZigbeeDeviceImpl::sendMessage(profileID=%s, clusterID=%s, message=%s)", profileID, clusterID, message));
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(DeviceStatus.Busy);
+
+ // enviamos el mensaje
+ boolean sendResult = driver.sendMessage(this, profileID, clusterID, message);
+
+ // actualizamos el estado
+ setStatus(DeviceStatus.Ready);
+
+ // comprobamos error
+ if (sendResult) {
+ resetErrorCount();
+ } else {
+ addErrorCount();
+ }
+
+ // devolvemos resultado
+ return sendResult;
+
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%02X@%s]", endPoint, node.getEUI64Addr().toFormattedString());
+ }
+
+ /**
+ * Función para procesar la recepción de un mensaje dirigido al EndPoint
+ * @param profileID
+ * @param clusterID
+ * @param message
+ */
+ public void receiveMessage(String profileID, String clusterID, byte[] message) {
+ logger.trace("ZigbeeDeviceImpl::receiveMessage(message=" + message + ")");
+ // notificamos a los listeners la recepción del mensaje
+ fireMessageReceived(profileID, clusterID, message);
+
+ }
+ // <editor-fold defaultstate="collapsed" desc="GESTION LISTENERS">
+ final ArrayList<ZigbeeDeviceListener> listeners = new ArrayList<ZigbeeDeviceListener>();
+ final HashMap<ZigbeeDeviceListener, Executor> executors = new HashMap<ZigbeeDeviceListener, Executor>();
+
+ @Override
+ public void registerListener(ZigbeeDeviceListener lstnr) {
+ logger.trace(String.format("ZigbeeDeviceImpl::registerListener(lstnr=%s)", lstnr));
+ synchronized (listeners) {
+ if (listeners.add(lstnr)) {
+ Executor ex = Executors.newSingleThreadExecutor();
+ executors.put(lstnr, ex);
+ }
+ }
+ }
+
+ @Override
+ public void unregisterListener(ZigbeeDeviceListener lstnr) {
+ logger.trace(String.format("ZigbeeDeviceImpl::unregisterListener(lstnr=%s)", lstnr));
+ synchronized (listeners) {
+ if (listeners.remove(lstnr)) {
+ executors.remove(lstnr);
+ }
+ }
+ }
+
+ /**
+ * Notifies about message recieved by a ZigbeeDevice,
+ * @param message Message received
+ */
+ protected void fireMessageReceived(final String profileID, final String clusterID, final byte[] message) {
+ logger.trace("ZigbeeDeviceImpl::fireMessageReceived(profileID=" + profileID + ", clusterID=" + clusterID + ",message=" + message + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final ZigbeeDevice device = this;
+ while (it.hasNext()) {
+ final ZigbeeDeviceListener lstnr = (ZigbeeDeviceListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.messageReceived(profileID, clusterID, message, device);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+
+ /**
+ * Notifies about status changed on a ZigbeeDevice,
+ * @param status current status
+ * @param oldStatus previous status
+ */
+ protected void fireStatusChanged(final ZigbeeDevice.DeviceStatus status, final ZigbeeDevice.DeviceStatus oldStatus) {
+ logger.trace("ZigbeeDeviceImpl::fireStatusChanged(status=" + status + ", oldStatus=" + oldStatus + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final ZigbeeDevice device = this;
+ while (it.hasNext()) {
+ final ZigbeeDeviceListener lstnr = (ZigbeeDeviceListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.statusChanged(status, oldStatus, device);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ ex.execute(launcher);
+ }
+ }
+ }
+ // </editor-fold>
+ // <editor-fold defaultstate="collapsed" desc="GESTION ERRORES">
+ private int errorCount = 0;
+
+ /**
+ * Incrementa el número de errores del dispositivo
+ */
+ public void addErrorCount() {
+ logger.trace("ZigbeeDeviceImpl::addErrorCount()");
+ errorCount += 1;
+
+ //Si el número de errores supera el umbral de error, marcamos estado de error
+ if (errorCount > ((AbstractDriver) driver).CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1) {
+ setStatus(DeviceStatus.Error);
+ }
+ //NOTA: la gestion de los errores se realiza en una tarea de mantenimiento
+
+ }
+
+ /**
+ * Devuelve el numero de errores del dispositivo
+ * @return
+ */
+ public int getErrorCount() {
+ logger.trace("ZigbeeDeviceImpl::getErrorCount()");
+ return errorCount;
+ }
+
+ /**
+ * Restablece a cero el número de errores del dispositivo
+ */
+ public void resetErrorCount() {
+ logger.trace("ZigbeeDeviceImpl::resetErrorCount()");
+ errorCount = 0;
+ // restablecemos el estado
+ if (status == DeviceStatus.Error) {
+ setStatus(DeviceStatus.Ready);
+ }
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeNodeImpl.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeNodeImpl.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/ZigbeeNodeImpl.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,761 @@
+/*
+ * 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.driver.impl;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNodeListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.util.Register305;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.EUI64Address;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.NetworkAddress;
+import es.unizar.howlab.core.zigbee.telegesis.driver.util.ZigbeeNodeType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Alvaro
+ */
+public class ZigbeeNodeImpl implements ZigbeeNode {
+
+ private ZigbeeNodeType type;
+ private EUI64Address address;
+ private NetworkAddress nodeID;
+ private String regPassword = "password";
+ private NodeStatus status = NodeStatus.Unknown;
+ private int RSSI = 0;
+ private short LQI = 0;
+ // Relaciones entre nodos
+ private ZigbeeNode parent;
+ private ArrayList<ZigbeeNode> childrenList = new ArrayList<ZigbeeNode>();
+ private ArrayList<ZigbeeNode> neighbourList = new ArrayList<ZigbeeNode>();
+ private ArrayList<ZigbeeNode> route = new ArrayList<ZigbeeNode>();
+ // endPoints
+ private ArrayList<ZigbeeDevice> zigbeeDevices = new ArrayList<ZigbeeDevice>();
+ // valores para registros
+ HashMap<String, String> registers = new HashMap<String, String>();
+ final Driver driver;
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public ZigbeeNodeImpl(Driver driver) {
+ logger.trace("ZigbeeNodeImpl::ZigbeeNodeImpl(driver=" + driver + ")");
+ this.driver = driver;
+
+ // inicializamos la lista de registros
+ for (Register305 r : Register305.values()) {
+ registers.put(String.format("%02X", r.getAddress()), null);
+ }
+ }
+
+ /**
+ * Lanza una busqueda de EndPoints del Nodo
+ * @return True si finaliza el proceso correctamente, false en otro caso
+ */
+ @Override
+ public boolean discoverZigbeeDevices() {
+ logger.trace("ZigbeeNodeImpl::discoverZigbeeDevices()");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Discovering);
+
+ // lanzamos la consulta de endPoints del nodo
+ boolean requestResult = driver.updateActiveEndPoints(this);
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (requestResult) {
+ resetErrorCount();
+ } else {
+ //addErrorCount();
+ return false;
+ }
+
+ // devolvemos el resultado
+ return requestResult;
+
+ }
+
+ }
+
+ /**
+ * Lanza una busqueda de vecinos del Nodo.
+ * Nota: si el nodo es un RFD, no puede tener vecinos, por lo que no se
+ * lanza la busqueda, y en este caso se devuelve resultado OK
+ * @return True si finaliza el proceso correctamente, false en otro caso
+ */
+ @Override
+ public boolean discoverNeighbours() {
+ logger.trace("ZigbeeNodeImpl::discoverNeighbours()");
+
+ // comprobamos tipo de nodo
+ switch (this.type) {
+ case EndDevice:
+ case SleepyEndDevice:
+ case MobileEndDevice:
+ return true;
+ }
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Discovering);
+
+ // lanzamos la consulta de endPoints del nodo
+ boolean requestResult = driver.updateNeighbourTable(this);
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (requestResult) {
+ resetErrorCount();
+ } else {
+ //addErrorCount();
+ return false;
+ }
+
+ // devolvemos el resultado
+ return requestResult;
+
+ }
+
+ }
+
+ /**
+ * Lanza una busqueda del padre del nodo.
+ * @return True si finaliza el proceso correctamente, false en otro caso
+ */
+ @Override
+ public boolean discoverParent() {
+ logger.trace("ZigbeeNodeImpl::discoverParent()");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Discovering);
+
+ // lanzamos la consulta del padre
+ String parentEUI = readRegister(Register305.PARENT_EUI.getAddress());
+
+ boolean requestResult;
+ if (parentEUI == null) {
+ requestResult = false;
+ } else {
+ requestResult = true;
+ setParent(driver.getNode(parentEUI));
+ }
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (requestResult) {
+ resetErrorCount();
+ } else {
+ //addErrorCount();
+ }
+
+ // devolvemos el resultado
+ return requestResult;
+
+ }
+
+ }
+
+ /**
+ * Lanza un proceso de recovery en el nodo
+ * @return True si finaliza el proceso correctamente, false en otro caso
+ */
+ @Override
+ public boolean recover() {
+ logger.trace("ZigbeeNodeImpl::recover()");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Recovering);
+
+ //Buscamos la ruta al nodo
+ boolean recovered = driver.findRoute(this);
+
+ // comprobamos resultado del recovery
+ if (recovered) {
+ resetErrorCount(); // esto actualiza el estado
+ } else {
+ addErrorCount(); // esto actualiza el estado
+ }
+
+ // devolvemos resultado
+ return recovered;
+
+ }
+
+ }
+
+ /**
+ * Lanza un proceso de descubrimiento asÃncrono de los vecinos del nodo
+ */
+ public void launchNeighbourDiscovery() {
+ logger.trace("ZigbeeNodeImpl::launchNeighbourDiscovery()");
+ final ZigbeeNodeImpl node = this;
+ // creamos tarea a ejecutar
+ Runnable target = new Runnable() {
+
+ @Override
+ public void run() {
+ node.discoverNeighbours();
+ }
+ };
+ // creamos el hilo y lo arracamos
+ Thread th = new Thread(target, "Neighbour update for node " + node);
+ th.start();
+
+ }
+
+ /**
+ * Lanza un proceso de descubrimiento asÃncrono del nodo
+ */
+ public void launchDiscovery() {
+ logger.trace("ZigbeeNodeImpl::launchDiscovery()");
+ final ZigbeeNodeImpl node = this;
+ // creamos tarea a ejecutar
+ Runnable target = new Runnable() {
+
+ @Override
+ public void run() {
+ // lanzamos el proceso de descubrimiento
+ node.discoverZigbeeDevices();
+ }
+ };
+ // creamos el hilo y lo arracamos
+ Thread th = new Thread(target, "Discovery task for node " + this);
+ th.start();
+ }
+
+ /**
+ * Actualiza el status, y lanza la notificación correspondiente
+ * @param status
+ */
+ public void setStatus(NodeStatus status) {
+ logger.trace(String.format("ZigbeeNodeImpl::setStatus(status=%s)", status));
+ // guardamos el estado anterior y lo actualizamos
+ NodeStatus oldStatus = this.status;
+ this.status = status;
+ // comprobamos para notificar cambio de estado
+ if (oldStatus != status) {
+ fireStatusChanged(status, oldStatus);
+ }
+ }
+
+ public void setType(ZigbeeNodeType type) {
+ logger.trace(String.format("ZigbeeNodeImpl::setType(type=%s)", type));
+ this.type = type;
+ }
+
+ public void setAddress(EUI64Address address) {
+ logger.trace(String.format("ZigbeeNodeImpl::setAddress(address=%s)", address));
+ this.address = address;
+ }
+
+ public void setNodeID(NetworkAddress nodeID) {
+ logger.trace(String.format("ZigbeeNodeImpl::setNodeID(nodeID=%s)", nodeID));
+ this.nodeID = nodeID;
+ }
+
+ public void setParent(ZigbeeNode parent) {
+ logger.trace(String.format("ZigbeeNodeImpl::setParent(parent=%s)", parent));
+ this.parent = parent;
+ }
+
+ public void setRSSI(int RSSI) {
+ logger.trace(String.format("ZigbeeNodeImpl::setRSSI(RSSI=%s)", RSSI));
+ this.RSSI = RSSI;
+ }
+
+ public void setLQI(short LQI){
+ logger.trace(String.format("ZigbeeNodeImpl::setLQI(LQI=%s)", LQI));
+ this.LQI = LQI;
+ }
+
+ /**
+ * Añade un nodo a la lista de vecinos o hijos según sea FFD o RFD
+ * @param node
+ */
+ public void addNode(ZigbeeNode node) {
+ logger.trace(String.format("ZigbeeNodeImpl::addNode(node=%s)", node));
+ // comprobamos el tipo de nodo
+ switch (node.getType()) {
+ case Coordinator:
+ case Router:
+ addNeighbour(node);
+ break;
+ default:
+ addChild(node);
+ break;
+ }
+
+ }
+
+ /**
+ * Elimina un nodo de la lista de vecinos o hijos según sea FFD o RFD
+ * @param node
+ */
+ public void removeNode(ZigbeeNode node) {
+ logger.trace(String.format("ZigbeeNodeImpl::removeNode(node=%s)", node));
+ // comprobamos el tipo de nodo
+ switch (node.getType()) {
+ case Coordinator:
+ case Router:
+ ((ZigbeeNodeImpl) node).removeNeighbour(node);
+ break;
+ default:
+ ((ZigbeeNodeImpl) node).removeChild(node);
+ break;
+ }
+
+ }
+
+ public void setNeighbours(ZigbeeNode[] neighbours) {
+ logger.trace(String.format("ZigbeeNodeImpl::setNeighbours(neighbours=%s)", neighbours));
+ this.neighbourList.clear();
+ this.neighbourList.addAll(Arrays.asList(neighbours));
+ }
+
+ public void addNeighbour(ZigbeeNode neighbour) {
+ logger.trace(String.format("ZigbeeNodeImpl::addNeighbour(neighbour=%s)", neighbour));
+ if (!neighbourList.contains(neighbour)) {
+ neighbourList.add(neighbour);
+ }
+ }
+
+ public void removeNeighbour(ZigbeeNode neighbour) {
+ logger.trace(String.format("ZigbeeNodeImpl::removeNeighbour(neighbour=%s)", neighbour));
+ if (neighbourList.contains(neighbour)) {
+ neighbourList.remove(neighbour);
+ }
+ }
+
+ public void setChildren(ZigbeeNode[] children) {
+ logger.trace(String.format("ZigbeeNodeImpl::setChildren(children=%s)", children));
+ this.childrenList.clear();
+ this.childrenList.addAll(Arrays.asList(children));
+ }
+
+ public void addChild(ZigbeeNode child) {
+ logger.trace(String.format("ZigbeeNodeImpl::addChild(child=%s)", child));
+ if (!childrenList.contains(child)) {
+ childrenList.add(child);
+ }
+ }
+
+ public void removeChild(ZigbeeNode child) {
+ logger.trace(String.format("ZigbeeNodeImpl::removeChild(child=%s)", child));
+ if (childrenList.contains(child)) {
+ childrenList.remove(child);
+ }
+ }
+
+ public void setRoute(ZigbeeNode[] route) {
+ logger.trace(String.format("ZigbeeNodeImpl::setRoute(route=%s)", route));
+ this.route.clear();
+ this.route.addAll(Arrays.asList(route));
+ }
+
+ public void setZigbeeDevices(ZigbeeDevice[] devices) {
+ logger.trace(String.format("ZigbeeNodeImpl::setZigbeeDevices(devices=%s)", devices));
+ this.zigbeeDevices.clear();
+ this.zigbeeDevices.addAll(Arrays.asList(devices));
+ }
+
+ public void addZigbeeDevice(ZigbeeDevice device) {
+ logger.trace(String.format("ZigbeeNodeImpl::addZigbeeDevice(device=%s)", device));
+ this.zigbeeDevices.add(device);
+ }
+
+ public void removeZigbeeDevice(ZigbeeDevice device) {
+ logger.trace(String.format("ZigbeeNodeImpl::removeZigbeeDevice(device=%s)", device));
+ this.zigbeeDevices.remove(device);
+ }
+
+ /**
+ * Establece la contraseña de escritura de registros
+ * @param newPassword
+ */
+ public void setRegisterPassword(String newPassword){
+ regPassword = newPassword;
+ }
+
+ /**
+ * Actualiza la contraseña de escritura de los registros en el nodo
+ * @param newPassword
+ * @return
+ */
+ public boolean updateRegisterPassword(String newPassword){
+ logger.trace("ZigbeeNodeImpl::updateRegisterPassword(newPassword=" + newPassword + ")");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Busy);
+
+ short regAddress = Register305.PASSWORD.getAddress();
+
+ // escribimos el registro
+ boolean writeResult = driver.writeRegister(this,regAddress, newPassword);
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (writeResult) {
+ // guardamos el valor del registro
+ registers.put(String.format("%02X", regAddress), newPassword);
+ regPassword = newPassword;
+ resetErrorCount();
+ } else {
+ addErrorCount();
+ }
+
+ // devolvemos resultado
+ return writeResult;
+
+ }
+
+ }
+
+ public String getRegisterPassword(){
+ return regPassword;
+ }
+
+ @Override
+ public NodeStatus getStatus() {
+ return status;
+ }
+
+ @Override
+ public ZigbeeNodeType getType() {
+ return type;
+ }
+
+ @Override
+ public EUI64Address getEUI64Addr() {
+ return address;
+ }
+
+ @Override
+ public int getRSSI() {
+ return RSSI;
+ }
+
+ @Override
+ public short getLQI() {
+ return LQI;
+ }
+
+ @Override
+ public NetworkAddress getNodeID() {
+ return nodeID;
+ }
+
+ @Override
+ public ZigbeeDevice[] getZigbeeDevices() {
+ logger.trace(String.format("ZigbeeNodeImpl::getZigbeeDevices()"));
+ return zigbeeDevices.toArray(new ZigbeeDevice[0]);
+ }
+
+ @Override
+ public ZigbeeDevice getZigbeeDevice(short endPoint) {
+ logger.trace(String.format("ZigbeeNodeImpl::getZigbeeDevice(endPoint=%s)", endPoint));
+ for (int i = 0; i < zigbeeDevices.size(); i++) {
+ ZigbeeDevice ep = zigbeeDevices.get(i);
+ if (ep.getEndPoint() == endPoint) {
+ return ep;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ZigbeeNode[] getNeighbours() {
+ return neighbourList.toArray(new ZigbeeNode[0]);
+ }
+
+ @Override
+ public ZigbeeNode getParent() {
+ return parent;
+ }
+
+ @Override
+ public ZigbeeNode[] getChildren() {
+ ZigbeeNode[] nodes = new ZigbeeNode[childrenList.size()];
+ return childrenList.toArray(nodes);
+ }
+
+ @Override
+ public ZigbeeNode[] getRoute() {
+ ZigbeeNode[] nodes = new ZigbeeNode[route.size()];
+ return route.toArray(nodes);
+ }
+
+ @Override
+ public boolean sendMessage(byte[] message) {
+ logger.trace("ZigbeeNodeImpl::sendMessage(message=" + message + ")");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Busy);
+
+ // enviamos el mensaje
+ boolean sendResult = driver.sendMessage(this, message);
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (sendResult) {
+ resetErrorCount();
+ } else {
+ addErrorCount();
+ }
+
+ // devolvemos resultado
+ return sendResult;
+
+ }
+
+ }
+
+ @Override
+ public String readRegister(short regAddress) {
+ logger.trace("ZigbeeNodeImpl::readRegister(regAddress=" + regAddress + ")");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Busy);
+
+ // Leemos el registro
+ String data = driver.readRegister(this, regAddress);
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (data != null) {
+ resetErrorCount();
+ // guardamos el valor del registro
+ registers.put(String.format("%02X", regAddress), data);
+ } else {
+ addErrorCount();
+ }
+
+ // devolvemos resultado
+ return data;
+
+ }
+
+ }
+
+ @Override
+ public String getRegister(short regAddress) {
+ logger.trace("ZigbeeNodeImpl::getRegister(regAddress=" + regAddress + ")");
+
+ // devolvemos el valor almacenado del registro
+ return registers.get(String.format("%02X", regAddress));
+
+ }
+
+ @Override
+ public HashMap<String, String> getRegisters() {
+ logger.trace("ZigbeeNodeImpl::getRegisters()");
+
+ // devolvemos una copia de la lista de registros
+ return (HashMap<String, String>) registers.clone();
+
+ }
+
+ @Override
+ public boolean writeRegister(short regAddress, String data) {
+ logger.trace("ZigbeeNodeImpl::writeRegister(regAddress=" + regAddress + ", data=" + data + ")");
+
+ synchronized (this) {
+ // actualizamos el estado
+ setStatus(NodeStatus.Busy);
+
+ // escribimos el registro
+ boolean writeResult = driver.writeRegister(this, regAddress, data);
+
+ // actualizamos el estado
+ setStatus(NodeStatus.Ready);
+
+ // comprobamos error
+ if (writeResult) {
+ // guardamos el valor del registro
+ registers.put(String.format("%02X", regAddress), data);
+ resetErrorCount();
+ } else {
+ addErrorCount();
+ }
+
+ // devolvemos resultado
+ return writeResult;
+
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ return "[" + address.toFormattedString() + "]";
+ }
+
+ /**
+ * Función para procesar la recepción de un mensaje dirigido al EndPoint
+ * @param message
+ */
+ public void receiveMessage(byte[] message) {
+ logger.trace("ZigbeeNodeImpl::receiveMessage(message=" + message + ")");
+ // notificamos a los listeners la recepción del mensaje
+ fireMessageReceived(message);
+
+ }
+ // <editor-fold defaultstate="collapsed" desc="GESTION LISTENERS">
+ final ArrayList<ZigbeeNodeListener> listeners = new ArrayList<ZigbeeNodeListener>();
+ final HashMap<ZigbeeNodeListener, Executor> executors = new HashMap<ZigbeeNodeListener, Executor>();
+
+ @Override
+ public void registerListener(ZigbeeNodeListener lstnr) {
+ logger.trace(String.format("ZigbeeNodeImpl::registerListener(lstnr=%s)", lstnr));
+ synchronized (listeners) {
+ if (listeners.add(lstnr)) {
+ Executor ex = Executors.newSingleThreadExecutor();
+ executors.put(lstnr, ex);
+ }
+ }
+ }
+
+ @Override
+ public void unregisterListener(ZigbeeNodeListener lstnr) {
+ logger.trace(String.format("ZigbeeNodeImpl::unregisterListener(lstnr=%s)", lstnr));
+ synchronized (listeners) {
+ if (listeners.remove(lstnr)) {
+ executors.remove(lstnr);
+ }
+ }
+ }
+
+ /**
+ * Notifies about message recieved by a ZigbeeNode,
+ * @param message Message received
+ */
+ protected void fireMessageReceived(final byte[] message) {
+ logger.trace("ZigbeeNodeImpl::fireMessageReceived(message=" + message + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final ZigbeeNode device = this;
+ while (it.hasNext()) {
+ final ZigbeeNodeListener lstnr = (ZigbeeNodeListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.messageReceived(message, device);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ if (ex!= null){
+ ex.execute(launcher);
+ }
+ }
+ }
+ }
+
+ /**
+ * Notifies about status changed on a ZigbeeNode,
+ * @param status current status
+ * @param oldStatus previous status
+ */
+ protected void fireStatusChanged(final ZigbeeNode.NodeStatus status, final ZigbeeNode.NodeStatus oldStatus) {
+ logger.trace("ZigbeeNodeImpl::fireStatusChanged(status=" + status + ", oldStatus=" + oldStatus + ")");
+ synchronized (listeners) {
+ // declaramos los parámetros como final para poder acceder desde la clase anónima
+ Iterator it = listeners.iterator();
+ final ZigbeeNode node = this;
+ while (it.hasNext()) {
+ final ZigbeeNodeListener lstnr = (ZigbeeNodeListener) it.next();
+ Runnable launcher = new Runnable() {
+
+ @Override
+ public void run() {
+ lstnr.statusChanged(status, oldStatus, node);
+ }
+ };
+ Executor ex = executors.get(lstnr);
+ if (ex!= null){
+ ex.execute(launcher);
+ }
+ }
+ }
+ }
+ // </editor-fold>
+ // <editor-fold defaultstate="collapsed" desc="GESTION ERRORES">
+ private int errorCount = 0;
+
+ /**
+ * Incrementa el número de errores del dispositivo
+ */
+ public void addErrorCount() {
+ logger.trace("ZigbeeNodeImpl::addErrorCount()");
+ errorCount += 1;
+
+ //Si el número de errores supera el umbral de error, marcamos estado de error
+ if (errorCount > ((AbstractDriver) driver).CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1) {
+ setStatus(NodeStatus.Error);
+ }
+ //NOTA: la gestion de los errores se realiza en una tarea de mantenimiento
+
+ }
+
+ /**
+ * Devuelve el numero de errores del dispositivo
+ * @return
+ */
+ public int getErrorCount() {
+ logger.trace("ZigbeeNodeImpl::getErrorCount()");
+ return errorCount;
+ }
+
+ /**
+ * Restablece a cero el número de errores del dispositivo
+ */
+ public void resetErrorCount() {
+ logger.trace("ZigbeeNodeImpl::resetErrorCount()");
+ errorCount = 0;
+ // restablecemos el estado
+ if (status == NodeStatus.Error) {
+ setStatus(NodeStatus.Ready);
+ }
+ }
+ // </editor-fold>
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/AbstractDriverMaintenanceTask.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/AbstractDriverMaintenanceTask.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/AbstractDriverMaintenanceTask.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,559 @@
+/*
+ * 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.driver.impl.maintenance;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver.DriverStatus;
+import es.unizar.howlab.core.zigbee.telegesis.driver.DriverListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Timer;
+import java.util.TimerTask;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+abstract public class AbstractDriverMaintenanceTask implements DriverListener {
+
+ Driver driver;
+ boolean enabled = true;
+ ArrayList startTargets = new ArrayList();
+ ArrayList busyTargets = new ArrayList();
+ ArrayList failedTargets = new ArrayList();
+ ArrayList idleTargets = new ArrayList();
+ private final String taskName;
+ // Logger
+ private Log logger = LogFactory.getLog(this.getClass().getName());
+ long frameDelay;
+ boolean maintenance;
+ long maintenanceTime;
+ boolean recover;
+ long recoveryTime;
+ boolean pauseOnNetworkLeft;
+ boolean wasRunning;
+
+ /**
+ * Constructor
+ * @param taskName Nombre para la tarea (a efectos de logging)
+ * @param maintenance Indica si se crea tarea de mantenimiento
+ * @param recover Indica si se crea tarea de recuperacion (reintentar)
+ * @param pauseOnNetworkLeft Indica si se pausa la tarea al desconectarse de la red
+ */
+ public AbstractDriverMaintenanceTask(String taskName, boolean maintenance, boolean recover, boolean pauseOnNetworkLeft) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask::AbstractDriverMaintenanceTask(taskName=%s, maintenance=%s, recover=%s, pauseOnNetworkLeft=%s)", taskName, maintenance, recover, pauseOnNetworkLeft));
+
+ this.taskName = taskName;
+ this.recover = recover;
+ this.maintenance = maintenance;
+ this.pauseOnNetworkLeft = pauseOnNetworkLeft;
+ }
+
+ /**
+ * Establece el periodo de separacion entre nodos para las operaciones
+ * @param frameDelay Tiempo de separacion, en segundos
+ */
+ public void setFrameDelay(long frameDelay) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::setFrameDelay(frameDelay=%d)", taskName, frameDelay));
+ this.frameDelay = frameDelay * 1000;
+ if (startingTask != null) {
+ startingTask.setTiming(0, this.frameDelay);
+ }
+ if (recoveryTask != null) {
+ recoveryTask.setTiming(this.recoveryTime, this.frameDelay);
+ }
+ if (maintenanceTask != null) {
+ maintenanceTask.setTiming(this.maintenanceTime, this.frameDelay);
+ }
+ }
+
+ /**
+ * Establece el periodo de mantenimiento de la operacion
+ * @param maintenanceTime Periodo de mantenimiento(en minutos)
+ */
+ public void setMaintenanceTime(long maintenanceTime) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::setMaintenanceTime(maintenanceTime=%d)", taskName, maintenanceTime));
+ this.maintenanceTime = maintenanceTime * 60 * 1000;
+ if (maintenanceTask != null) {
+ maintenanceTask.setTiming(this.maintenanceTime, this.frameDelay);
+ }
+ }
+
+ /**
+ * Establece el periodo de reintento para operaciones fallidas
+ * @param recoveryTime Periodo de reintento (en minutos)
+ */
+ public void setRecoveryTime(long recoveryTime) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::setRecoveryTime(recoveryTime=%d)", taskName, recoveryTime));
+ this.recoveryTime = recoveryTime * 60 * 1000;
+ if (recoveryTask != null) {
+ recoveryTask.setTiming(this.recoveryTime, this.frameDelay);
+ }
+ }
+
+ private class MaintenanceTask implements Runnable {
+
+ protected ArrayList targetList;
+ protected long period;
+ protected long frameDelay;
+ protected boolean running = false;
+ protected Thread currentThread = null;
+ protected HashMap<Object, Timer> timers = new HashMap<Object, Timer>();
+ protected final String mTaskName;
+
+ /**
+ * Constructor
+ * @param mTaskName nombre de la tarea (a efectos de logging)
+ * @param period Periodo de ejecución de la tarea
+ * @param frameDelay Periodo de separación entre nodos
+ * @param targetList Lista de nodos a mantener
+ */
+ public MaintenanceTask(String mTaskName, long period, long frameDelay, ArrayList targetList) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::MaintenanceTask.MaintenanceTask(mTaskName=%s, period=%d, frameDelay=%d, nodes=%s)", taskName, mTaskName, period, frameDelay, targetList));
+ this.mTaskName = mTaskName;
+ this.targetList = targetList;
+ this.period = period;
+ this.frameDelay = frameDelay;
+ }
+
+ public void setTiming(long period, long frameDelay) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::MaintenanceTask[%s].setTiming(period=%d, frameDelay=%d)", taskName, mTaskName, period, frameDelay));
+ this.period = period;
+ this.frameDelay = frameDelay;
+ if (running) {
+ // si estamos en ejecución, interrumpimos el hilo para aplicar configuracion
+ currentThread.interrupt();
+ }
+
+ }
+
+ /**
+ * Detiene la tarea
+ */
+ public void stop() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::MaintenanceTask[%s].stop()", taskName, mTaskName));
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Stopping maintenance task...", taskName, mTaskName));
+ running = false;
+ currentThread.interrupt();
+ // esperamoas a que termine el hilo
+ try {
+ currentThread.join();
+ } catch (InterruptedException ex) {
+ }
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Maintenance task stopped", taskName, mTaskName));
+ }
+
+ /**
+ * Inicia la tarea
+ */
+ public void start() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::MaintenanceTask[%s].start()", taskName, mTaskName));
+
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Starting maintenance task", taskName, mTaskName));
+ // Creamos el hilo
+ currentThread = new Thread(this, String.format("[Driver Maintenance Task: %s.%s] ", taskName, mTaskName));
+ currentThread.start();
+
+ }
+
+ public void cancelTaskForTarget(Object target) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::MaintenanceTask[%s].cancelTaskForTarget(target=%s)", taskName, mTaskName, target));
+
+
+ // recuperamos el timer
+ Timer tm = timers.get(target);
+ if (tm != null) {
+ logger.info(String.format("[Driver Maintenance Task: %s.%s] Cancel task for target %s", taskName, mTaskName, target));
+ tm.cancel();
+ }
+
+ }
+
+ @Override
+ public void run() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::MaintenanceTask[%s].run()", taskName, mTaskName));
+
+ // Inicializamos los tiempos
+ long wakeUpTime = System.currentTimeMillis() + period;
+
+ // guardamos el thread
+ if (currentThread == null) {
+ currentThread = Thread.currentThread();
+ }
+ // lanzamos un bucle infinito
+ running = true;
+ while (running) {
+ try {
+ // calculamos el siguiente instante de activacion y paramos el hilo
+ wakeUpTime = wakeUpTime + period;
+ long sleepTime = Math.max(wakeUpTime - System.currentTimeMillis(), 0);
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Task loop will resume on %d milliseconds", taskName, mTaskName, sleepTime));
+ Thread.sleep(sleepTime);
+ logger.info(String.format("[Driver Maintenance Task: %s.%s] Task loop resumed", taskName, mTaskName));
+
+ // si hay algún timer corriendo, lo paramos
+ for (Timer tm : timers.values()) {
+ tm.cancel();
+ }
+ // y borramos la lista
+ timers.clear();
+
+ // Recorremos todos los nodos
+ for (int i = 0; i < targetList.size(); i++) {
+ // recuperamos el nodo
+ Object target = targetList.get(i);
+ // programamos tarea
+ Timer tm = scheduleTask(target, frameDelay * i);
+ // guardamos el timer
+ timers.put(target, tm);
+ }
+
+ } catch (InterruptedException ex) {
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Task loop interrupted", taskName, mTaskName));
+ // no hacemos nada, sólo se interrumpe este hilo para pararlo
+ }
+ }
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Task loop finished", taskName, mTaskName));
+
+ // si hay algún timer corriendo, lo paramos
+ for (Timer tm : timers.values()) {
+ tm.cancel();
+ }
+ // y borramos la lista
+ timers.clear();
+ }
+ }
+
+ private class StartMaintenanceTask extends MaintenanceTask {
+
+ /**
+ * Constructor
+ * @param frameDelay Periodo de separación entre nodos
+ * @param targetList Lista de nodos a mantener
+ */
+ public StartMaintenanceTask(long frameDelay, ArrayList targetList) {
+ super("InitializacionTask", 1000, frameDelay, targetList);
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::StartMaintenanceTask.StartMaintenanceTask(frameDelay=%d, nodes=%s)", taskName, frameDelay, targetList));
+ }
+
+ @Override
+ public void run() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::StartMaintenanceTask.run()", taskName));
+
+ // guardamos el thread
+ if (currentThread == null) {
+ currentThread = Thread.currentThread();
+ }
+ // Recorremos todos los nodos
+ for (int i = 0; i < targetList.size(); i++) {
+ // recuperamos el nodo
+ Object target = targetList.get(i);
+ // programamos tarea
+ Timer tm = scheduleTask(target, frameDelay * i);
+ // guardamos el timer
+ timers.put(target, tm);
+ }
+
+ // solo vamos a ejecutar la tarea una vez, pero damos la posibilidad de
+ // cancelar tareas programadas si no se han ejecutado todavÃa, deteniendo
+ // este hilo hasta que terminen todas
+ try {
+ long wakeUpTime = System.currentTimeMillis() + frameDelay * targetList.size();
+ long sleepTime = Math.max(wakeUpTime - System.currentTimeMillis(), 0);
+ logger.debug(String.format("[Driver Maintenance Task: %s.%s] Wating for task ends for %d milliseconds", taskName, mTaskName, sleepTime));
+ Thread.sleep(sleepTime);
+ } catch (InterruptedException ex) {
+ logger.info(String.format("[Driver Maintenance Task: %s.%s] Task loop interrupted, cancelling pending tasks", taskName, mTaskName));
+ // si hay algún timer corriendo, lo paramos
+ for (Timer tm : timers.values()) {
+ tm.cancel();
+ }
+ // borramos la lista
+ timers.clear();
+ }
+
+ }
+ }
+ MaintenanceTask maintenanceTask;
+ MaintenanceTask recoveryTask;
+ StartMaintenanceTask startingTask;
+
+ public synchronized void start(Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::start(drv=%s)", taskName, drv));
+ // por si acaso ya tenÃamos un driver
+ if (driver != null) {
+ stop();
+ }
+ logger.info(String.format("[Driver Maintenance Task: %s] Starting maintenance task", taskName));
+ // guardamos el driver
+ driver = drv;
+
+ // nos registramos como Listener
+ driver.registerListener(this);
+
+ // marcamos ejecucion
+ wasRunning = true;
+
+ // iniciamos las tareas
+ resume();
+
+ }
+
+ private void resume() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::resume()", taskName));
+
+ // creamos las tareas
+ if (maintenance) {
+ maintenanceTask = new MaintenanceTask("MaintenanceTask", maintenanceTime, frameDelay, idleTargets);
+ maintenanceTask.start();
+ }
+ if (recover) {
+ recoveryTask = new MaintenanceTask("RecoveryTask", recoveryTime, frameDelay, failedTargets);
+ recoveryTask.start();
+ }
+
+ // arrancamos la tareas con los nodos y devices actuales
+ for (ZigbeeNode node : driver.getNodes()) {
+ startTargets.add(node);
+ startTargets.addAll(Arrays.asList(node.getZigbeeDevices()));
+ }
+ startingTask = new StartMaintenanceTask(frameDelay, startTargets);
+ startingTask.start();
+
+
+ }
+
+ private void pause() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::pause()", taskName));
+ // paramos las tareas
+ if (maintenance) {
+ maintenanceTask.stop();
+ }
+ if (recover) {
+ recoveryTask.stop();
+ }
+
+ }
+
+ public synchronized void stop() {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::stop()", taskName));
+
+ // comprobamos si tenÃamos un driver
+ if (driver != null) {
+ logger.info(String.format("[Driver Maintenance Task: %s] Stopping maintenance task", taskName));
+ // marcamos ejecucion
+ wasRunning = false;
+
+ // paramos las tareas
+ pause();
+
+ //desregistramos el driver
+ driver.unregisterListener(this);
+ driver = null;
+ }
+
+ }
+
+ /**
+ * Programa la tarea a ejecutar, retrasada en el tiempo indicado
+ * @param target objetivo de la operacion
+ * @param delay milisegundos de retardo
+ * @return el timer que lanzará la operacion
+ */
+ public synchronized Timer scheduleTask(final Object target, long delay) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::scheduleTask(target=%s, delay=%d)", taskName, target, delay));
+
+ // comprobamos que tenemos un driver para ejecutar la opreacion
+ if (driver == null) {
+ return null;
+ }
+
+ logger.info(String.format("[Driver Maintenance Task: %s] scheduling task execution for %s in %d milliseconds", taskName, target, delay));
+ // creamos una tarea para lanzar la busqueda
+ TimerTask tmTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ // comprobamos si el target está en la lista de target ocupados
+ if (busyTargets.contains(target)) {
+ logger.debug(String.format("[Driver Maintenance Task: %s] target %s already busy", taskName, target));
+ // abandonamos la tarea
+ return;
+ }
+
+ // añadimos el target a la lista de targets ocupados
+ busyTargets.add(target);
+
+ // lo eliminamos de las lista de targets que han finalizado
+ idleTargets.remove(target);
+ failedTargets.remove(target);
+
+ // lanzamos la operacion
+ logger.debug(String.format("[Driver Maintenance Task: %s] executing task for target %s", taskName, target));
+ boolean opRes = executeTask(target);
+ logger.debug(String.format("[Driver Maintenance Task: %s] executing task for target %s reports %s", taskName, target, (opRes ? "OK" : "FAIL")));
+
+ // Eliminamos el target de la lista de ocupados. Comprobamos si
+ // estaba en la lista, ya que si no estaba es porque el target ha
+ // sido eliminado, por lo que no hay que añadirlo al resto de
+ // listas
+ if (busyTargets.remove(target)) {
+ // comprobamos el resultado
+ if (opRes) {
+ idleTargets.add(target);
+ } else {
+ failedTargets.add(target);
+ }
+ }
+
+ }
+ };
+
+ // creamos un timer para la tarea
+ Timer tm = new Timer();
+ tm.schedule(tmTask, delay);
+ return tm;
+
+ }
+
+ abstract protected boolean executeTask(Object target);
+
+ @Override
+ public void newNode(ZigbeeNode node, Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::newNode(node=%s, drv=%s)", taskName, node, drv));
+ // comprobamos driver
+ if (!drv.equals(driver)) {
+ return;
+ }
+
+ // programamos la tarea en el nodo con delay=0
+ scheduleTask(node, 0);
+
+ }
+
+ @Override
+ public void newDevice(ZigbeeDevice device, Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::newDevice(device=%s, drv=%s)", taskName, device, drv));
+ // comprobamos driver
+ if (!drv.equals(driver)) {
+ return;
+ }
+
+ // programamos la tarea en el device con delay=0
+ scheduleTask(device, 0);
+
+ }
+
+ @Override
+ public void nodeLeft(ZigbeeNode node, Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::nodeLeft(node=%s, drv=%s)", taskName, node, drv));
+ // comprobamos driver
+ if (!drv.equals(driver)) {
+ return;
+ }
+
+ // eliminamos el nodo de la lista de objetivos
+ busyTargets.remove(node);
+ idleTargets.remove(node);
+ failedTargets.remove(node);
+
+ // cancelamos las tareas
+ if (recover) {
+ recoveryTask.cancelTaskForTarget(node);
+ }
+ if (maintenance) {
+ maintenanceTask.cancelTaskForTarget(node);
+ }
+
+ }
+
+ @Override
+ public void deviceLeft(ZigbeeDevice device, Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::deviceLeft(device=%s, drv=%s)", taskName, device, drv));
+ // comprobamos driver
+ if (!drv.equals(driver)) {
+ return;
+ }
+
+ // eliminamos el device de la lista de objetivos
+ busyTargets.remove(device);
+ idleTargets.remove(device);
+ failedTargets.remove(device);
+
+ // cancelamos las tareas
+ if (recover) {
+ recoveryTask.cancelTaskForTarget(device);
+ }
+ if (maintenance) {
+ maintenanceTask.cancelTaskForTarget(device);
+ }
+
+
+ }
+
+ @Override
+ public void joinNetwork(int channel, String PANID, String EPID, Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::joinNetwork(channel=%s, PANID=%s, EPID=%s, drv=%s)", taskName, channel, PANID, EPID, drv));
+
+ // comprobamos el driver
+ if (!drv.equals(driver)) {
+ return;
+ }
+
+ // comprobamos si hay que reanudar
+ if (wasRunning && pauseOnNetworkLeft) {
+ logger.info(String.format("[Driver Maintenance Task: %s] resuming task due to network join", taskName));
+ resume();
+ }
+ }
+
+ @Override
+ public void leftNetwork(Driver drv) {
+ logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::leftNetwork(drv=%s)", taskName, drv));
+ // comprobamos el driver
+ if (!drv.equals(driver)) {
+ return;
+ }
+
+ // comprobamos si hay que parar
+ if (pauseOnNetworkLeft && wasRunning) {
+ logger.info(String.format("[Driver Maintenance Task: %s] pausing task due to network left", taskName));
+ pause();
+ }
+
+ }
+
+ @Override
+ public void statusChanged(DriverStatus status, DriverStatus oldStatus, Driver drv) {
+// logger.trace(String.format("AbstractDriverMaintenanceTask[%s]::statusChanged(status=%s, oldStatus=%s, drv=%s)", status, oldStatus, drv));
+// // comprobamos el driver
+// if (!drv.equals(driver)) {
+// return;
+// }
+//
+// // Si abandonamos el estado Running ==> paramos
+// if (oldStatus == DriverStatus.Running) {
+// stop();
+// }
+ // Ignoramos esto para parar explÃcitamente las tareas, y tener control de cuando terminan
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ErrorCheckerDriverMaintenanceTask.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ErrorCheckerDriverMaintenanceTask.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ErrorCheckerDriverMaintenanceTask.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,93 @@
+/*
+ * 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.driver.impl.maintenance;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.AbstractDriver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeDeviceImpl;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeNodeImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class ErrorCheckerDriverMaintenanceTask extends AbstractDriverMaintenanceTask {
+
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public ErrorCheckerDriverMaintenanceTask() {
+ // creamos la clase padre
+ super("ErrorChecker", true, true, true);
+ logger.trace(String.format("ErrorCheckerDriverMaintenanceTask::ErrorCheckerDriverMaintenanceTask()"));
+
+ }
+
+ @Override
+ protected boolean executeTask(Object target) {
+ logger.trace(String.format("ErrorCheckerDriverMaintenanceTask::executeTask(target=%s)", target));
+
+ // recuperamos la configuracion de los umbrales de error
+ long errorThreshold1 = ((AbstractDriver) driver).CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_1;
+ long errorThreshold2 = ((AbstractDriver) driver).CONF_ZIGBEE_ERROR_LEVEL_THRESHOLD_2;
+
+ // comprobamos el tipo de dispositivo
+ if ((target instanceof ZigbeeNodeImpl)) {
+ // recuperamos el nodo
+ ZigbeeNodeImpl node = (ZigbeeNodeImpl) target;
+
+ // comprobamos el nivel de error
+ int errorLevel = node.getErrorCount();
+ if (errorLevel > errorThreshold2) {
+ // eliminamos el nodo
+ logger.info(String.format("[Driver Maintenance] Error level 2 (%d) on node %s. Removing node", errorLevel, target));
+ ((AbstractDriver) driver).removeNode(node);
+ return true; // esto hará que se elimine el nodo de las listas de mantenimiento
+ } else if (errorLevel > errorThreshold1) {
+ // lanzamos la operacion de recovery
+ logger.info(String.format("[Driver Maintenance] Error level 1 (%d) on node %s. Launching recovery", errorLevel, target));
+ return node.recover();
+
+ }
+
+ return true; // esto hará que marque la tarea como completada sin más
+ } else if ((target instanceof ZigbeeDeviceImpl)) {
+ // recuperamos el device
+ ZigbeeDeviceImpl device = (ZigbeeDeviceImpl) target;
+
+ // comprobamos el nivel de error
+ int errorLevel = device.getErrorCount();
+ if (errorLevel > errorThreshold2) {
+ // eliminamos el nodo
+ logger.info(String.format("[Driver Maintenance] Error level 2 (%d) on device %s. Removing device", errorLevel, target));
+ ((AbstractDriver) driver).removeDevice(device);
+ return true; // esto hará que se elimine el device de las listas de mantenimiento
+ } else if (errorLevel > errorThreshold1) {
+ // lanzamos la operacion de recovery
+ logger.info(String.format("[Driver Maintenance] Error level 1 (%d) on device %s. Launching recovery", errorLevel, target));
+ return device.recover();
+
+ }
+
+ return true; // esto hará que marque la tarea como completada sin más
+ } else {
+ return true; // esto hará que marque la tarea como completada sin más
+ }
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NeighbourFinderDriverMaintenanceTask.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NeighbourFinderDriverMaintenanceTask.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NeighbourFinderDriverMaintenanceTask.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,61 @@
+/*
+ * 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.driver.impl.maintenance;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeNodeImpl;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class NeighbourFinderDriverMaintenanceTask extends AbstractDriverMaintenanceTask {
+
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public NeighbourFinderDriverMaintenanceTask() {
+ // creamos la clase padre
+ super("NeighbourFinder", true, true, true);
+ logger.trace(String.format("NeighbourFinderDriverMaintenanceTask::NeighbourFinderDriverMaintenanceTask()"));
+
+ }
+
+ @Override
+ protected boolean executeTask(Object target) {
+ logger.trace(String.format("NeighbourFinderDriverMaintenanceTask::executeTask(target=%s)", target));
+
+ // comprobamos que se trata de un ZigbeeNode
+ if (!(target instanceof ZigbeeNodeImpl)) {
+ return true; // esto hará que marque la tarea como completada sin más
+ }
+
+
+ // comprobamos el tipo de nodo
+ ZigbeeNodeImpl node = (ZigbeeNodeImpl) target;
+ switch (node.getType()) {
+ case Unknown:
+ case Coordinator:
+ case Router:
+ logger.info(String.format("[Driver Maintenance] Discovering neighbours for node %s", node));
+ return node.discoverNeighbours();
+ default:
+ return true;
+ }
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NodeRegisterUpdaterDriverMaintenanceTask.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NodeRegisterUpdaterDriverMaintenanceTask.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/NodeRegisterUpdaterDriverMaintenanceTask.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,98 @@
+/*
+ * 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.driver.impl.maintenance;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.AbstractDriver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeNodeImpl;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class NodeRegisterUpdaterDriverMaintenanceTask extends AbstractDriverMaintenanceTask {
+
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+ // lista de reistros para reintentar
+ HashMap<ZigbeeNodeImpl, HashMap<String, String>> nodeRegisters = new HashMap<ZigbeeNodeImpl, HashMap<String, String>>();
+
+ public NodeRegisterUpdaterDriverMaintenanceTask() {
+ // creamos la clase padre
+ super("NodeRegisterUpdater", false, true, true);
+ logger.trace(String.format("NodeRegisterUpdaterDriverMaintenanceTask::NodeRegisterUpdaterDriverMaintenanceTask()"));
+
+ }
+
+ @Override
+ protected boolean executeTask(Object target) {
+ logger.trace(String.format("NodeRegisterUpdaterDriverMaintenanceTask::executeTask(target=%s)", target));
+
+ // comprobamos que se trata de un ZigbeeNode
+ if (!(target instanceof ZigbeeNodeImpl)) {
+ return true; // esto hará que marque la tarea como completada sin más
+ }
+
+ ZigbeeNodeImpl node = (ZigbeeNodeImpl) target;
+
+ logger.info(String.format("[Driver Maintenance] Writing registers for node %s", node));
+
+ // recuperamos la lista de registros
+ HashMap<String, String> registers = nodeRegisters.get(node);
+ if (registers == null) { // se trata de la primera llamada
+ // recuperamos la lista de registros del driver
+ ((AbstractDriver) driver).getNodeRegisterConfig(node.getEUI64Addr().toString());
+ }
+
+ // inicializamos la lista de registros pendientes
+ HashMap<String, String> pendingRegisters = new HashMap<String, String>();
+
+
+ // lanzamos la escritura de registros
+ Iterator it = registers.keySet().iterator();
+ while (it.hasNext()) {
+ // recuperamos el registro
+ String regStrAddr = (String) it.next();
+ String regValue = registers.get(regStrAddr);
+ short regAddr = (short) Integer.parseInt(regStrAddr, 16);
+ logger.info(String.format("[Driver Maintenance] Writing register %02X on node %s with value=%s", regAddr, node, regValue));
+ boolean writeResult = driver.writeRegister(node, regAddr, regValue);
+ // comprobamos resultado
+ if (!writeResult) {
+ logger.info(String.format("[Driver Maintenance] Error writing register %02X on node %s with value=%s. Will retry", regAddr, node, regValue));
+ // añadimos el registro para reintentarlo más tarde
+ pendingRegisters.put(regStrAddr, regValue);
+ }
+ }
+ // comprobamos si ha fallado algún registro
+ if (pendingRegisters.size() > 0) {
+ // guardamos los registros para escribirlos más tarde
+ nodeRegisters.put(node, pendingRegisters);
+
+ // devolvemos error
+ return false;
+ } else {
+ // devolvemos OK
+ return true;
+
+ }
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ParentFinderDriverMaintenanceTask.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ParentFinderDriverMaintenanceTask.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ParentFinderDriverMaintenanceTask.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,53 @@
+/*
+ * 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.driver.impl.maintenance;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeNodeImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class ParentFinderDriverMaintenanceTask extends AbstractDriverMaintenanceTask {
+
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public ParentFinderDriverMaintenanceTask() {
+ // creamos la clase padre
+ super("ParentFinder", true, true, true);
+ logger.trace(String.format("ParentFinderDriverMaintenanceTask::ParentFinderDriverMaintenanceTask()"));
+
+ }
+
+ @Override
+ protected boolean executeTask(Object target) {
+ logger.trace(String.format("ParentFinderDriverMaintenanceTask::executeTask(target=%s)", target));
+
+ // comprobamos que se trata de un ZigbeeNode
+ if (!(target instanceof ZigbeeNodeImpl)) {
+ return true; // esto hará que marque la tarea como completada sin más
+ }
+
+ // lanzamos la busqueda de padres
+ logger.info(String.format("[Driver Maintenance] Discovering parent for node %s", target));
+ return ((ZigbeeNodeImpl) target).discoverParent();
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ZigbeeDevicesFinderDriverMaintenanceTask.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ZigbeeDevicesFinderDriverMaintenanceTask.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/maintenance/ZigbeeDevicesFinderDriverMaintenanceTask.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,57 @@
+/*
+ * 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.driver.impl.maintenance;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeDeviceImpl;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeNodeImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class ZigbeeDevicesFinderDriverMaintenanceTask extends AbstractDriverMaintenanceTask {
+
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public ZigbeeDevicesFinderDriverMaintenanceTask() {
+ // creamos la clase padre
+ super("ZigbeeDevicesFinder", false, true, true);
+ logger.trace(String.format("ZigbeeDevicesFinderDriverMaintenanceTask::ZigbeeDevicesFinderDriverMaintenanceTask()"));
+
+ }
+
+ @Override
+ protected boolean executeTask(Object target) {
+ logger.trace(String.format("ZigbeeDevicesFinderDriverMaintenanceTask::executeTask(target=%s)", target));
+
+ // comprobamos que se trata de un ZigbeeNode
+ if ((target instanceof ZigbeeNodeImpl)) {
+ // lanzamos la busqueda de endpoints
+ logger.info(String.format("[Driver Maintenance] Discovering ZigbeeDevices for node %s", target));
+ return ((ZigbeeNodeImpl) target).discoverZigbeeDevices();
+ } else if ((target instanceof ZigbeeDeviceImpl)) {
+ // lanzamos la busqueda del descriptor del device
+ logger.info(String.format("[Driver Maintenance] Discovering ZigbeeDevice descriptor for device %s", target));
+ return ((ZigbeeDeviceImpl) target).discover();
+ } else {
+ return true;// esto hará que marque la tarea como completada sin más
+ }
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/Activator.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/Activator.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/Activator.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,64 @@
+/*
+ * 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.driver.impl.osgi;
+
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+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.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext bc = null;
+ private ServiceTracker st = null;
+ GatewayServiceTracker 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 tracker para el Gateway que se encargará de crear los drivers
+ stc = new GatewayServiceTracker();
+ st = new ServiceTracker(bc, Gateway.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 CNXServiceTracker para despublicar los gateways
+ stc.stop();
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/GatewayServiceTracker.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/GatewayServiceTracker.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/GatewayServiceTracker.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,139 @@
+/*
+ * 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.driver.impl.osgi;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.DriverFactory;
+import es.unizar.howlab.core.zigbee.telegesis.driver.osgi.Constants;
+import es.unizar.howlab.core.zigbee.telegesis.gateway.Gateway;
+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 HowLab, University of Zaragoza (alvaro)
+ */
+public class GatewayServiceTracker implements ServiceTrackerCustomizer {
+
+ HashMap<ServiceReference, ServiceRegistration> gatewaysUsed = new HashMap<ServiceReference, ServiceRegistration>();
+ HashMap<Driver, ZigbeePublisher> zpList = new HashMap<Driver, ZigbeePublisher>();
+
+ /**
+ * Ejecuta las operaciones de detencion del tracker
+ */
+ public void stop() {
+
+ // Despublicamos los drivers publicados
+ Iterator<ServiceReference> it = gatewaysUsed.keySet().iterator();
+ BundleContext bc = Activator.getBundleContext();
+ while (it.hasNext()) {
+ ServiceReference srefGtwy = it.next();
+ // recuperamos el driver
+ ServiceRegistration sregDriver = gatewaysUsed.get(srefGtwy);
+ Driver drv = (Driver) bc.getService(sregDriver.getReference());
+
+ // despublicamos los dispositivos asociados al driver
+ ZigbeePublisher zp = zpList.get(drv);
+ zp.stop();
+
+ // paramos el driver
+ drv.stop();
+
+ // desregistramos el driver
+ sregDriver.unregister();
+
+ // liberamos la referencia del gateway
+ bc.ungetService(srefGtwy);
+ }
+
+ }
+
+ @Override
+ public Object addingService(ServiceReference reference) {
+
+ BundleContext bc = Activator.getBundleContext();
+
+ // recuperamos el gateway
+ Gateway gtwy = (Gateway) bc.getService(reference);
+
+ // intentamos crear un driver con el gateway
+ Driver drv = DriverFactory.createDriver(gtwy);
+ if (drv == null) {
+ // soltamos el gateway
+ bc.ungetService(reference);
+ gtwy = null;
+ } else {
+ // registramos el driver en OSGi
+ Dictionary properties = new Hashtable();
+ properties.put(Constants.DRIVER_DEVICE_NAME, gtwy.getDeviceName());
+ properties.put(Constants.DRIVER_DONGLE_ADDRESS, gtwy.getDongleAddress());
+ properties.put(Constants.DRIVER_FIRMWARE_REVISION, gtwy.getFirmwareRevision());
+ ServiceRegistration srDriver = bc.registerService(Driver.class.getName(), drv, properties);
+ // lo añadimos a la lista de gateways
+ gatewaysUsed.put(reference, srDriver);
+
+ // creamos un ZigbeePublisher para el driver
+ ZigbeePublisher zp = new ZigbeePublisher(drv);
+ zp.start();
+ zpList.put(drv, zp);
+
+ }
+
+ // devolvemos el gateway (será null si no hemos abierto un gateway
+ return gtwy;
+
+ }
+
+ @Override
+ public void modifiedService(ServiceReference reference, Object service) {
+ // no hacemos nada
+ }
+
+ @Override
+ public void removedService(ServiceReference reference, Object service) {
+ // Comprobamos si es un gateway asociado a un driver
+ if (gatewaysUsed.containsKey(reference)) {
+ BundleContext bc = Activator.getBundleContext();
+ // Recuperamos el driver
+ ServiceRegistration sregDriver = gatewaysUsed.get(reference);
+ Driver drv = (Driver) bc.getService(sregDriver.getReference());
+
+ // despublicamos los dispositivos asociados al driver
+ ZigbeePublisher zp = zpList.get(drv);
+ zp.stop();
+
+ // paramos el driver
+ drv.stop();
+ // despublicamos el driver
+ sregDriver.unregister();
+
+ // Soltamos el gateway
+ bc.ungetService(reference);
+
+ // los eliminamos de la lista
+ gatewaysUsed.remove(reference);
+
+ }
+
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/ZigbeePublisher.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/ZigbeePublisher.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/osgi/ZigbeePublisher.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,342 @@
+/*
+ * 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.driver.impl.osgi;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver;
+import es.unizar.howlab.core.zigbee.telegesis.driver.Driver.DriverStatus;
+import es.unizar.howlab.core.zigbee.telegesis.driver.DriverListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice.DeviceStatus;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDeviceListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNode.NodeStatus;
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeNodeListener;
+import es.unizar.howlab.core.zigbee.telegesis.driver.osgi.Constants;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Clase para registrar servicios en OSGi, conforme a los cambios de estado
+ * de los nodos y devices
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class ZigbeePublisher implements DriverListener, ZigbeeNodeListener, ZigbeeDeviceListener {
+
+ private final HashMap<ZigbeeNode, ServiceRegistration> nodesRegistered = new HashMap<ZigbeeNode, ServiceRegistration>();
+ private final HashMap<ZigbeeDevice, ServiceRegistration> devicesRegistered = new HashMap<ZigbeeDevice, ServiceRegistration>();
+ // Logger
+ static Log logger = LogFactory.getLog(ZigbeePublisher.class.getName());
+ final Driver driver;
+
+ public ZigbeePublisher(Driver drv) {
+ logger.trace("ZigbeePublisher::ZigbeePublisher(drv=" + drv + ")");
+ // guardamos el driver
+ driver = drv;
+ }
+
+ /**
+ * Registra el listener y publica los dispositivos descubiertos hasta ahora
+ */
+ public void start() {
+ logger.trace("ZigbeePublisher::start()");
+ // nos registramos como listener
+ driver.registerListener(this);
+
+ // publicamos los servicios
+ publishAllServices();
+
+ }
+
+ /**
+ * Publica los sercicios asociados a los dispositivos del driver
+ */
+ private void publishAllServices() {
+ logger.trace("ZigbeePublisher::publishAllServices()");
+
+ // recuperamos los nodos
+ ZigbeeNode[] nodes = driver.getNodes();
+ for (int i = 0; i < nodes.length; i++) {
+ ZigbeeNode nd = nodes[i];
+
+ // registramos listener del nodo
+ nd.registerListener(this);
+
+ // publicamos el nodo
+ registerNode(nd);
+
+ // recuperamos devices
+ ZigbeeDevice[] devices = nd.getZigbeeDevices();
+ for (int j = 0; j < devices.length; j++) {
+ ZigbeeDevice zb = devices[j];
+ // registramos listener del device
+ zb.registerListener(this);
+ // publicamos el device
+ registerDevice(zb);
+ }
+ }
+
+ }
+
+ /**
+ * Elimina el registro de todos los dispositivos publicados
+ */
+ public void stop() {
+ logger.trace("ZigbeePublisher::stop()");
+
+ // despublicamos los servicios
+ unpublishAllServices();
+
+ // nos desregistramos como listener del driver
+ driver.unregisterListener(this);
+
+ }
+
+ /**
+ * Elimina el registro de todos los servicios publicados
+ */
+ private void unpublishAllServices() {
+ logger.trace("ZigbeePublisher::unpublishAllServices()");
+
+ synchronized (devicesRegistered) {
+ // Desregistramos devices
+ Iterator itDevices = devicesRegistered.keySet().iterator();
+ while (itDevices.hasNext()) {
+ // recuperamos el ZigbeeDevice
+ ZigbeeDevice zb = (ZigbeeDevice) itDevices.next();
+ logger.info("Unregistering service for ZigbeeDevice: " + zb);
+
+ // nos desregistramos como listener
+ zb.unregisterListener(this);
+
+ // despublicamos el ZigbeeDevice
+ ServiceRegistration sr = (ServiceRegistration) devicesRegistered.get(zb);
+ sr.unregister();
+ }
+ devicesRegistered.clear();
+ }
+
+ synchronized (nodesRegistered) {
+ // Desregistramos nodos
+ Iterator itNodes = nodesRegistered.keySet().iterator();
+ while (itNodes.hasNext()) {
+ // recuperamos el ZigbeeNode
+ ZigbeeNode zn = (ZigbeeNode) itNodes.next();
+ logger.info("Unregistering service for ZigbeeNode: " + zn);
+
+ // nos desregistramos como listener
+ zn.unregisterListener(this);
+
+ // despublicamos el ZigbeeNode
+ ServiceRegistration sr = (ServiceRegistration) nodesRegistered.get(zn);
+ sr.unregister();
+ }
+ nodesRegistered.clear();
+
+ }
+ }
+
+ /**
+ * Registra el dispositivo en OSGi
+ * @param zb
+ */
+ protected void registerDevice(ZigbeeDevice zb) {
+ logger.trace("ZigbeePublisher::registerDevice(zb=" + zb + ")");
+ synchronized (devicesRegistered) {
+ // comprobamos si lo hemos registrado ya
+ if (!devicesRegistered.containsKey(zb)) {
+ // recuperamos el bundle context
+ BundleContext bc = Activator.getBundleContext();
+
+ // registramos el ZigbeeDevice
+ Dictionary properties = new Hashtable();
+ properties.put(Constants.DRIVER_ZIGBEE_DEVICE_ADDRESS, zb.getZigbeeNode().getEUI64Addr());
+ properties.put(Constants.DRIVER_ZIGBEE_DEVICE_ENDPOINT, zb.getEndPoint());
+ if (zb.getDeviceId() != null){
+ properties.put(Constants.DRIVER_ZIGBEE_DEVICE_ID, zb.getDeviceId());
+ }
+ if (zb.getProfileId() != null){
+ properties.put(Constants.DRIVER_ZIGBEE_DEVICE_PROFILE_ID, zb.getProfileId());
+ }
+ ServiceRegistration sr = bc.registerService(ZigbeeDevice.class.getName(), zb, properties);
+ logger.info("Registered service for ZigbeeDevice: " + zb);
+
+ // guardamos la referencia del registro
+ devicesRegistered.put(zb, sr);
+ }
+ }
+ }
+
+ /**
+ * Desregistra un nodo en OSGi
+ * @param zn
+ */
+ protected void unregisterNode(ZigbeeNode zn) {
+ logger.trace("ZigbeePublisher::unregisterNode(zn=" + zn + ")");
+ synchronized (nodesRegistered) {
+ // comprobamos si está registrado
+ if (nodesRegistered.containsKey(zn)) {
+ // recuperamos la referencia del servicio
+ ServiceRegistration sr = nodesRegistered.get(zn);
+
+ // desregistramos el ZigbeNode
+ sr.unregister();
+ logger.info("Unregistered service for ZigbeeNode: " + zn);
+
+ // eliminamos la referencia del registro
+ nodesRegistered.remove(zn);
+ }
+ }
+ }
+
+ /**
+ * Desregistra un device en OSGi
+ * @param zb
+ */
+ protected void unregisterDevice(ZigbeeDevice zb) {
+ logger.trace("ZigbeePublisher::unregisterDevice(zb=" + zb + ")");
+ // comprobamos si está registrado
+ synchronized (devicesRegistered) {
+ if (devicesRegistered.containsKey(zb)) {
+ // recuperamos la referencia del servicio
+ ServiceRegistration sr = devicesRegistered.get(zb);
+
+ // desregistramos el ZigbeeDevice
+ sr.unregister();
+ logger.info("Unregistered service for ZigbeeDevice: " + zb);
+
+ // eliminamos la referencia del registro
+ devicesRegistered.remove(zb);
+ }
+ }
+ }
+
+ /**
+ * Registra el nodo en OSGi
+ * @param zn
+ */
+ protected void registerNode(ZigbeeNode zn) {
+ logger.trace("ZigbeePublisher::registerNode(zn=" + zn + ")");
+ synchronized (nodesRegistered) {
+ // comprobamos si lo hemos registrado ya
+ if (!nodesRegistered.containsKey(zn)) {
+ // recuperamos el bundle context
+ BundleContext bc = Activator.getBundleContext();
+
+ // registramos el ZigbeeNode
+ Dictionary properties = new Hashtable();
+ properties.put(Constants.DRIVER_ZIGBEE_NODE_ADDRESS, zn.getEUI64Addr());
+ properties.put(Constants.DRIVER_ZIGBEE_NODE_TYPE, zn.getType());
+ ServiceRegistration sr = bc.registerService(ZigbeeNode.class.getName(), zn, properties);
+ logger.info("Registered service for ZigbeeNode: " + zn);
+
+ // guardamos la referencia del registro
+ nodesRegistered.put(zn, sr);
+ }
+ }
+ }
+
+ @Override
+ public void newNode(ZigbeeNode node, Driver drv) {
+ logger.trace("ZigbeePublisher::newNode(node=" + node + ", drv=" + drv + ")");
+ // nos registramos como listener del Nodo
+ node.registerListener(this);
+
+ // registramos el nodo
+ registerNode(node);
+ }
+
+ @Override
+ public void nodeLeft(ZigbeeNode node, Driver drv) {
+ logger.trace("ZigbeePublisher::nodeLeft(node=" + node + ", drv=" + drv + ")");
+
+ // nos desregistramos como listener
+ node.unregisterListener(this);
+
+ // desregistramos el nodo
+ unregisterNode(node);
+
+ }
+
+ @Override
+ public void newDevice(ZigbeeDevice device, Driver drv) {
+ logger.trace("ZigbeePublisher::newDevice(device=" + device + ", drv=" + drv + ")");
+ // nos registramos como listener del device
+ device.registerListener(this);
+ // registramos el device
+ registerDevice(device);
+ }
+
+ @Override
+ public void deviceLeft(ZigbeeDevice device, Driver drv) {
+ logger.trace("ZigbeePublisher::deviceLeft(device=" + device + ", drv=" + drv + ")");
+ // nos desregistramos como listener
+ device.unregisterListener(this);
+
+ // desregistramos el device
+ unregisterDevice(device);
+ }
+
+ @Override
+ public void joinNetwork(int channel, String PANID, String EPID, Driver drv) {
+ logger.trace("ZigbeePublisher::joinNetwork(channel=" + channel + ", PANID=" + PANID + ", EPID=" + EPID + ", drv=" + drv + ")");
+
+ // publicamos todos los dispositivos
+ publishAllServices();
+ }
+
+ @Override
+ public void leftNetwork(Driver drv) {
+ logger.trace("ZigbeePublisher::leftNetwork(drv=" + drv + ")");
+
+ // despublicamos todos los dispositivos
+ unpublishAllServices();
+
+ }
+
+ @Override
+ public void statusChanged(DriverStatus status, DriverStatus oldStatus, Driver drv) {
+ // ignoramos
+ }
+
+ @Override
+ public void messageReceived(String profileID, String clusterID, byte[] message, ZigbeeDevice zb) {
+ // ignoramos
+ }
+
+ @Override
+ public void statusChanged(DeviceStatus status, DeviceStatus oldStatus, ZigbeeDevice zb) {
+ logger.trace("ZigbeePublisher::statusChanged(status=" + status + ", oldStatus=" + oldStatus + ", zb=" + zb + ")");
+ registerDevice(zb);
+ }
+
+ @Override
+ public void messageReceived(byte[] message, ZigbeeNode zn) {
+ // ignoramos
+ }
+
+ @Override
+ public void statusChanged(NodeStatus status, NodeStatus oldStatus, ZigbeeNode zn) {
+ logger.trace("ZigbeePublisher::statusChanged(status=" + status + ", oldStatus=" + oldStatus + ", zn=" + zn + ")");
+ registerNode(zn);
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/AbstractGatewayListener.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/AbstractGatewayListener.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/AbstractGatewayListener.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,117 @@
+/*
+ * 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.driver.impl.util;
+
+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.Map;
+
+/**
+ * Clase abstracta para que la extiendan los listeners especÃficos sin tener que
+ * implementar todos los métodos
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public abstract class AbstractGatewayListener implements GatewayListener {
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ abstract public void clearListener();
+
+ @Override
+ public void acknowledgement(short seqNumber, boolean wasACK, Gateway gtwy) {
+ }
+
+ @Override
+ public void routeRecordReceived(String EUI64Addr, int numHops, String[] route, Gateway gtwy) {
+ }
+
+ @Override
+ public void broadcastMessageReceived(String EUI64Addr, byte[] message, Gateway gtwy) {
+ }
+
+ @Override
+ public void messageReceived(String EUI64Addr, byte[] message, String type, Gateway gtwy) {
+ }
+
+ @Override
+ public void endpointMessageReceived(String EUI64Addr, String nodeID, short sourceEP, short destEP, String profileID, String clusterID, byte[] payload, Gateway gtwy) {
+ }
+
+ @Override
+ public void nodeAnnounce(ZigbeeDeviceType type, String EUI64Addr, String nodeID, int RSSI, short LQI, Gateway gtwy) {
+ }
+
+ @Override
+ public void newNode(String EUI64Addr, String nodeID, String parentID, Gateway gtwy) {
+ }
+
+ @Override
+ public void leftPAN(Gateway gtwy) {
+ }
+
+ @Override
+ public void joinedPan(int channel, String PID, String EPID, Gateway gtwy) {
+ }
+
+ @Override
+ public void registerWrited(String nodeID, String EUI64Addr, short errorCode, Gateway gtwy) {
+ }
+
+ @Override
+ public void registerReaded(String nodeID, String EUI64Addr, short register, short errorCode, String data, Gateway gtwy) {
+ }
+
+ @Override
+ public void addrResponse(short errorCode, String nodeID, String EUI64Addr, Gateway gtwy) {
+ }
+
+ @Override
+ public void neighbourTableResponse(String nodeID, short errorCode, int tableLength, NeighbourTableEntry[] table, Gateway gtwy) {
+ }
+
+ @Override
+ public void nodeDescriptorResponse(String nodeID, short errorCode, Map descriptor, Gateway gtwy) {
+ }
+
+ @Override
+ public void powerDescriptorResponse(String nodeID, short errorCode, String descriptor, Gateway gtwy) {
+ }
+
+ @Override
+ public void nodeActiveEPResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ }
+
+ @Override
+ public void nodeEndPointSimpleDescriptorResponse(String nodeID, short errorCode, short EP, String ProfileID, String DeviceID, String[] inClusterList, String[] outClusterList, Gateway gtwy) {
+ }
+
+ @Override
+ public void nodeMatchingDescriptorResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ }
+
+ @Override
+ public void unhandledCommand(String command, String[] parameters, Gateway gtwy) {
+ }
+
+ @Override
+ public void unknownMessage(String message, Gateway gtwy) {
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrACK.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrACK.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrACK.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,131 @@
+/*
+ * 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.driver.impl.util;
+
+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.ArrayList;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle ACK/NACK notifications
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class GtwyLstnrACK extends AbstractGatewayListener {
+
+ final Gateway gateway;
+ ArrayList<String> ACKList = new ArrayList<String>();
+ ArrayList<String> NACKList = new ArrayList<String>();
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrACK(Gateway gtwy) {
+ logger.trace("GtwyLstnrACK::GtwyLstnrACK(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación de ACK
+ * para el SeqNumber indicado, o hasta que transcurra el tiempo máximo
+ * indicado
+ * @param seqNumber SeqNumber de referencia
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe el ACK, o false si se recibe NACK o pasa el tiempo
+ * indicado
+ */
+ public boolean waitForACK(short seqNumber, long milliseconds) {
+ logger.trace("GtwyLstnrACK::waitForACK(seqNumber=" + seqNumber + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting ACK] waiting for ACK:%02X for %d milliseconds", seqNumber, milliseconds));
+ // obtenemos una representación del SeqNumber para usar en el control
+ String SEQ = String.format("%02X", seqNumber);
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+ // iniciamos bucle de espera
+ while (!ACKList.contains(SEQ)) {
+ try {
+ // esperamos notificación de ACK
+ this.wait(wakeUpDelay);
+ // comprobamos si ha llegado el ACK
+ if (ACKList.contains(SEQ)) {
+ logger.info(String.format("[Waiting ACK] ACK:%02X received", seqNumber));
+ clearListener();
+ return true;
+ }
+ // comprobamos si ha llegado un NACK
+ if (NACKList.contains(SEQ)) {
+ logger.warn(String.format("[Waiting ACK] NACK:%02X received", seqNumber));
+ clearListener();
+ return false;
+ }
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting ACK] Timeout awaiting ACK:%02X", seqNumber));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ // si hemos llegado aquÃ, es porque el SEQ habÃa llegado antes de empezar a esperar, devolvemos OK
+ logger.info(String.format("[Waiting ACK] ACK:%02X received", seqNumber));
+ clearListener();
+ return true;
+ }
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrACK::clearListener()");
+ gateway.unregisterListener(this);
+ ACKList.clear();
+ NACKList.clear();
+ }
+
+ @Override
+ public void acknowledgement(short seqNumber, boolean wasACK, Gateway gtwy) {
+ logger.trace("GtwyLstnrACK::acknowledgement(seqNumber=" + seqNumber + ", wasACK=" + wasACK + ", gtwy=" + gtwy + ")");
+ if (ACKList == null) {
+ return;
+ }
+ synchronized (this) {
+ // guardamos el ACK/NACK
+ String SEQ = String.format("%02X", seqNumber);
+ if (wasACK) {
+ ACKList.add(SEQ);
+ } else {
+ NACKList.add(SEQ);
+ }
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrActiveEndPoints.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrActiveEndPoints.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrActiveEndPoints.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,150 @@
+/*
+ * 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.driver.impl.util;
+
+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.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle NeighbourTableResponse notifications
+ * @author Alvaro
+ */
+public class GtwyLstnrActiveEndPoints extends AbstractGatewayListener {
+
+ final Gateway gateway;
+ // variables para almacenar resultados de eventos
+ HashMap<String, short[]> nodesActiveEPList = new HashMap<String, short[]>();
+ HashMap<String, String> nodesErrorCodeList = new HashMap<String, String>();
+ // variables para consultar resultados de espera
+ short[] nodeActiveEPList = null;
+ String errorMessage = "";
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrActiveEndPoints(Gateway gtwy) {
+ logger.trace("GtwyLstnrActiveEndPoints::GtwyLstnrActiveEndPoints(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación para
+ * el nodo indicado, o hasta que transcurra el tiempo máximo
+ * @param nodeID Dirección del nodo
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe la respuesta OK, o false si se recibe respuesta
+ * NOK o pasa el tiempo indicado
+ */
+ public boolean waitForActiveEndPoints(String nodeID, long milliseconds) {
+ logger.trace("GtwyLstnrActiveEndPoints::waitForActiveEndPoints(nodeID=" + nodeID + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting ActiveEndPoints] waiting for EPList of nodeID %s for %d milliseconds", nodeID, milliseconds));
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+
+ // iniciamos bucle de espera
+ while (!nodesActiveEPList.containsKey(nodeID)) {
+ try {
+ // esperamos notificación
+ this.wait(wakeUpDelay);
+ // comprobamos si ha llegado la tabla
+ if (nodesActiveEPList.containsKey(nodeID)) {
+ logger.info(String.format("[Waiting ActiveEndPoints] EPList of nodeID %s received", nodeID));
+ // guardamos los resultados
+ nodeActiveEPList = nodesActiveEPList.get(nodeID);
+ clearListener();
+ return true;
+ }
+ // comprobamos si ha llegado un NOK
+ if (nodesErrorCodeList.containsKey(nodeID)) {
+ errorMessage = nodesErrorCodeList.get(nodeID);
+ logger.warn(String.format("[Waiting ActiveEndPoints] Error awaiting EPList of nodeID %s. Error code: %s", nodeID, errorMessage));
+ clearListener();
+ return false;
+ }
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting ActiveEndPoints] Timeout awaiting EPList of nodeID %s", nodeID));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ // si hemos llegado aquÃ, es porque la tabla habÃa llegado antes de empezar a esperar, devolvemos OK
+ nodeActiveEPList = nodesActiveEPList.get(nodeID);
+ logger.info(String.format("[Waiting ActiveEndPoints] EPList of nodeID %s received", nodeID));
+ clearListener();
+ return true;
+ }
+ }
+
+ /**
+ * Recupera la lista de EndPoints despues de esperar
+ * @return NeighbourTable
+ */
+ public short[] getEndPointList() {
+ return nodeActiveEPList;
+ }
+
+ /**
+ * Recupera el código de error despues de esperar
+ * @return errorMessage
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrActiveEndPoints::clearListener()");
+ gateway.unregisterListener(this);
+ nodesActiveEPList.clear();
+ nodesErrorCodeList.clear();
+ }
+
+ @Override
+ public void nodeActiveEPResponse(String nodeID, short errorCode, short[] EPList, Gateway gtwy) {
+ logger.trace("GtwyLstnrActiveEndPoints::nodeActiveEPResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", EPList=" + EPList + ", gtwy=" + gtwy + ")");
+ synchronized (this) {
+ // comprobamos el resultado
+ if (errorCode == 0) { // resultado correcto
+ nodesActiveEPList.put(nodeID, EPList);
+ } else { // resultado incorrecto
+ nodesErrorCodeList.put(nodeID, String.format("%02X", errorCode));
+ }
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrAddrResponse.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrAddrResponse.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrAddrResponse.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,151 @@
+/*
+ * 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.driver.impl.util;
+
+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.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle AddrResponse notifications
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class GtwyLstnrAddrResponse extends AbstractGatewayListener {
+
+ final Gateway gateway;
+ // variables para almacenar resultados de eventos
+ HashMap<String, String> nodesIdList = new HashMap<String, String>();
+ HashMap<String, Integer> nodesNeighbourTablesLength = new HashMap<String, Integer>();
+ HashMap<String, String> nodesErrorCodeList = new HashMap<String, String>();
+ // variables para consultar resultados de espera
+ String nodeID = null;
+ String errorMessage = "";
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrAddrResponse(Gateway gtwy) {
+ logger.trace("GtwyLstnrAddrResponse::GtwyLstnrAddrResponse(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación para
+ * el nodo indicado, o hasta que transcurra el tiempo máximo
+ * @param EUI64Addr Dirección del nodo
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe la respuesta OK, o false si se recibe respuesta
+ * NOK o pasa el tiempo indicado
+ */
+ public boolean waitForAddrResponse(String EUI64Addr, long milliseconds) {
+ logger.trace("GtwyLstnrAddrResponse::waitForAddrResponse(seqNumber=" + EUI64Addr + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting AddrResponse] waiting AddrResponse for node %s for %d milliseconds", EUI64Addr, milliseconds));
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+
+ // iniciamos bucle de espera
+ while (!nodesIdList.containsKey(EUI64Addr)) {
+ try {
+ // esperamos notificación
+ this.wait(wakeUpDelay);
+ // comprobamos si ha llegado la tabla
+ if (nodesIdList.containsKey(EUI64Addr)) {
+ logger.info(String.format("[Waiting AddrResponse] AddrResponse of nodeID %s received", nodeID));
+ // guardamos los resultados
+ this.nodeID = nodesIdList.get(EUI64Addr);
+ clearListener();
+ return true;
+ }
+ // comprobamos si ha llegado un NOK
+ if (nodesErrorCodeList.containsKey(EUI64Addr)) {
+ errorMessage = nodesErrorCodeList.get(EUI64Addr);
+ clearListener();
+ logger.warn(String.format("[Waiting AddrResponse] Error awaiting AddrResponse of nodeID %s. Error code: %s", nodeID, errorMessage));
+ return false;
+ }
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting AddrResponse] Timeout awaiting AddrResponse of nodeID %s", nodeID));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ // si hemos llegado aquÃ, es porque la tabla habÃa llegado antes de empezar a esperar, devolvemos OK
+ logger.info(String.format("[Waiting AddrResponse] AddrResponse of nodeID %s received", nodeID));
+ this.nodeID = nodesIdList.get(EUI64Addr);
+ clearListener();
+ return true;
+ }
+ }
+
+ /**
+ * Recupera el NodeID despues de esperar
+ * @return NodeID
+ */
+ public String getNodeID() {
+ return nodeID;
+ }
+
+ /**
+ * Recupera el código de error despues de esperar
+ * @return errorMessage
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrAddrResponse::clearListener()");
+ gateway.unregisterListener(this);
+ nodesIdList.clear();
+ nodesErrorCodeList.clear();
+ }
+
+ @Override
+ public void addrResponse(short errorCode, String nodeID, String EUI64Addr, Gateway gtwy) {
+ logger.trace("GtwyLstnrAddrResponse::neighbourTableResponse(errorCode=" + errorCode + ", nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + gtwy + ")");
+ synchronized (this) {
+ // comprobamos el resultado
+ if (errorCode == 0) { // resultado correcto
+ nodesIdList.put(EUI64Addr, nodeID);
+ } else { // resultado incorrecto
+ nodesErrorCodeList.put(EUI64Addr, String.format("%02X", errorCode));
+ }
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrEndPointDescriptor.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrEndPointDescriptor.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrEndPointDescriptor.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,250 @@
+/*
+ * 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.driver.impl.util;
+
+import es.unizar.howlab.core.zigbee.telegesis.driver.ZigbeeDevice;
+import es.unizar.howlab.core.zigbee.telegesis.driver.impl.ZigbeeDeviceImpl;
+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.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle EndPointDescriptor notifications
+ * @author Alvaro
+ */
+public class GtwyLstnrEndPointDescriptor extends AbstractGatewayListener {
+
+ Gateway gateway;
+ // variables para almacenar resultados de eventos
+ HashMap<String, HashMap<String, ZigbeeDevice>> endPointDescriptorsNodeList = new HashMap<String, HashMap<String, ZigbeeDevice>>();
+ HashMap<String, HashMap<String, String>> endPointDescriptorsErrorNodeList = new HashMap<String, HashMap<String, String>>();
+ // variables para consultar resultados de espera
+ ZigbeeDevice endPointDescriptor = null;
+ String errorMessage = "";
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrEndPointDescriptor(Gateway gtwy) {
+ logger.trace("GtwyLstnrEndPointDescriptor::GtwyLstnrEndPointDescriptor(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación
+ * EndPointSimpleDescriptor para el nodo indicado y el endPoint solicitado,
+ * o hasta que transcurra el tiempo máximo indicado
+ * @param nodeID Dirección del nodo
+ * @param endPoint Dirección del endPoint
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe la respuesta OK, o false si se recibe respuesta
+ * NOK o pasa el tiempo indicado
+ */
+ public boolean waitForEndPointSimpleDescriptor(String nodeID, short endPoint, long milliseconds) {
+ logger.trace("GtwyLstnrEndPointDescriptor::waitForEndPointSimpleDescriptor(nodeID=" + nodeID + ", regAddress=" + endPoint + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting EndPointDescriptor] waiting for EPDescriptor of nodeID %s, EP:%02X for %d milliseconds", nodeID, endPoint, milliseconds));
+ // obtenemos una representación del endPoint para usar en el control
+ String strEP = String.format("%02X", endPoint);
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+
+ // comprobamos primero si ya ha llegado la respuesta antes de esperar
+ // comprobamos si ha llegado el descriptor OK
+ endPointDescriptor = getDescriptor(nodeID, endPoint);
+ if (endPointDescriptor != null) {
+ logger.info(String.format("[Waiting EndPointDescriptor] EPDescriptor of nodeID %s, EP:%02X received", nodeID, endPoint));
+ clearListener();
+ return true;
+ }
+
+ // comprobamos si ha llegado descriptor NOK
+ if (getErrorCode(nodeID, endPoint) != null) {
+ errorMessage = getErrorCode(nodeID, endPoint);
+ logger.warn(String.format("[Waiting EndPointDescriptor] Error awaiting EPDescriptor of nodeID %s, EP:%02X. Error code: %s", nodeID, endPoint, errorMessage));
+ clearListener();
+ return false;
+ }
+
+ // iniciamos bucle de espera con una variable de control
+ boolean done = false;
+ while (!done) {
+ try {
+ // esperamos notificación de lectura de registro
+ this.wait(wakeUpDelay);
+
+ // comprobamos si ha llegado el descriptor OK
+ endPointDescriptor = getDescriptor(nodeID, endPoint);
+ if (endPointDescriptor != null) {
+ logger.info(String.format("[Waiting EndPointDescriptor] EPDescriptor of nodeID %s, EP:%02X received", nodeID, endPoint));
+ clearListener();
+ return true;
+ }
+ // comprobamos si ha llegado descriptor NOK
+ if (getErrorCode(nodeID, endPoint) != null) {
+ errorMessage = getErrorCode(nodeID, endPoint);
+ logger.warn(String.format("[Waiting EndPointDescriptor] Error awaiting EPDescriptor of nodeID %s, EP:%02X. Error code: %s", nodeID, endPoint, errorMessage));
+ clearListener();
+ return false;
+ }
+
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting EndPointDescriptor] Timeout awaiting EPDescriptor of nodeID %s, EP:%02X", nodeID, endPoint));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ }
+
+ // no deberÃamos llegar a este punto de ejecución
+ return false;
+ }
+
+ /**
+ * Recupera el valor del registro y nodo en la lista combinada
+ * @param nodeID dirección de red del nodo
+ * @param endPoint dirección del endPoint
+ * @return ZigbeeDevice conteniendo el descriptor, o null si no existe
+ */
+ private ZigbeeDevice getDescriptor(String nodeID, short endPoint) {
+ // obtenemos una representación del endPoint para usar en el control
+ String strEP = String.format("%02X", endPoint);
+
+ if (endPointDescriptorsNodeList.containsKey(nodeID)) {
+ HashMap<String, ZigbeeDevice> endPointDescriptorList = endPointDescriptorsNodeList.get(nodeID);
+ // comprobamos si ha llegado el valor del registro
+ if (endPointDescriptorList.containsKey(strEP)) {
+ return endPointDescriptorList.get(strEP);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Recupera el código de error despues de esperar
+ * @return errorMessage
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Recupera la condición de error del registro y nodo en la lista combinada
+ * @param nodeID dirección del nodo
+ * @param endPoint dirección del endPoint
+ * @return valor correspondiente, o null si no existe
+ */
+ private String getErrorCode(String nodeID, short endPoint) {
+ // obtenemos una representación del endPoint para usar en el control
+ String strEP = String.format("%02X", endPoint);
+
+ if (endPointDescriptorsErrorNodeList.containsKey(nodeID)) {
+ HashMap<String, String> endPointList = endPointDescriptorsErrorNodeList.get(nodeID);
+ // comprobamos si ha llegado el codigo de error
+ if (endPointList.containsKey(strEP)) {
+ return endPointList.get(strEP);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Recupera el endPointDescriptor despues de esperar
+ * @return ZigbeeDevice auxiliar conteniendo el descriptor
+ */
+ public ZigbeeDevice getEndPointDescriptor() {
+ return endPointDescriptor;
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrEndPointDescriptor::clearListener()");
+ gateway.unregisterListener(this);
+ gateway = null;
+ endPointDescriptorsNodeList.clear();
+ endPointDescriptorsErrorNodeList.clear();
+ }
+
+ @Override
+ public void nodeEndPointSimpleDescriptorResponse(String nodeID, short errorCode, short EP, String ProfileID, String DeviceID, String[] inClusterList, String[] outClusterList, Gateway gtwy) {
+ logger.trace("GtwyLstnrEndPointDescriptor::nodeEndPointSimpleDescriptorResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", EP=" + EP + ", profileID=" + ProfileID + ", DeviceID=" + DeviceID + ", inClusterList=" + inClusterList + ", outClusterList=" + outClusterList + ", gtwy=" + gtwy + ")");
+ synchronized (this) {
+ // comprobamos el resultado
+ if (errorCode == 0) { // resultado OK
+ // recuperamos la lista de endPoints del nodo
+ HashMap<String, ZigbeeDevice> endPointDescriptorsList = endPointDescriptorsNodeList.get(nodeID);
+ if (endPointDescriptorsList == null) {
+ endPointDescriptorsList = new HashMap<String, ZigbeeDevice>();
+ }
+
+ // creamos un zigbeeDevice temporal
+ ZigbeeDeviceImpl auxDevice = new ZigbeeDeviceImpl(null, null, EP);
+ // actualizamos los datos
+ ((ZigbeeDeviceImpl) auxDevice).setProfileID(ProfileID);
+ ((ZigbeeDeviceImpl) auxDevice).setDeviceID(DeviceID);
+ ((ZigbeeDeviceImpl) auxDevice).setInClusterList(inClusterList);
+ ((ZigbeeDeviceImpl) auxDevice).setOutClusterList(outClusterList);
+
+ // guardamos el valor del descriptor
+ endPointDescriptorsList.put(String.format("%02X", EP), auxDevice);
+
+ // guardamos la lista de descriptores
+ endPointDescriptorsNodeList.put(nodeID, endPointDescriptorsList);
+
+ } else { // resultado NOK
+ // recuperamos la lista de endPoints del nodo
+ HashMap<String, String> endPointDescriptorsList = endPointDescriptorsErrorNodeList.get(nodeID);
+ if (endPointDescriptorsList == null) {
+ endPointDescriptorsList = new HashMap<String, String>();
+ }
+
+ // guardamos el código de error
+ endPointDescriptorsList.put(String.format("%02X", EP), String.format("%02X", errorCode));
+
+ // guardamos la lista errores
+ endPointDescriptorsErrorNodeList.put(nodeID, endPointDescriptorsList);
+
+ }
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrNeighbourTableResponse.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrNeighbourTableResponse.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrNeighbourTableResponse.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,164 @@
+/*
+ * 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.driver.impl.util;
+
+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.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle NeighbourTableResponse notifications
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class GtwyLstnrNeighbourTableResponse extends AbstractGatewayListener {
+
+ final Gateway gateway;
+ // variables para almacenar resultados de eventos
+ HashMap<String, NeighbourTableEntry[]> nodesNeighbourTablesList = new HashMap<String, NeighbourTableEntry[]>();
+ HashMap<String, Integer> nodesNeighbourTablesLength = new HashMap<String, Integer>();
+ HashMap<String, String> nodesErrorCodeList = new HashMap<String, String>();
+ // variables para consultar resultados de espera
+ NeighbourTableEntry[] neighbourTableEntries = null;
+ int neighbourTableLength = 0;
+ String errorMessage = "";
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrNeighbourTableResponse(Gateway gtwy) {
+ logger.trace("GtwyLstnrNeighbourTableResponse::GtwyLstnrNeighbourTableResponse(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación para
+ * el nodo indicado, o hasta que transcurra el tiempo máximo
+ * @param nodeID Dirección del nodo
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe la respuesta OK, o false si se recibe respuesta
+ * NOK o pasa el tiempo indicado
+ */
+ public boolean waitForNeighbourTableResponse(String nodeID, long milliseconds) {
+ logger.trace("GtwyLstnrNeighbourTableResponse::waitForNeighbourTableResponse(seqNumber=" + nodeID + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting Neighbour table] waiting for NTable of nodeID %s for %d milliseconds", nodeID, milliseconds));
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+
+ // iniciamos bucle de espera
+ while (!nodesNeighbourTablesList.containsKey(nodeID)) {
+ try {
+ // esperamos notificación
+ this.wait(wakeUpDelay);
+ // comprobamos si ha llegado la tabla
+ if (nodesNeighbourTablesList.containsKey(nodeID)) {
+ logger.info(String.format("[Waiting Neighbour table] NTable of nodeID %s received", nodeID));
+ // guardamos los resultados
+ neighbourTableEntries = nodesNeighbourTablesList.get(nodeID);
+ neighbourTableLength = nodesNeighbourTablesLength.get(nodeID);
+ clearListener();
+ return true;
+ }
+ // comprobamos si ha llegado un NOK
+ if (nodesErrorCodeList.containsKey(nodeID)) {
+ logger.warn(String.format("[Waiting Neighbour table] Error awaiting NTable of nodeID %s. Error code: %s", nodeID, errorMessage));
+ errorMessage = nodesErrorCodeList.get(nodeID);
+ clearListener();
+ return false;
+ }
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting Neighbour table] Timeout awaiting NTable of nodeID %s", nodeID));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ // si hemos llegado aquÃ, es porque la tabla habÃa llegado antes de empezar a esperar, devolvemos OK
+ logger.info(String.format("[Waiting Neighbour table] NTable of nodeID %s received", nodeID));
+ neighbourTableEntries = nodesNeighbourTablesList.get(nodeID);
+ neighbourTableLength = nodesNeighbourTablesLength.get(nodeID);
+ clearListener();
+ return true;
+ }
+ }
+
+ /**
+ * Recupera la tabla de vecinos despues de esperar
+ * @return NeighbourTable
+ */
+ public NeighbourTableEntry[] getNeighbourTable() {
+ return neighbourTableEntries;
+ }
+
+ /**
+ * Recupera la longitud de la tabla de vecinos despues de esperar
+ * @return NeighbourTableLength
+ */
+ public int getNeighbourTableLength() {
+ return neighbourTableLength;
+ }
+
+ /**
+ * Recupera el código de error despues de esperar
+ * @return errorMessage
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrNeighbourTableResponse::clearListener()");
+ gateway.unregisterListener(this);
+ nodesNeighbourTablesList.clear();
+ nodesNeighbourTablesLength.clear();
+ nodesErrorCodeList.clear();
+ }
+
+ @Override
+ public void neighbourTableResponse(String nodeID, short errorCode, int tableLength, NeighbourTableEntry[] table, Gateway gtwy) {
+ logger.trace("GtwyLstnrNeighbourTableResponse::neighbourTableResponse(nodeID=" + nodeID + ", errorCode=" + errorCode + ", tableLength=" + tableLength + ", table=" + table + ", gtwy=" + gtwy + ")");
+ synchronized (this) {
+ // comprobamos el resultado
+ if (errorCode == 0) { // resultado correcto
+ nodesNeighbourTablesList.put(nodeID, table);
+ nodesNeighbourTablesLength.put(nodeID, tableLength);
+ } else { // resultado incorrecto
+ nodesErrorCodeList.put(nodeID, String.format("%02X", errorCode));
+ }
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterRead.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterRead.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterRead.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,239 @@
+/*
+ * 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.driver.impl.util;
+
+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.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle RegisterRead notifications
+ * @author Alvaro
+ */
+public class GtwyLstnrRegisterRead extends AbstractGatewayListener {
+
+ Gateway gateway;
+ // variables para almacenar resultados de eventos
+ HashMap<String, HashMap<String, String>> registersDataNodeList = new HashMap<String, HashMap<String, String>>();
+ HashMap<String, HashMap<String, String>> registersErrorNodeList = new HashMap<String, HashMap<String, String>>();
+ // variables para consultar resultados de espera
+ String registerData = null;
+ String errorMessage = "";
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrRegisterRead(Gateway gtwy) {
+ logger.trace("GtwyLstnrRegisterRead::GtwyLstnrRegisterRead(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación de
+ * registro leido para el nodo indicado y el registro solicitado, o hasta que
+ * transcurra el tiempo máximo indicado
+ * @param EUI64Addr Dirección del nodo
+ * @param regAddress Dirección del registro
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe la respuesta OK, o false si se recibe respuesta
+ * NOK o pasa el tiempo indicado
+ */
+ public boolean waitForRegisterReaded(String EUI64Addr, short regAddress, long milliseconds) {
+ logger.trace("GtwyLstnrRegisterRead::waitForRegisterReaded(EUI64Addr=" + EUI64Addr + ", reqAddress=" + regAddress + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting RegisterReaded] waiting for SREAD of node %s, address %02X, for %d milliseconds", EUI64Addr, regAddress, milliseconds));
+ // obtenemos una representación del SeqNumber para usar en el control
+ String REG = String.format("%02X", regAddress);
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+
+ // comprobamos primero si ya ha llegado la respuesta antes de esperar
+ registerData = getData(EUI64Addr, regAddress);
+ if (registerData != null) {
+ logger.info(String.format("[Waiting RegisterReaded] SREAD of node %s, address %02X received", EUI64Addr, regAddress));
+ clearListener();
+ return true;
+ }
+
+ // comprobamos si ha llegado la lectura del registro NOK
+ if (getErrorCode(EUI64Addr, regAddress) != null) {
+ errorMessage = getErrorCode(EUI64Addr, regAddress);
+ logger.warn(String.format("[Waiting RegisterReaded] Error awaiting SREAD of node %s, address %02X. Error code: %s", EUI64Addr, regAddress, errorMessage));
+ clearListener();
+ return false;
+ }
+
+ // iniciamos bucle de espera con una variable de control
+ boolean done = false;
+ while (!done) {
+ try {
+ // esperamos notificación de lectura de registro
+ this.wait(wakeUpDelay);
+
+ // comprobamos si ha llegado la lectura del registro OK
+ registerData = getData(EUI64Addr, regAddress);
+ if (registerData != null) {
+ logger.info(String.format("[Waiting RegisterReaded] SREAD of node %s, address %02X received", EUI64Addr, regAddress));
+ clearListener();
+ return true;
+ }
+ // comprobamos si ha llegado la lectura del registro NOK
+ if (getErrorCode(EUI64Addr, regAddress) != null) {
+ errorMessage = getErrorCode(EUI64Addr, regAddress);
+ logger.warn(String.format("[Waiting RegisterReaded] Error awaiting SREAD of node %s, address %02X. Error code: %s", EUI64Addr, regAddress, errorMessage));
+ clearListener();
+ return false;
+ }
+
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting RegisterReaded] Timeout awaiting SREAD of node %s, address %02X", EUI64Addr, regAddress));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ }
+
+ // no deberÃamos llegar a este punto de ejecución
+ return false;
+ }
+
+ /**
+ * Recupera el valor del registro y nodo en la lista combinada
+ * @param EUI64Addr dirección del nodo
+ * @param regAddress dirección del registro
+ * @return valor correspondiente, o null si no existe
+ */
+ private String getData(String EUI64Addr, short regAddress) {
+ // obtenemos una representación del SeqNumber para usar en el control
+ String REG = String.format("%02X", regAddress);
+
+ if (registersDataNodeList.containsKey(EUI64Addr)) {
+ HashMap<String, String> registerList = registersDataNodeList.get(EUI64Addr);
+ // comprobamos si ha llegado el valor del registro
+ if (registerList.containsKey(REG)) {
+ return registerList.get(REG);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Recupera la condición de error del registro y nodo en la lista combinada
+ * @param EUI64Addr dirección del nodo
+ * @param regAddress dirección del registro
+ * @return valor correspondiente, o null si no existe
+ */
+ private String getErrorCode(String EUI64Addr, short regAddress) {
+ // obtenemos una representación del SeqNumber para usar en el control
+ String REG = String.format("%02X", regAddress);
+
+ if (registersErrorNodeList.containsKey(EUI64Addr)) {
+ HashMap<String, String> registerList = registersErrorNodeList.get(EUI64Addr);
+ // comprobamos si ha llegado el codigo de error
+ if (registerList.containsKey(REG)) {
+ return registerList.get(REG);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Recupera el código de error despues de esperar
+ * @return errorMessage
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Recupera el contenido del registro despues de esperar
+ * @return RegisterData
+ */
+ public String getRegisterData() {
+ return registerData;
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrRegisterRead::clearListener()");
+ gateway.unregisterListener(this);
+ gateway = null;
+ registersDataNodeList.clear();
+ registersErrorNodeList.clear();
+ }
+
+ @Override
+ public void registerReaded(String nodeID, String EUI64Addr, short register, short errorCode, String data, Gateway gtwy) {
+ logger.trace("GtwyLstnrRegisterRead::registerReaded(nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + ", register=" + register + ", errorCode=" + errorCode + ", data=" + data + ", gtwy=" + gtwy + ")");
+ synchronized (this) {
+ // comprobamos el resultado
+ if (errorCode == 0) { // resultado OK
+ // recuperamos la lista de registros del nodo
+ HashMap<String, String> registerList = registersDataNodeList.get(EUI64Addr);
+ if (registerList == null) {
+ registerList = new HashMap<String, String>();
+ }
+
+ // guardamos el valor del registro
+ registerList.put(String.format("%02X", register), data);
+
+ // guardamos la lista de registros
+ registersDataNodeList.put(EUI64Addr, registerList);
+
+ } else { // resultado NOK
+ // recuperamos la lista de registros del nodo
+ HashMap<String, String> registerList = registersErrorNodeList.get(EUI64Addr);
+ if (registerList == null) {
+ registerList = new HashMap<String, String>();
+ }
+
+ // guardamos el código de error
+ registerList.put(String.format("%02X", register), String.format("%02X", errorCode));
+
+ // guardamos la lista de registros
+ registersErrorNodeList.put(EUI64Addr, registerList);
+
+ }
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterWrited.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterWrited.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrRegisterWrited.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,140 @@
+/*
+ * 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.driver.impl.util;
+
+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.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle RegisterWrited notifications
+ * @author Alvaro
+ */
+public class GtwyLstnrRegisterWrited extends AbstractGatewayListener {
+
+ final Gateway gateway;
+ HashMap<String, String> errorCodeNodeList = new HashMap<String, String>();
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+ // variables para consultar resultado despues de espera
+ String errorMessage = "";
+
+ public GtwyLstnrRegisterWrited(Gateway gtwy) {
+ logger.trace("GtwyLstnrRegisterWrited::GtwyLstnrRegisterWrited(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación de
+ * registro escrito para el nodo indicado, o hasta que transcurra el tiempo
+ * máximo indicado
+ * @param EUI64Addr Dirección del nodo
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si la operación de escritura ha ido OK, y False si se recibe
+ * erroCode distinto de 0 o pasa el tiempo máximo
+ */
+ public boolean waitForRegisterWrited(String EUI64Addr, long milliseconds) {
+ logger.trace("GatewayRegisterReadListener::waitForRegisterWrited(EUI64Addr=" + EUI64Addr + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+
+ // iniciamos bucle de espera
+ while (!errorCodeNodeList.containsKey(EUI64Addr)) {
+ try {
+ // esperamos notificación de lectura de registro
+ this.wait(wakeUpDelay);
+
+ // comprobamos si hemos recibido resultado de escritura
+ if (errorCodeNodeList.containsKey(EUI64Addr)) {
+ String errorCode = errorCodeNodeList.get(EUI64Addr);
+ errorMessage = errorCode;
+ clearListener();
+ if (errorCode.equals("00")) {
+ logger.info(String.format("[Waiting RegisterWrited] SWRITE of node %s received", EUI64Addr));
+ return true;
+ } else {
+ logger.warn(String.format("[Waiting RegisterWrited] Error awaiting SWRITE of node %s. Error code: %s", EUI64Addr, errorMessage));
+ return false;
+ }
+ }
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting RegisterWrited] Timeout awaiting SWRITE of node %s", EUI64Addr));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ }
+
+ // si hemos llegado a este punto, es porque el resutlado ha llegado antes de esperar
+ String errorCode = errorCodeNodeList.get(EUI64Addr);
+ errorMessage = errorCode;
+ clearListener();
+ if (errorCode.equals("00")) {
+ logger.info(String.format("[Waiting RegisterWrited] SWRITE of node %s received", EUI64Addr));
+ return true;
+ } else {
+ logger.warn(String.format("[Waiting RegisterWrited] Error retrieving SWRITE of node %s. Error code: %s", EUI64Addr, errorMessage));
+ return false;
+ }
+ }
+
+ /**
+ * Recupera el código de error despues de esperar
+ * @return errorMessage
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GatewayRegisterReadListener::clearListener()");
+ gateway.unregisterListener(this);
+ errorCodeNodeList.clear();
+ }
+
+ @Override
+ public void registerWrited(String nodeID, String EUI64Addr, short errorCode, Gateway gtwy) {
+ logger.trace("GatewayRegisterReadListener::registerWrited(nodeID=" + nodeID + ", EUI64Addr=" + EUI64Addr + ", errorCode=" + errorCode + ", gtwy=" + gtwy + ")");
+ synchronized (this) {
+ // guardamos el resultado
+ errorCodeNodeList.put(EUI64Addr, String.format("%02X", errorCode));
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrSourceRoute.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrSourceRoute.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/GtwyLstnrSourceRoute.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,118 @@
+/*
+ * 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.driver.impl.util;
+
+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.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * GatewayListener to handle SourceRoute notifications
+ * @author HowLab, University of Zaragoza (alvaro)
+ */
+public class GtwyLstnrSourceRoute extends AbstractGatewayListener {
+
+ final Gateway gateway;
+ HashMap<String, String[]> SRList = new HashMap<String, String[]>();
+ // Logger
+ Log logger = LogFactory.getLog(this.getClass().getName());
+
+ public GtwyLstnrSourceRoute(Gateway gtwy) {
+ logger.trace("GtwyLstnrSourceRoute::GtwyLstnrSourceRoute(gtwy=" + gtwy + ")");
+ gateway = gtwy;
+ gateway.registerListener(this);
+ }
+
+ /**
+ * Bloquea la ejecución hasta que el listener reciba una notificación de SR
+ * para la direccion indicada, o hasta que transcurra el tiempo máximo
+ * indicado
+ * @param EUI64Addr Direccion del nodo
+ * @param milliseconds Tiempo máximo de bloqueo
+ * @return True si se recibe el SR, o false si pasa el tiempo indicado
+ */
+ public boolean waitForSourceRoute(String EUI64Addr, long milliseconds) {
+ logger.trace("GtwyLstnrSourceRoute::waitForSourceRoute(EUI64Addr=" + EUI64Addr + ", milliseconds=" + milliseconds + ")");
+
+ synchronized (this) {
+ logger.info(String.format("[Waiting SourceRoute] waiting SR:XX,%s... for %d milliseconds", EUI64Addr, milliseconds));
+ // preparamos tiempos de espera
+ long endWaitTime = System.currentTimeMillis() + milliseconds;
+ long wakeUpDelay = milliseconds;
+ // iniciamos bucle de espera
+ while (!SRList.containsKey(EUI64Addr)) {
+ try {
+ // esperamos notificación de SR
+ this.wait(wakeUpDelay);
+ // comprobamos si ha llegado el SR
+ if (SRList.containsKey(EUI64Addr)) {
+ logger.info(String.format("[Waiting SourceRoute] SR:XX,%s... received", EUI64Addr));
+ clearListener();
+ return true;
+ }
+ // Calculamos tiempo restante
+ wakeUpDelay = endWaitTime - System.currentTimeMillis();
+ // comprobamos timeout
+ if (wakeUpDelay <= 0) {
+ logger.warn(String.format("[Waiting SourceRoute] Timeout awaiting SR:XX,%s", EUI64Addr));
+ clearListener();
+ return false;
+ }
+ } catch (InterruptedException ex) {
+ // no hacemos nada
+ }
+ }
+ // si hemos llegado aquÃ, es porque el SR habÃa llegado antes de empezar a esperar, devolvemos OK
+ logger.info(String.format("[Waiting SourceRoute] SR:XX,%s... received", EUI64Addr));
+ clearListener();
+ return true;
+ }
+ }
+
+ /**
+ * Función para operaciones de cierre del listener
+ */
+ @Override
+ public void clearListener() {
+ logger.trace("GtwyLstnrSourceRoute::clearListener()");
+ gateway.unregisterListener(this);
+ SRList.clear();
+ }
+
+ @Override
+ public void routeRecordReceived(String EUI64Addr, int numHops, String[] route, Gateway gtwy) {
+ logger.trace("GtwyLstnrSourceRoute::routeRecordReceived(EUI64Addr=" + EUI64Addr + ", numHops=" + numHops + ", route=" + route + ", gtwy=" + gtwy + ")");
+ if (SRList == null) {
+ return;
+ }
+ synchronized (this) {
+ // guardamos el SR
+ SRList.put(EUI64Addr, route);
+
+ // notificamos procesos en espera
+ this.notifyAll();
+ }
+
+ }
+
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/Register305.java
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/Register305.java (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/java/es/unizar/howlab/core/zigbee/telegesis/driver/impl/util/Register305.java Thu Feb 2 13:18:42 2012
@@ -1,0 +1,203 @@
+/*
+ * 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.driver.impl.util;
+
+/**
+ *
+ * @author Alvaro
+ */
+public enum Register305 {
+
+ CHANNEL_MASK((short) 0x00, false, "FFFF", true, true, false, false),
+ TRANSMIT_POWER_LEVEL((short) 0x01, false, "3", true, true, false, false),
+ PREFERRED_PAN_ID((short) 0x02, false, "0000", true, true, false, false),
+ PREFERRED_EXTENDED_PAN_ID((short) 0x03, false, "0000000000000000", true, true, false, false),
+ LOCAL_EUI((short) 0x04, false, "null", true, false, false, false),
+ LOCAL_NODEID((short) 0x05, false, "null", true, false, false, false),
+ PARENT_EUI((short) 0x06, false, "null", true, false, false, false),
+ PARENT_NODEID((short) 0x07, false, "null", true, false, false, false),
+ NETWORK_KEY((short) 0x08, true, "00000000000000000000000000000000", false, true, false, false),
+ TRUST_CENTRE_LINK_KEY((short) 0x09, true, "00000000000000000000000000000000", false, true, false, false),
+ MAIN_FUNCTION((short) 0x0A, true, "0000", true, true, false, false),
+ USER_READABLE_NAME((short) 0x0B, true, "Telegesis", true, true, false, false),
+ PASSWORD((short) 0x0C, true, "password", true, true, false, false),
+ DEVICE_INFORMATION((short) 0x0D, false, "null", true, false, false, false),
+ PROMPT_ENABLE_1((short) 0x0E, false, "0000", true, true, false, false),
+ PROMPT_ENABLE_2((short) 0x0F, false, "0006", true, true, false, false),
+ EXTENDED_FUNCTION((short) 0x10, false, "0000", true, true, false, false),
+ DEVICE_SPECIFIC((short) 0x11, false, "0005", true, true, false, false),
+ UART_SETUP((short) 0x12, false, "0500", true, true, false, false),
+ PULL_UP_ENABLE((short) 0x13, false, "0000", true, true, false, true),
+ PULL_DOWN_ENABLE((short) 0x14, false, "0000", true, true, false, true),
+ IO_CONFIGURATION((short) 0x15, false, "00000600", true, true, false, true),
+ DATA_DIRECTION_OF_IO_PORT((short) 0x16, false, "00F8", true, true, true, false),
+ INITIAL_VALUE_OF_S16((short) 0x17, false, "00F8", true, true, false, true),
+ OUTPUT_BUFFER_OF_IO_PORT((short) 0x18, false, "00F0", true, true, true, false),
+ INITIAL_VALUE_OF_S18((short) 0x19, false, "00F0", true, true, false, true),
+ INPUT_BUFFER_OF_IO_PORT((short) 0x1A, false, "null", true, false, true, false),
+ SPECIAL_FUNCTION_PIN_1((short) 0x1B, false, "3A98", true, true, true, false),
+ INITIAL_VALUE_OF_S1B((short) 0x1C, false, "3A98", true, true, false, true),
+ SPECIAL_FUNCTION_PIN_2((short) 0x1D, false, "1D4C", true, true, true, false),
+ INITIAL_VALUE_OF_S1D((short) 0x1E, false, "1D4C", true, true, false, true),
+ A_D1((short) 0x1F, false, "null", true, false, false, false),
+ A_D2((short) 0x20, false, "null", true, false, false, false),
+ A_D3((short) 0x21, false, "null", true, false, false, false),
+ A_D4((short) 0x22, false, "null", true, false, false, false),
+ IMMEDIATE_FUNCTIONALITY_AT_IRQ0((short) 0x23, false, "0001", true, true, false, false),
+ IMMEDIATE_FUNCTIONALITY_AT_IRQ1((short) 0x24, false, "0000", true, true, false, false),
+ IMMEDIATE_FUNCTIONALITY_AT_IRQ2((short) 0x25, false, "0000", true, true, false, false),
+ IMMEDIATE_FUNCTIONALITY_AT_IRQ3((short) 0x26, false, "0000", true, true, false, false),
+ FUNCTIONALITY_1_AT_BOOT_UP((short) 0x27, false, "0000", true, true, false, false),
+ FUNCTIONALITY_AT_NETWORK_JOIN((short) 0x28, false, "0000", true, true, false, false),
+ TIMER_COUNTER_0((short) 0x29, false, "0004", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_0((short) 0x2A, false, "8010", true, true, false, false),
+ TIMER_COUNTER_1((short) 0x2B, false, "00F0", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_1((short) 0x2C, false, "821E", true, true, false, false),
+ TIMER_COUNTER_2((short) 0x2D, false, "00F4", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_2((short) 0x2E, false, "8014", true, true, false, false),
+ TIMER_COUNTER_3((short) 0x2F, false, "00F2", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_3((short) 0x30, false, "8015", true, true, false, false),
+ TIMER_COUNTER_4((short) 0x31, false, "0000", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_4((short) 0x32, false, "0000", true, true, false, false),
+ TIMER_COUNTER_5((short) 0x33, false, "0000", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_5((short) 0x34, false, "0000", true, true, false, false),
+ TIMER_COUNTER_6((short) 0x35, false, "0000", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_6((short) 0x36, false, "0000", true, true, false, false),
+ TIMER_COUNTER_7((short) 0x37, false, "0000", true, true, false, false),
+ FUNCTIONALITY_FOR_TIMER_COUNTER_7((short) 0x38, false, "0000", true, true, false, false),
+ POWER_MODE((short) 0x39, false, "0000", true, true, true, false),
+ INITIAL_POWER_MODE((short) 0x3A, false, "0000", true, true, false, true),
+ START_UP_FUNCTIONALITY_PLAINTEXT_A((short) 0x3B, false, "BUTTON3", true, true, false, false),
+ START_UP_FUNCTIONALITY_PLAINTEXT_B((short) 0x3C, false, "BUTTON4", true, true, false, false),
+ SUPPLY_VOLTAGE((short) 0x3D, false, "null", true, false, false, false),
+ MULTICAST_TABLE_ENTRY_00((short) 0x3E, false, "0000", true, true, false, false),
+ MULTICAST_TABLE_ENTRY_01((short) 0x3F, false, "0000", true, true, false, false),
+ SOURCE_AND_DESTINATION_ENDPOINTS_FOR_XCASTS((short) 0x40, false, "0101", true, true, true, false),
+ INITIAL_VALUE_OF_S40((short) 0x41, false, "0101", true, true, false, true),
+ CLUSTER_ID_FOR_XCASTS((short) 0x42, false, "0002", true, true, true, false),
+ INITIAL_VALUE_OF_S42((short) 0x43, false, "0002", true, true, false, true),
+ PROFILE_ID_FOR_XCASTS((short) 0x44, false, "C091", true, true, true, false),
+ INITIAL_VALUE_OF_S44((short) 0x45, false, "C091", true, true, false, true),
+ START_UP_FUNCTIONALITY_32_BIT_NUMBER((short) 0x46, false, "00000000", true, true, true, false),
+ POWER_DESCRIPTOR((short) 0x47, false, "C110", true, true, false, false),
+ ENDPOINT_2_PROFILE_ID((short) 0x48, false, "C091", true, true, false, false),
+ ENDPOINT_2_DEVICE_ID((short) 0x49, false, "0000", true, true, false, false),
+ ENDPOINT_2_DEVICE_VERSION((short) 0x4A, false, "0000", true, true, false, false),
+ ENDPOINT_2_INPUT_CLUSTER_LIST((short) 0x4B, false, "0000", true, true, false, false),
+ ENDPOINT_2_OUTPUT_CLUSTER_LIST((short) 0x4C, false, "0000", true, true, false, false),
+ MOBILE_END_DEVICE_POLL_TIMEOUT((short) 0x4D, false, "0014", true, true, false, true),
+ END_DEVICE_POLL_TIMEOUT((short) 0x4E, false, "0605", true, true, false, true),
+ MAC_TIMEOUT((short) 0x4F, false, "0BB8", true, true, false, true);
+ private final short address;
+ private final boolean password;
+ private final String defaultValue;
+ private final boolean writable;
+ private final boolean readable;
+ private final boolean volatil;
+ private final boolean reset;
+
+ /**
+ *
+ * @param address
+ * @param password
+ * @param defaultValue
+ * @param writable
+ * @param readable
+ * @param volatil
+ * @param reset
+ */
+ Register305(short address, boolean password, String defaultValue, boolean writable, boolean readable, boolean volatil, boolean reset) {
+ this.address = address;
+ this.password = password;
+ this.defaultValue = defaultValue;
+ this.writable = writable;
+ this.readable = readable;
+ this.volatil = volatil;
+ this.reset = reset;
+ }
+
+ /**
+ * Recupera la dirección asociada al registro
+ * @return
+ */
+ public short getAddress() {
+ return address;
+ }
+
+ /**
+ * Indica si el registro está protegido por contraseña
+ * @return
+ */
+ public boolean requiresPassword() {
+ return password;
+ }
+
+ /**
+ * Devuelve el valor por defecto del registro
+ * @return Valor, o null si no procede
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * Indica si el registro se puede escribir
+ * @return
+ */
+ public boolean isWritable() {
+ return writable;
+ }
+
+ /**
+ * Indica si el registro se puede leer
+ * @return
+ */
+ public boolean isReadable() {
+ return readable;
+ }
+
+ /**
+ * Indica si el valor del registro se pierde al hacer un reset
+ * @return
+ */
+ public boolean isVolatile() {
+ return volatil;
+ }
+ /**
+ * Indica si se requiere un reset para que el valor se actualice
+ * @return
+ */
+ public boolean requiresReset() {
+ return reset;
+ }
+
+ /**
+ * Devuelve el valor correspondiente a la dirección proporcionada
+ * @param address dirección del registro
+ * @return
+ */
+ public static Register305 fromByte(short address){
+ Register305[] regs = Register305.values();
+ // recorremos todos los posibles valores
+ for (int i = 0; i < regs.length; i ++){
+ if (regs[i].getAddress() == address){
+ return regs[i];
+ }
+ }
+ return null;
+ }
+}
Added: projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/LICENSE
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/LICENSE (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/LICENSE Thu Feb 2 13:18:42 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-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/driver/es.unizar.howlab.core.zigbee.telegesis.driver.xml
==============================================================================
--- projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/driver/es.unizar.howlab.core.zigbee.telegesis.driver.xml (added)
+++ projects/zb4osgi/sandbox/howlab/telegesis-driver-impl/src/main/resources/es/unizar/howlab/core/zigbee/telegesis/driver/es.unizar.howlab.core.zigbee.telegesis.driver.xml Thu Feb 2 13:18:42 2012
@@ -1,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Document : config.xml
+ Created on : 11 de agosto de 2011, 17:35
+ Author : alvaro
+ Description:
+ Purpose of the document follows.
+
+-->
+
+<root>
+ <es.unizar.howlab.core.zigbee.telegesis.driver>
+ <autostart>true</autostart><!-- Arranca el driver al crearlo -->
+
+ <ack_timeout>3000</ack_timeout><!-- Timeout para respuestas ACK -->
+ <register_read_timeout>3000</register_read_timeout><!-- Timeout para respuestas register_read -->
+ <register_write_timeout>3000</register_write_timeout><!-- Timeout para respuestas regiter_write -->
+ <zdo_response_timeout>3000</zdo_response_timeout><!-- Timeout para respuestas ZDO (ep_list, ep_descriptor) -->
+ <neighbour_response_timeout>10000</neighbour_response_timeout><!-- Timeout para respuestas de tabla de vecinos -->
+
+ <check_zigbee_error>true</check_zigbee_error><!-- Comprueba los errores zigbee -->
+
+ <check_zigbee_error_frame_delay>10</check_zigbee_error_frame_delay><!-- Tiempo de separación entre nodos para comprobacion de errores -->
+ <check_zigbee_error_maintenance_period>5</check_zigbee_error_maintenance_period><!-- Periodo para reintentar las comprobaciones de errores fallidas -->
+ <check_zigbee_error_recovery_period>1</check_zigbee_error_recovery_period><!-- Periodo para ejecutar la comprobación de errores en los nodos-->
+ <zigbee_error_level_threshold_1>2</zigbee_error_level_threshold_1><!-- Umbral de error para intentar recuperacion del nodo -->
+ <zigbee_error_level_threshold_2>3</zigbee_error_level_threshold_2><!-- Umbral de error para remover el nodo -->
+
+
+ <get_neighbours>true</get_neighbours><!-- Incluye la busqueda de vecinos en las tareas periódicas -->
+ <get_neighbours_frame_delay>5</get_neighbours_frame_delay><!-- Tiempo de separación entre nodos para busqueda de vecinos -->
+ <get_neighbours_recovery_period>5</get_neighbours_recovery_period> <!-- Periodo para reintentar las busquedas de vecinos fallidas -->
+ <get_neighbours_maintenance_period>60</get_neighbours_maintenance_period><!-- Periodo para actualizar los vecinos de los nodos -->
+
+ <get_parent>true</get_parent><!-- Incluye la busqueda del padre en las tareas periódicas -->
+ <get_parent_frame_delay>5</get_parent_frame_delay><!-- Tiempo de separación entre nodos para busqueda de padre -->
+ <get_parent_recovery_period>5</get_parent_recovery_period> <!-- Periodo para reintentar las busquedas de padres fallidas -->
+ <get_parent_maintenance_period>60</get_parent_maintenance_period><!-- Periodo para actualizar los padres de los nodos -->
+
+ <get_zigbee_devices>true</get_zigbee_devices><!-- Incluye la busqueda de endpoints en las tareas peiódicas -->
+ <get_zigbee_devices_frame_delay>5</get_zigbee_devices_frame_delay><!-- Tiempo de separación entre nodos para busqueda de endpoints -->
+ <get_zigbee_devices_recovery_period>5</get_zigbee_devices_recovery_period><!-- Periodo para reintentar las busquedas de endpoints fallidas -->
+
+ <update_dongle_s_registers>false</update_dongle_s_registers><!-- Actualiza la configuracion del dongle al conectarlo -->
+ <update_node_s_registers>false</update_node_s_registers><!-- Actualiza la configuracion de los nodos al detectarlos -->
+ <update_node_s_registers_frame_delay>5</update_node_s_registers_frame_delay><!-- Tiempo de separación entre nodos para escritura de registros -->
+ <update_node_s_registers_recovery_period>5</update_node_s_registers_recovery_period><!-- Periodo para reintentar las escrituras de registros fallidas -->
+
+ <s_register_password>Tormenta</s_register_password><!-- Contraseña para registros protegidos contra escritura -->
+ <s_reg_xcast_source_ep>02</s_reg_xcast_source_ep><!-- End point para mensajes enviados por el ZDO -->
+ <node_registers>
+ <address>dongle</address> <!-- Registros a escribir en el dongle -->
+ <s_registers>
+ <s_register>
+ <address>00</address>
+ <value>3FFC</value>
+ </s_register>
+ <s_register>
+ <address>02</address><!-- PID -->
+ <value>1234</value>
+ </s_register>
+ <s_register>
+ <address>09</address>
+ <value>00123400000000000000000000000000</value>
+ </s_register>
+ <s_register>
+ <address>0A</address>
+ <value>001C</value>
+ </s_register>
+ <s_register>
+ <address>0B</address>
+ <value>COO_test1</value>
+ </s_register>
+ <s_register>
+ <address>10</address>
+ <value>159A</value>
+ </s_register>
+ <s_register>
+ <address>4E</address>
+ <value>0AE1</value>
+ </s_register>
+ <s_register>
+ <address>4F</address>
+ <value>FFFF</value>
+ </s_register>
+ <s_register>
+ <address>0E</address>
+ <value>8000</value>
+ </s_register>
+ <s_register>
+ <address>0F</address>
+ <value>0006</value>
+ </s_register>
+ <s_register>
+ <address>11</address>
+ <value>0300</value>
+ </s_register>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+ <node_registers> <!-- Registros a escribir en el nodo "0011223344556677" -->
+ <address>0011223344556677</address>
+ <s_registers>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+ <node_registers> <!-- Registros a escribir en el nodo "8899aabbccddeeff" -->
+ <address>8899aabbccddeeff</address>
+ <s_registers>
+ <s_register>
+ <address>12</address>
+ <value>0C10</value>
+ </s_register>
+ </s_registers>
+ </node_registers>
+
+ </es.unizar.howlab.core.zigbee.telegesis.driver>
+
+</root>
More information about the Commit
mailing list