From afd694f05178c22b4f71f65143c4647ce912d980 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 26 Jul 2015 18:06:29 +0200 Subject: o Much improved Debug class. - Inlining all definitions to make everything shorter and easier to read. - More const so even more can be inlined. o Adding some support for ATTiny85, still more work to be done. o Removing two unused battery characteristics. o Dynamically adding battery and temperature characteristics if their pipes are defined. --- Debug.h | 173 +++++++++++++++++--------------------------- Makefile | 11 +-- app.cpp | 6 ++ config-check.h | 19 +++++ services.h | 145 +++++++++++++++++++++++-------------- services_lock.h | 145 +++++++++++++++++++++++-------------- trygvisio_soil_moisture.ino | 49 ++++++------- trygvisio_soil_moisture.xml | 44 ----------- ublue_setup.gen.out.txt | 75 +++++++++---------- 9 files changed, 334 insertions(+), 333 deletions(-) diff --git a/Debug.h b/Debug.h index 4485afd..a70a144 100644 --- a/Debug.h +++ b/Debug.h @@ -12,138 +12,99 @@ enum DebugSink { template class Debug { public: - inline void begin(unsigned int baud_rate); + inline void begin(const long baud_rate) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.begin(baud_rate); + } + } + + inline bool operator!() const { + return !available(); + }; - inline operator bool(); + inline bool available() const { + if (sink == DEBUG_SINK_SERIAL) { + return Serial.available(); + } - inline bool available(); + return false; + }; - size_t write(uint8_t); + size_t write(uint8_t value) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.write(value); + } + + return value; + } template inline - void print(T t, int format = DEC); + void print(T t, int format = DEC) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.print(t, format); + } + }; + template inline - void print(const char *t); + void print(const T *t) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.print(t); + } + }; + template inline - void print(const __FlashStringHelper *t); + void print(T *t) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.print(t); + } + }; template inline - void println(T t, int format = DEC); + void println(T t, int format = DEC) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.println(t, format); + } + }; template inline - void println(const T *t); + void println(const T *t) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.println(t); + } + }; + template inline - void println(const __FlashStringHelper *t); + void println(T *t) const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.println(t); + } + }; inline - void println(); + void println() const { + if (sink == DEBUG_SINK_SERIAL) { + Serial.println(); + } + }; inline - void flush(); + void flush() { + if (sink == DEBUG_SINK_SERIAL) { + Serial.flush(); + } + }; }; -template -inline void Debug::begin(unsigned int baud_rate) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.begin(baud_rate); - } -} - -template -inline Debug::operator bool() { - if (sink == DEBUG_SINK_SERIAL) { - return Serial; - } - - return false; -} - -template -inline bool Debug::available() { - if (sink == DEBUG_SINK_SERIAL) { - return Serial.available(); - } - - return false; -} - -template -inline size_t Debug::write(uint8_t value) { - if (sink == DEBUG_SINK_SERIAL) { - return Serial.write(value); - } - - return 0; -} - -template -template -inline -void Debug::print(T t, int format) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.print(t, format); - } -} - -template -inline -void Debug::print(const char *t) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.print(t); - } -} -template -inline -void Debug::print(const __FlashStringHelper *t) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.print(t); - } -} - -template -template -inline -void Debug::println(T t, int format) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.println(t, format); - } -} - -template -template -inline -void Debug::println(const T *t) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.println(t); - } -} - -template -inline -void Debug::println(const __FlashStringHelper *t) { - if (sink == DEBUG_SINK_SERIAL) { - Serial.println(t); - } -} - -template -inline -void Debug::println() { - if (sink == DEBUG_SINK_SERIAL) { - Serial.println(); - } -} - #if DEBUG_SINK == 1 -static Debug debug; +static const Debug debug; #elif DEBUG_SINK == 2 -static Debug debug; +static const Debug debug; #else #error Invalid value for DEBUG_SINK, must be one of 1 (for no output), 2 for serial port // , or 3 for software serial. diff --git a/Makefile b/Makefile index 9445351..f96b9db 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,11 @@ -BOARD_TAG = leonardo -#BOARD_TAG = blendmicro16 +BOARDS_TXT = ../hardware/blend/avr/boards.txt +ARDUINO_VAR_PATH = ../hardware/blend/avr/variants +BOARD_TAG = blendmicro16 #DEVICE_PORT = /dev/ttyACM0 -MONITOR_BAUDRATE = 115200 -MONITOR_PORT ?= /dev/ttyACM0 +MONITOR_BAUDRATE = 115200 +MONITOR_PORT ?= $(shell ls /dev/ttyACM* | head -n 1) -ARDUINO_LIBS = BLE SPI EEPROM +ARDUINO_LIBS = BLE SPI EEPROM Low-Power AltSoftSerial ifdef CONFIG_MK include $(CONFIG_MK) diff --git a/app.cpp b/app.cpp index aef96d7..30160dc 100644 --- a/app.cpp +++ b/app.cpp @@ -2,12 +2,16 @@ #include "Debug.h" #include "config-check.h" +#ifdef PERSISTENT_CONFIGURATION_SUPPORT #include +#endif #if SM_BOARD_VERSION == 1 #define SENSOR_COUNT 2 #elif SM_BOARD_VERSION == 2 #define SENSOR_COUNT 4 +#elif SM_BOARD_VERSION == 3 +#define SENSOR_COUNT 1 #else #error "SM_BOARD_VERSION must be set to a valid value. See config-check.h" #endif @@ -37,6 +41,8 @@ struct sm_sensor { { A1, 3, 5, 0, 200, 3000, 4, "woot"}, { A2, 8, 10, 0, 200, 3000, 3, "foo"}, { A3, 11, 12, 0, 200, 3000, 3, "bar"}, +#elif SM_BOARD_VERSION == 3 + { A0, 1, 2, 0, 200, 3000, 3, "0"}, #endif }; diff --git a/config-check.h b/config-check.h index f259706..45f1af0 100644 --- a/config-check.h +++ b/config-check.h @@ -35,6 +35,7 @@ * Values: * 1: prototype-a, the hand assembled PCB * 2: prototype-b, the china produced PCB + * 3: attiny85 * * No default, has to be specified in config.h */ @@ -107,4 +108,22 @@ #define DEBUG_SINK 2 #endif +/******************************************************************************* + * Board specific sanity checks + */ + +#ifdef __AVR_ATtiny85__ + +#ifdef PERSISTENT_CONFIGURATION_SUPPORT +#warning PERSISTENT_CONFIGURATION_SUPPORT is not implemented for ATtiny85-based boards +#undef PERSISTENT_CONFIGURATION_SUPPORT +#endif + +#ifdef USE_LOW_POWER_MODE +#warning USE_LOW_POWER_MODE is not implemented for ATtiny85-based boards. +#undef USE_LOW_POWER_MODE +#endif + +#endif // __AVR_ATtiny85__ + #endif diff --git a/services.h b/services.h index 94efd74..b2b1853 100644 --- a/services.h +++ b/services.h @@ -11,7 +11,7 @@ #define SETUP_ID 0 #define SETUP_FORMAT 3 /** nRF8001 D */ -#define ACI_DYNAMIC_DATA_SIZE 180 +#define ACI_DYNAMIC_DATA_SIZE 166 /* Service: Gap - Characteristic: Device name - Pipe: SET */ #define PIPE_GAP_DEVICE_NAME_SET 1 @@ -21,40 +21,30 @@ #define PIPE_BATTERY_BATTERY_LEVEL_SET 2 #define PIPE_BATTERY_BATTERY_LEVEL_SET_MAX_SIZE 1 -/* Service: Battery - Characteristic: Battery Power State - Pipe: SET */ -#define PIPE_BATTERY_BATTERY_POWER_STATE_SET 3 -#define PIPE_BATTERY_BATTERY_POWER_STATE_SET_MAX_SIZE 1 - -/* Service: Battery - Characteristic: Battery Level State - Pipe: SET */ -#define PIPE_BATTERY_BATTERY_LEVEL_STATE_SET 4 -#define PIPE_BATTERY_BATTERY_LEVEL_STATE_SET_MAX_SIZE 2 - /* Service: Soil Moisture - Characteristic: Soil Moisture Control - Pipe: TX */ -#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX 5 +#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX 3 #define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX_MAX_SIZE 20 /* Service: Soil Moisture - Characteristic: Soil Moisture Control - Pipe: SET */ -#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET 6 +#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET 4 #define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET_MAX_SIZE 20 /* Service: Soil Moisture - Characteristic: Soil Moisture Control - Pipe: RX_ACK_AUTO */ -#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_RX_ACK_AUTO 7 +#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_RX_ACK_AUTO 5 #define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_RX_ACK_AUTO_MAX_SIZE 20 /* Service: Soil Moisture - Characteristic: Intermediate Temperature - Pipe: TX */ -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX 8 -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX_MAX_SIZE 10 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX 6 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX_MAX_SIZE 5 /* Service: Soil Moisture - Characteristic: Intermediate Temperature - Pipe: SET */ -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET 9 -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET_MAX_SIZE 10 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET 7 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET_MAX_SIZE 5 -#define NUMBER_OF_PIPES 9 +#define NUMBER_OF_PIPES 7 #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\ - {ACI_STORE_LOCAL, ACI_SET}, \ - {ACI_STORE_LOCAL, ACI_SET}, \ {ACI_STORE_LOCAL, ACI_SET}, \ {ACI_STORE_LOCAL, ACI_SET}, \ {ACI_STORE_LOCAL, ACI_TX}, \ @@ -69,7 +59,73 @@ #define GAP_PPCP_SLAVE_LATENCY 0 #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */ -#define NB_SETUP_MESSAGES 23 +/** @brief do a set_local_data for PIPE_GAP_DEVICE_NAME_SET + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 10 + * @details use this function to do a set_local_data for PIPE_GAP_DEVICE_NAME_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_gap_device_name(void *src, int size); + +/** @brief do a set_local_data for PIPE_BATTERY_BATTERY_LEVEL_SET + * @param src the value to send + * @details use this function to do a set_local_data for PIPE_BATTERY_BATTERY_LEVEL_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_battery_battery_level(uint8_t src); + +/** @brief send a new value for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 20 + * @param is_freshest_sample set it to true if you want to overwrite an eventual pending transaction on this pipe. + * @details use this function to send a new value for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX. If no transaction are currently + * running, the send will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. If a transaction on this pipe is already pending, then this function + * will not overwrite the data of the previous transaction and return false. + * @return : true if is_freshest_sample true, otherwise return false if a transaction on this pipe is already pending, true otherwise. + */ +bool services_send_soil_moisture_soil_moisture_control(void *src, int size, bool is_freshest_sample); + +/** @brief do a set_local_data for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 20 + * @details use this function to do a set_local_data for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_soil_moisture_soil_moisture_control(void *src, int size); + +/** @brief send a new value for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 5 + * @param is_freshest_sample set it to true if you want to overwrite an eventual pending transaction on this pipe. + * @details use this function to send a new value for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX. If no transaction are currently + * running, the send will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. If a transaction on this pipe is already pending, then this function + * will not overwrite the data of the previous transaction and return false. + * @return : true if is_freshest_sample true, otherwise return false if a transaction on this pipe is already pending, true otherwise. + */ +bool services_send_soil_moisture_intermediate_temperature(void *src, int size, bool is_freshest_sample); + +/** @brief do a set_local_data for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 5 + * @details use this function to do a set_local_data for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_soil_moisture_intermediate_temperature(void *src, int size); + +/** @brief function to trig pending transaction on pipes + * @details This function check for each pipe if it has a pending transaction (send/rx_request/ack) + * and if so executes this transaction. + * This function should be called in the APP_RUN state of the process function of the application. + */ +void services_update_pipes(void); + +#define NB_SETUP_MESSAGES 20 #define SETUP_MESSAGES_CONTENT {\ {0x00,\ {\ @@ -78,7 +134,7 @@ },\ {0x00,\ {\ - 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ + 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x07,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ 0xd1,0x0f,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ },\ },\ @@ -131,61 +187,43 @@ },\ {0x00,\ {\ - 0x1f,0x06,0x20,0x8c,0x00,0x0b,0x2a,0x19,0x01,0x10,0x04,0x04,0x05,0x05,0x00,0x0c,0x28,0x03,0x01,0x02,\ - 0x0d,0x00,0x1a,0x2a,0x06,0x04,0x02,0x01,0x00,0x0d,0x2a,0x1a,\ + 0x1f,0x06,0x20,0x8c,0x00,0x0b,0x2a,0x19,0x01,0x10,0x04,0x04,0x10,0x10,0x00,0x0c,0x28,0x00,0x01,0x3f,\ + 0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x10,\ },\ },\ {0x00,\ {\ - 0x1f,0x06,0x20,0xa8,0x01,0x00,0x04,0x04,0x05,0x05,0x00,0x0e,0x28,0x03,0x01,0x02,0x0f,0x00,0x1b,0x2a,\ - 0x06,0x04,0x03,0x02,0x00,0x0f,0x2a,0x1b,0x01,0x00,0x00,0x04,\ + 0x1f,0x06,0x20,0xa8,0x00,0xd0,0x32,0x04,0x04,0x13,0x13,0x00,0x0d,0x28,0x03,0x01,0x1a,0x0e,0x00,0x3f,\ + 0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x11,\ },\ },\ {0x00,\ {\ - 0x1f,0x06,0x20,0xc4,0x04,0x10,0x10,0x00,0x10,0x28,0x00,0x01,0x3f,0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,\ - 0xc5,0x59,0x5d,0x03,0x10,0x00,0xd0,0x32,0x04,0x04,0x13,0x13,\ - },\ - },\ - {0x00,\ - {\ - 0x1f,0x06,0x20,0xe0,0x00,0x11,0x28,0x03,0x01,0x1a,0x12,0x00,0x3f,0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,\ - 0xc5,0x59,0x5d,0x03,0x11,0x00,0xd0,0x32,0x54,0x14,0x14,0x00,\ - },\ - },\ - {0x00,\ - {\ - 0x1f,0x06,0x20,0xfc,0x00,0x12,0x00,0x11,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,0x03,\ + 0x1f,0x06,0x20,0xc4,0x00,0xd0,0x32,0x54,0x14,0x14,0x00,0x00,0x0e,0x00,0x11,0x02,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ },\ },\ {0x00,\ {\ - 0x1f,0x06,0x21,0x18,0x02,0x00,0x13,0x29,0x02,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,0x14,0x28,0x03,\ - 0x01,0x12,0x15,0x00,0x1e,0x2a,0x16,0x04,0x0b,0x0a,0x00,0x15,\ + 0x1f,0x06,0x20,0xe0,0x00,0x00,0x00,0x00,0x46,0x14,0x03,0x02,0x00,0x0f,0x29,0x02,0x01,0x00,0x00,0x04,\ + 0x04,0x05,0x05,0x00,0x10,0x28,0x03,0x01,0x12,0x11,0x00,0x1e,\ },\ },\ {0x00,\ {\ - 0x1c,0x06,0x21,0x34,0x2a,0x1e,0x01,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x99,0x88,0x77,0x66,0x46,0x14,0x03,\ - 0x02,0x00,0x16,0x29,0x02,0x01,0x00,0x00,0x00,\ + 0x1e,0x06,0x20,0xfc,0x2a,0x16,0x04,0x06,0x05,0x00,0x11,0x2a,0x1e,0x01,0x00,0x00,0x00,0x00,0x00,0x46,\ + 0x14,0x03,0x02,0x00,0x12,0x29,0x02,0x01,0x00,0x00,0x00,\ },\ },\ {0x00,\ {\ 0x1f,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,0x2a,0x19,0x01,0x00,0x80,0x04,\ - 0x00,0x0b,0x00,0x00,0x2a,0x1a,0x01,0x00,0x80,0x04,0x00,0x0d,\ - },\ - },\ - {0x00,\ - {\ - 0x1f,0x06,0x40,0x1c,0x00,0x00,0x2a,0x1b,0x01,0x00,0x80,0x04,0x00,0x0f,0x00,0x00,0x00,0x11,0x02,0x04,\ - 0x82,0x04,0x00,0x12,0x00,0x13,0x2a,0x1e,0x01,0x00,0x82,0x04,\ + 0x00,0x0b,0x00,0x00,0x00,0x11,0x02,0x04,0x82,0x04,0x00,0x0e,\ },\ },\ {0x00,\ {\ - 0x07,0x06,0x40,0x38,0x00,0x15,0x00,0x16,\ + 0x0f,0x06,0x40,0x1c,0x00,0x0f,0x2a,0x1e,0x01,0x00,0x82,0x04,0x00,0x11,0x00,0x12,\ },\ },\ {0x00,\ @@ -195,13 +233,12 @@ },\ {0x00,\ {\ - 0x15,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ - 0x00,0x00,\ + 0x0f,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ },\ },\ {0x00,\ {\ - 0x06,0x06,0xf0,0x00,0x03,0xb7,0x68,\ + 0x06,0x06,0xf0,0x00,0x03,0xb7,0x22,\ },\ },\ } diff --git a/services_lock.h b/services_lock.h index d3a271b..df5ee8d 100644 --- a/services_lock.h +++ b/services_lock.h @@ -15,7 +15,7 @@ #define SETUP_ID 0 #define SETUP_FORMAT 3 /** nRF8001 D */ -#define ACI_DYNAMIC_DATA_SIZE 180 +#define ACI_DYNAMIC_DATA_SIZE 166 /* Service: Gap - Characteristic: Device name - Pipe: SET */ #define PIPE_GAP_DEVICE_NAME_SET 1 @@ -25,40 +25,30 @@ #define PIPE_BATTERY_BATTERY_LEVEL_SET 2 #define PIPE_BATTERY_BATTERY_LEVEL_SET_MAX_SIZE 1 -/* Service: Battery - Characteristic: Battery Power State - Pipe: SET */ -#define PIPE_BATTERY_BATTERY_POWER_STATE_SET 3 -#define PIPE_BATTERY_BATTERY_POWER_STATE_SET_MAX_SIZE 1 - -/* Service: Battery - Characteristic: Battery Level State - Pipe: SET */ -#define PIPE_BATTERY_BATTERY_LEVEL_STATE_SET 4 -#define PIPE_BATTERY_BATTERY_LEVEL_STATE_SET_MAX_SIZE 2 - /* Service: Soil Moisture - Characteristic: Soil Moisture Control - Pipe: TX */ -#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX 5 +#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX 3 #define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX_MAX_SIZE 20 /* Service: Soil Moisture - Characteristic: Soil Moisture Control - Pipe: SET */ -#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET 6 +#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET 4 #define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET_MAX_SIZE 20 /* Service: Soil Moisture - Characteristic: Soil Moisture Control - Pipe: RX_ACK_AUTO */ -#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_RX_ACK_AUTO 7 +#define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_RX_ACK_AUTO 5 #define PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_RX_ACK_AUTO_MAX_SIZE 20 /* Service: Soil Moisture - Characteristic: Intermediate Temperature - Pipe: TX */ -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX 8 -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX_MAX_SIZE 10 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX 6 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX_MAX_SIZE 5 /* Service: Soil Moisture - Characteristic: Intermediate Temperature - Pipe: SET */ -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET 9 -#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET_MAX_SIZE 10 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET 7 +#define PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET_MAX_SIZE 5 -#define NUMBER_OF_PIPES 9 +#define NUMBER_OF_PIPES 7 #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\ - {ACI_STORE_LOCAL, ACI_SET}, \ - {ACI_STORE_LOCAL, ACI_SET}, \ {ACI_STORE_LOCAL, ACI_SET}, \ {ACI_STORE_LOCAL, ACI_SET}, \ {ACI_STORE_LOCAL, ACI_TX}, \ @@ -73,7 +63,73 @@ #define GAP_PPCP_SLAVE_LATENCY 0 #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */ -#define NB_SETUP_MESSAGES 23 +/** @brief do a set_local_data for PIPE_GAP_DEVICE_NAME_SET + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 10 + * @details use this function to do a set_local_data for PIPE_GAP_DEVICE_NAME_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_gap_device_name(void *src, int size); + +/** @brief do a set_local_data for PIPE_BATTERY_BATTERY_LEVEL_SET + * @param src the value to send + * @details use this function to do a set_local_data for PIPE_BATTERY_BATTERY_LEVEL_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_battery_battery_level(uint8_t src); + +/** @brief send a new value for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 20 + * @param is_freshest_sample set it to true if you want to overwrite an eventual pending transaction on this pipe. + * @details use this function to send a new value for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_TX. If no transaction are currently + * running, the send will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. If a transaction on this pipe is already pending, then this function + * will not overwrite the data of the previous transaction and return false. + * @return : true if is_freshest_sample true, otherwise return false if a transaction on this pipe is already pending, true otherwise. + */ +bool services_send_soil_moisture_soil_moisture_control(void *src, int size, bool is_freshest_sample); + +/** @brief do a set_local_data for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 20 + * @details use this function to do a set_local_data for PIPE_SOIL_MOISTURE_SOIL_MOISTURE_CONTROL_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_soil_moisture_soil_moisture_control(void *src, int size); + +/** @brief send a new value for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 5 + * @param is_freshest_sample set it to true if you want to overwrite an eventual pending transaction on this pipe. + * @details use this function to send a new value for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_TX. If no transaction are currently + * running, the send will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. If a transaction on this pipe is already pending, then this function + * will not overwrite the data of the previous transaction and return false. + * @return : true if is_freshest_sample true, otherwise return false if a transaction on this pipe is already pending, true otherwise. + */ +bool services_send_soil_moisture_intermediate_temperature(void *src, int size, bool is_freshest_sample); + +/** @brief do a set_local_data for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET + * @param src source buffer to send data from + * @param size the number of bytes to send. Maximum size is 5 + * @details use this function to do a set_local_data for PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET. If no transaction are currently + * running, the set will be immediate, otherwise, it will be done at the end of the current transaction + * when services_update_pipes will be called. + */ +void services_set_soil_moisture_intermediate_temperature(void *src, int size); + +/** @brief function to trig pending transaction on pipes + * @details This function check for each pipe if it has a pending transaction (send/rx_request/ack) + * and if so executes this transaction. + * This function should be called in the APP_RUN state of the process function of the application. + */ +void services_update_pipes(void); + +#define NB_SETUP_MESSAGES 20 #define SETUP_MESSAGES_CONTENT {\ {0x00,\ {\ @@ -82,7 +138,7 @@ },\ {0x00,\ {\ - 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ + 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x07,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ 0xd1,0x0f,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ },\ },\ @@ -135,61 +191,43 @@ },\ {0x00,\ {\ - 0x1f,0x06,0x20,0x8c,0x00,0x0b,0x2a,0x19,0x01,0x10,0x04,0x04,0x05,0x05,0x00,0x0c,0x28,0x03,0x01,0x02,\ - 0x0d,0x00,0x1a,0x2a,0x06,0x04,0x02,0x01,0x00,0x0d,0x2a,0x1a,\ + 0x1f,0x06,0x20,0x8c,0x00,0x0b,0x2a,0x19,0x01,0x10,0x04,0x04,0x10,0x10,0x00,0x0c,0x28,0x00,0x01,0x3f,\ + 0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x10,\ },\ },\ {0x00,\ {\ - 0x1f,0x06,0x20,0xa8,0x01,0x00,0x04,0x04,0x05,0x05,0x00,0x0e,0x28,0x03,0x01,0x02,0x0f,0x00,0x1b,0x2a,\ - 0x06,0x04,0x03,0x02,0x00,0x0f,0x2a,0x1b,0x01,0x00,0x00,0x04,\ + 0x1f,0x06,0x20,0xa8,0x00,0xd0,0x32,0x04,0x04,0x13,0x13,0x00,0x0d,0x28,0x03,0x01,0x1a,0x0e,0x00,0x3f,\ + 0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x11,\ },\ },\ {0x00,\ {\ - 0x1f,0x06,0x20,0xc4,0x04,0x10,0x10,0x00,0x10,0x28,0x00,0x01,0x3f,0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,\ - 0xc5,0x59,0x5d,0x03,0x10,0x00,0xd0,0x32,0x04,0x04,0x13,0x13,\ - },\ - },\ - {0x00,\ - {\ - 0x1f,0x06,0x20,0xe0,0x00,0x11,0x28,0x03,0x01,0x1a,0x12,0x00,0x3f,0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,\ - 0xc5,0x59,0x5d,0x03,0x11,0x00,0xd0,0x32,0x54,0x14,0x14,0x00,\ - },\ - },\ - {0x00,\ - {\ - 0x1f,0x06,0x20,0xfc,0x00,0x12,0x00,0x11,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,0x03,\ + 0x1f,0x06,0x20,0xc4,0x00,0xd0,0x32,0x54,0x14,0x14,0x00,0x00,0x0e,0x00,0x11,0x02,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ },\ },\ {0x00,\ {\ - 0x1f,0x06,0x21,0x18,0x02,0x00,0x13,0x29,0x02,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,0x14,0x28,0x03,\ - 0x01,0x12,0x15,0x00,0x1e,0x2a,0x16,0x04,0x0b,0x0a,0x00,0x15,\ + 0x1f,0x06,0x20,0xe0,0x00,0x00,0x00,0x00,0x46,0x14,0x03,0x02,0x00,0x0f,0x29,0x02,0x01,0x00,0x00,0x04,\ + 0x04,0x05,0x05,0x00,0x10,0x28,0x03,0x01,0x12,0x11,0x00,0x1e,\ },\ },\ {0x00,\ {\ - 0x1c,0x06,0x21,0x34,0x2a,0x1e,0x01,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x99,0x88,0x77,0x66,0x46,0x14,0x03,\ - 0x02,0x00,0x16,0x29,0x02,0x01,0x00,0x00,0x00,\ + 0x1e,0x06,0x20,0xfc,0x2a,0x16,0x04,0x06,0x05,0x00,0x11,0x2a,0x1e,0x01,0x00,0x00,0x00,0x00,0x00,0x46,\ + 0x14,0x03,0x02,0x00,0x12,0x29,0x02,0x01,0x00,0x00,0x00,\ },\ },\ {0x00,\ {\ 0x1f,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,0x2a,0x19,0x01,0x00,0x80,0x04,\ - 0x00,0x0b,0x00,0x00,0x2a,0x1a,0x01,0x00,0x80,0x04,0x00,0x0d,\ - },\ - },\ - {0x00,\ - {\ - 0x1f,0x06,0x40,0x1c,0x00,0x00,0x2a,0x1b,0x01,0x00,0x80,0x04,0x00,0x0f,0x00,0x00,0x00,0x11,0x02,0x04,\ - 0x82,0x04,0x00,0x12,0x00,0x13,0x2a,0x1e,0x01,0x00,0x82,0x04,\ + 0x00,0x0b,0x00,0x00,0x00,0x11,0x02,0x04,0x82,0x04,0x00,0x0e,\ },\ },\ {0x00,\ {\ - 0x07,0x06,0x40,0x38,0x00,0x15,0x00,0x16,\ + 0x0f,0x06,0x40,0x1c,0x00,0x0f,0x2a,0x1e,0x01,0x00,0x82,0x04,0x00,0x11,0x00,0x12,\ },\ },\ {0x00,\ @@ -199,13 +237,12 @@ },\ {0x00,\ {\ - 0x15,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ - 0x00,0x00,\ + 0x0f,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ },\ },\ {0x00,\ {\ - 0x06,0x06,0xf0,0x00,0x83,0x26,0xe0,\ + 0x06,0x06,0xf0,0x00,0x83,0x26,0xaa,\ },\ },\ } diff --git a/trygvisio_soil_moisture.ino b/trygvisio_soil_moisture.ino index c09f091..8ecc907 100644 --- a/trygvisio_soil_moisture.ino +++ b/trygvisio_soil_moisture.ino @@ -1,8 +1,12 @@ // See config.h on how to configure the sketch #include "config-check.h" +#ifdef USE_LOW_POWER_MODE #include +#endif +#ifdef PERSISTENT_CONFIGURATION_SUPPORT #include +#endif #include #include #include @@ -12,6 +16,14 @@ #include "app.h" #include "Debug.h" +#ifdef PIPE_SOIL_MOISTURE_INTERMEDIATE_TEMPERATURE_SET +#define USE_TEMPERATURE +#endif + +#ifdef PIPE_BATTERY_BATTERY_LEVEL_SET +#define USE_BATTERY +#endif + static void setup_rf(); static void show_pipes(); @@ -57,7 +69,7 @@ void setup() { CLKPR = 0; #endif - debug.begin((unsigned int)115200); + debug.begin(115200); #if WAIT_FOR_SERIAL_BEFORE_STARING // Wait until the serial port is available (useful only for the Leonardo) @@ -188,8 +200,9 @@ static void aci_loop() { // (uint8_t *)&(aci_evt->params.cmd_rsp.params.get_device_version), // sizeof(aci_evt_cmd_rsp_params_get_device_version_t)); } +#ifdef USE_TEMPERATURE if (aci_evt->params.cmd_rsp.cmd_opcode == ACI_CMD_GET_TEMPERATURE) { - debug.print("aci_evt->params.cmd_rsp.params.get_temperature="); + debug.print(F("aci_evt->params.cmd_rsp.params.get_temperature=")); debug.print(aci_evt->params.cmd_rsp.params.get_temperature.temperature_value, DEC); debug.println(); @@ -225,6 +238,7 @@ static void aci_loop() { (uint8_t *) &temperature_measurement, sizeof(temperature_measurement)); } +#endif // USE_TEMPERATURE break; case ACI_EVT_CONNECTED: @@ -238,8 +252,9 @@ static void aci_loop() { // This will trigger a ACI_CMD_GET_DEVICE_VERSION. lib_aci_device_version(); +#ifdef USE_TEMPERATURE lib_aci_get_temperature(); - +#endif sm_on_connect(); break; @@ -420,31 +435,8 @@ static void show_pipes() { debug.println(x, DEC); } } -/* - boolean tx_moisture(sm_res *res) { - static const uint8_t pipe = PIPE_SOIL_MOISTURE_SOIL_MOISTURE_LEVEL_TX; - uint8_t *data = (uint8_t *)res; - uint8_t len = 2 + res->len; - boolean status = false; - - boolean available = lib_aci_is_pipe_available(&aci_state, pipe); - - debug.print(F("tx_soil_moisture, len=")); - debug.println(len, DEC); - debug.print(F("aci_state.data_credit_available=")); - debug.println(aci_state.data_credit_available, DEC); - debug.print(F("available=")); - debug.println(available, DEC); - - if (available && aci_state.data_credit_available > 0) { - status = lib_aci_send_data(pipe, data, len); - if (status) { - aci_state.data_credit_available--; - } - } - return status; - } - */ + +#ifdef USE_BATTERY void notify_battery_level(uint8_t value) { static const uint8_t pipe = PIPE_BATTERY_BATTERY_LEVEL_SET; @@ -455,6 +447,7 @@ void notify_battery_level(uint8_t value) { lib_aci_send_data(pipe, &value, 1); } +#endif // USE_BATTERY void notify_soil_moisture(const struct sm_res &res, uint8_t body_len) { diff --git a/trygvisio_soil_moisture.xml b/trygvisio_soil_moisture.xml index 97aaba3..196cfb4 100644 --- a/trygvisio_soil_moisture.xml +++ b/trygvisio_soil_moisture.xml @@ -28,50 +28,6 @@ 0 - - Battery Power State - 2a1a - 0 - 0 - 1 - 1 - false - false - - false - false - false - false - false - - true - false - - 0 - - - - Battery Level State - 2a1b - 0 - 0 - 2 - 1 - false - false - - false - false - false - false - false - - true - false - - 0 - - Soil Moisture diff --git a/ublue_setup.gen.out.txt b/ublue_setup.gen.out.txt index 38d0450..dffc2b2 100644 --- a/ublue_setup.gen.out.txt +++ b/ublue_setup.gen.out.txt @@ -1,28 +1,28 @@ ------------------------------------------------------------------------------ uBlue Setup generation report Generated with uBlue setup DLL version: 1.0.0.16903 - Generated: Sun Jun 21 20:26:23 2015 (UTC) + Generated: Sun Jul 26 15:48:26 2015 (UTC) This file is automatically generated, do not modify ------------------------------------------------------------------------------ [Counts] -Setup data size = 612 bytes -Local database size = 333 bytes -Local attribute count = 6 +Setup data size = 520 bytes +Local database size = 279 bytes +Local attribute count = 4 Remote attribute count = 0 -Total pipe count = 9 -Dynamic data size = 180 bytes (worst case) +Total pipe count = 7 +Dynamic data size = 166 bytes (worst case) [Setup Area Layout] Setup area, total = 1595 bytes -Setup area, used = 427 bytes ( 26% of total ) -Local services = 333 bytes ( 77% of used ) +Setup area, used = 347 bytes ( 21% of total ) +Local services = 279 bytes ( 80% of used ) Remote services = 0 bytes ( 0% of used ) -Pipes = 60 bytes ( 14% of used ) -VS UUID area = 16 bytes ( 3% of used ) -Extended Attr area = 18 bytes ( 4% of used ) +Pipes = 40 bytes ( 11% of used ) +VS UUID area = 16 bytes ( 4% of used ) +Extended Attr area = 12 bytes ( 3% of used ) [Device Settings] @@ -71,17 +71,13 @@ Handle Pipes Structure 0x0009 +----- Service (Primary): "Battery" (01:0x180F) 0x000A |----- |Characteristic: "Batt Lev" (01:0x2A19) [rd] [rd:allow|wr:none] 0x000B x |Value: {0x10} [rd:allow|wr:none] -0x000C |----- |Characteristic: "?" (01:0x2A1A) [rd] [rd:allow|wr:none] -0x000D x |Value: {0x00} [rd:allow|wr:none] -0x000E |----- |Characteristic: "Batt Lev State" (01:0x2A1B) [rd] [rd:allow|wr:none] -0x000F x |Value: {0x00 0x00} [rd:allow|wr:none] -0x0010 +----- Service (Primary): "?" (02:0x0010) -0x0011 |----- |Characteristic: "?" (02:0x0011) [rd|wr|not] [rd:allow|wr:none] -0x0012 |Value: {} [rd:allow|wr:allow] -0x0013 |----- |Descriptor: "Client Characteristic Configuration" (01:0x2902) Value: {0x00 0x00} [rd:allow|wr:allow] -0x0014 |----- |Characteristic: "?" (01:0x2A1E) [rd|not] [rd:allow|wr:none] -0x0015 x> |Value: {0xAA 0xBB 0xCC 0xDD 0xEE 0xFF 0x99 0x88 0x77 0x66} [rd:allow|wr:none] -0x0016 |----- |Descriptor: "Client Characteristic Configuration" (01:0x2902) Value: {0x00 0x00} [rd:allow|wr:allow] +0x000C +----- Service (Primary): "?" (02:0x0010) +0x000D |----- |Characteristic: "?" (02:0x0011) [rd|wr|not] [rd:allow|wr:none] +0x000E |Value: {} [rd:allow|wr:allow] +0x000F |----- |Descriptor: "Client Characteristic Configuration" (01:0x2902) Value: {0x00 0x00} [rd:allow|wr:allow] +0x0010 |----- |Characteristic: "?" (01:0x2A1E) [rd|not] [rd:allow|wr:none] +0x0011 x> |Value: {0x00 0x00 0x00 0x00 0x00} [rd:allow|wr:none] +0x0012 |----- |Descriptor: "Client Characteristic Configuration" (01:0x2902) Value: {0x00 0x00} [rd:allow|wr:allow] [Remote Database] @@ -94,18 +90,16 @@ Pipe Store Type Service Char. CPF Desc. ---- ------ ------ ---------- --------- ----------- --------- 01 Local SET 01:0x1800 01:0x2A00 -- -- 02 Local SET 01:0x180F 01:0x2A19 -- -- -03 Local SET 01:0x180F 01:0x2A1A -- -- -04 Local SET 01:0x180F 01:0x2A1B -- -- -05 Local TX 02:0x0010 02:0x0011 -- -- -06 Local SET 02:0x0010 02:0x0011 -- -- -07 Local RX_AA 02:0x0010 02:0x0011 -- -- -08 Local TX 02:0x0010 01:0x2A1E -- -- -09 Local SET 02:0x0010 01:0x2A1E -- -- +03 Local TX 02:0x0010 02:0x0011 -- -- +04 Local SET 02:0x0010 02:0x0011 -- -- +05 Local RX_AA 02:0x0010 02:0x0011 -- -- +06 Local TX 02:0x0010 01:0x2A1E -- -- +07 Local SET 02:0x0010 01:0x2A1E -- -- [Setup Data] 07-06-00-00-03-02-42-07 -1F-06-10-00-00-00-00-00-00-00-06-00-09-01-01-00-00-06-00-01-D1-0F-18-00-00-00-00-00-00-00-00-00 +1F-06-10-00-00-00-00-00-00-00-04-00-07-01-01-00-00-06-00-01-D1-0F-18-00-00-00-00-00-00-00-00-00 1F-06-10-1C-10-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-50-03-90-01-FF 1F-06-10-38-FF-FF-02-58-0A-05-00-00-00-00-00-00-00-10-00-00-00-00-00-00-00-00-00-00-00-00-00-00 05-06-10-54-00-00 @@ -114,16 +108,13 @@ Pipe Store Type Service Char. CPF Desc. 1F-06-20-38-01-2A-06-04-03-02-00-05-2A-01-01-80-01-04-04-05-05-00-06-28-03-01-02-07-00-04-2A-06 1F-06-20-54-04-09-08-00-07-2A-04-01-FF-FF-FF-FF-00-00-FF-FF-04-04-02-02-00-08-28-00-01-01-18-04 1F-06-20-70-04-02-02-00-09-28-00-01-0F-18-04-04-05-05-00-0A-28-03-01-02-0B-00-19-2A-06-04-02-01 -1F-06-20-8C-00-0B-2A-19-01-10-04-04-05-05-00-0C-28-03-01-02-0D-00-1A-2A-06-04-02-01-00-0D-2A-1A -1F-06-20-A8-01-00-04-04-05-05-00-0E-28-03-01-02-0F-00-1B-2A-06-04-03-02-00-0F-2A-1B-01-00-00-04 -1F-06-20-C4-04-10-10-00-10-28-00-01-3F-D8-1F-4A-8E-BC-D3-70-C5-59-5D-03-10-00-D0-32-04-04-13-13 -1F-06-20-E0-00-11-28-03-01-1A-12-00-3F-D8-1F-4A-8E-BC-D3-70-C5-59-5D-03-11-00-D0-32-54-14-14-00 -1F-06-20-FC-00-12-00-11-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-46-14-03 -1F-06-21-18-02-00-13-29-02-01-00-00-04-04-05-05-00-14-28-03-01-12-15-00-1E-2A-16-04-0B-0A-00-15 -1C-06-21-34-2A-1E-01-AA-BB-CC-DD-EE-FF-99-88-77-66-46-14-03-02-00-16-29-02-01-00-00-00 -1F-06-40-00-2A-00-01-00-80-04-00-03-00-00-2A-19-01-00-80-04-00-0B-00-00-2A-1A-01-00-80-04-00-0D -1F-06-40-1C-00-00-2A-1B-01-00-80-04-00-0F-00-00-00-11-02-04-82-04-00-12-00-13-2A-1E-01-00-82-04 -07-06-40-38-00-15-00-16 +1F-06-20-8C-00-0B-2A-19-01-10-04-04-10-10-00-0C-28-00-01-3F-D8-1F-4A-8E-BC-D3-70-C5-59-5D-03-10 +1F-06-20-A8-00-D0-32-04-04-13-13-00-0D-28-03-01-1A-0E-00-3F-D8-1F-4A-8E-BC-D3-70-C5-59-5D-03-11 +1F-06-20-C4-00-D0-32-54-14-14-00-00-0E-00-11-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 +1F-06-20-E0-00-00-00-00-46-14-03-02-00-0F-29-02-01-00-00-04-04-05-05-00-10-28-03-01-12-11-00-1E +1E-06-20-FC-2A-16-04-06-05-00-11-2A-1E-01-00-00-00-00-00-46-14-03-02-00-12-29-02-01-00-00-00 +1F-06-40-00-2A-00-01-00-80-04-00-03-00-00-2A-19-01-00-80-04-00-0B-00-00-00-11-02-04-82-04-00-0E +0F-06-40-1C-00-0F-2A-1E-01-00-82-04-00-11-00-12 13-06-50-00-3F-D8-1F-4A-8E-BC-D3-70-C5-59-5D-03-00-00-D0-32 -15-06-60-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 -06-06-F0-00-83-26-E0 +0F-06-60-00-00-00-00-00-00-00-00-00-00-00-00-00 +06-06-F0-00-83-26-AA -- cgit v1.2.3