From ef30beccd53b38f4dfd4701a1e7fc5eed2e24479 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Thu, 9 Jun 2016 09:36:50 +0300 Subject: [PATCH 1/8] Added initial changes needed for using littleb in mraa Signed-off-by: Shiran Ben-Melech --- CMakeLists.txt | 1 + api/mraa/littleb.h | 320 ++++++++++++++++++++++++++++++++++ api/mraa/types.h | 1 + api/mraa/types.hpp | 1 + examples/python/hello_gpio.py | 7 +- include/firmata/firmata.h | 3 + include/firmata/firmata_ble.h | 61 +++++++ src/CMakeLists.txt | 6 +- src/firmata/CMakeLists.txt | 1 + src/firmata/firmata.c | 28 +++ src/firmata/firmata_ble.c | 93 ++++++++++ src/firmata/firmata_mraa.c | 11 ++ src/mraa.c | 13 ++ 13 files changed, 543 insertions(+), 3 deletions(-) create mode 100644 api/mraa/littleb.h create mode 100644 include/firmata/firmata_ble.h create mode 100644 src/firmata/firmata_ble.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b3910bb3..697f44f0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ option (BUILDSWIGNODE "Build swig node modules." ON) option (BUILDSWIGJAVA "Build Java API." OFF) option (USBPLAT "Detection USB platform." OFF) option (FIRMATA "Add Firmata support to mraa." OFF) +option (FIRMATABLE "Add littleb" OFF) option (ONEWIRE "Add Onewire support to mraa." ON) option (IMRAA "Add Imraa support to mraa." OFF) option (FTDI4222 "Build with FTDI FT4222 subplatform support." OFF) diff --git a/api/mraa/littleb.h b/api/mraa/littleb.h new file mode 100644 index 000000000..12591ece6 --- /dev/null +++ b/api/mraa/littleb.h @@ -0,0 +1,320 @@ +/* + * Author: Shiran Ben-Melech + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_LEN 256 +#define MAX_OBJECTS 256 + +static const char* BLUEZ_DEST = "org.bluez"; +static const char* BLUEZ_DEVICE = "org.bluez.Device1"; +static const char* BLUEZ_GATT_SERVICE = "org.bluez.GattService1"; +static const char* BLUEZ_GATT_CHARACTERISTICS = "org.bluez.GattCharacteristic1"; + +/** + * LB return codes + */ +typedef enum { + LB_SUCCESS = 0, /**< Expected response */ + LB_ERROR_FEATURE_NOT_IMPLEMENTED = 1, /**< Feature TODO */ + LB_ERROR_FEATURE_NOT_SUPPORTED = 2, /**< Feature not supported by HW */ + LB_ERROR_INVALID_DEVICE = 3, /**< Not a BL or BLE device */ + LB_ERROR_INVALID_BUS = 4, /**< sd bus invalid */ + LB_ERROR_NO_RESOURCES = 5, /**< No resource of that type avail */ + LB_ERROR_MEMEORY_ALLOCATION = 6, /**< Memory allocation fail */ + LB_ERROR_SD_BUS_CALL_FAIL = 7, /**< sd_bus call failure */ + + LB_ERROR_UNSPECIFIED = 99 /**< Unknown Error */ +} lb_result_t; + +typedef struct ble_characteristic { + const char* char_path; /**< device path under dbus */ + const char* uuid; /**< uuid of the characteristic. */ +} ble_char; + +typedef struct ble_service { + const char* service_path; /**< device path under dbus */ + const char* uuid; /**< uuid of the service. */ + bool primary; /**< is the service primary in the device */ + ble_char** characteristics; /**< list of the characteristics inside the service */ + int characteristics_size; /**< count of characteristics in the service */ +} ble_service; + +typedef struct bl_device { + const char* device_path; /**< device path under dbus */ + const char* address; /**< address of the bluetooth device */ + const char* name; /**< name of the bluetooth device */ + ble_service** services; /**< list of the service inside the device */ + int services_size; /**< count of services in the device */ +} bl_device; + + +typedef struct lb_context { + sd_bus* bus; /**< system bus to be used */ + bl_device** devices; /**< list of the devices found in a scan */ + int devices_size; /**< count of devices found*/ +} lb_context; + +typedef struct event_callback_pair { + const char* event; + sd_bus_message_handler_t* callback; +} event_pair; + + +/** + * Initialize littleb. + * + * Set event and event loop configuration + * + * @return Result of operation + */ +lb_result_t lb_init(); + +/** + * Destroy littleb + * + * @return Result of operation + */ +lb_result_t lb_destroy(); + +/** + * Create new littleb context to contain devices found + * + * @param ADD + * @return new lb_context or NULL if failed + */ +lb_context* lb_context_new(); + +/** + * Free littleb context created with lb_context_new + * + * @param lb_context to be freed + * @return Result of operation + */ +lb_result_t lb_context_free(lb_context* lb_ctx); + +/** + * Populate internal list of bl devices found in a scan of specified length + * + * @param lb_context to use + * @param seconds to perform device scan + * @return Result of operation + */ +lb_result_t lb_get_bl_devices(lb_context* lb_ctx, int seconds); + +/** + * Connect to a specific bluetooth device + * + * bl_device can be found by name, path or address using lb_get_device functions + * + * @param lb_context to use + * @param bl_device to connect to + * @return Result of operation + */ +lb_result_t lb_connect_device(lb_context* lb_ctx, bl_device* dev); + +/** + * Disconnect from a specific bluetooth device + * + * @param lb_context to use + * @param bl_device to disconnect from + * @return Result of operation + */ +lb_result_t lb_disconnect_device(lb_context* lb_ctx, bl_device* dev); + +/** + * Pair with specific bluetooth device + * + * @param lb_context to use + * @param bl_device to pair with + * @return Result of operation + */ +lb_result_t lb_pair_device(lb_context* lb_ctx, bl_device* dev); + +/** + * Cancel pairing with specific bluetooth device + * + * @param lb_context to use + * @param bl_device to cancel pair with + * @return Result of operation + */ +lb_result_t lb_unpair_device(lb_context* lb_ctx, bl_device* dev); + +/** + * Populate ble_char with characteristic found by using it's device path under dbus + * + * @param lb_context to use + * @param bl_dev to search the characteristic in + * @param characteristic_path to search for + * @param ble_char to populate with characteristic found + * @return Result of operation + */ +lb_result_t lb_get_ble_characteristic_by_characteristic_path(lb_context* lb_ctx, + bl_device* dev, + const char* characteristic_path, + ble_char** ble_characteristic_ret); + +/** + * Populate ble_char with characteristic found by using it's uuid + * + * @param lb_context to use + * @param bl_dev to search the characteristic in + * @param uuid to search for + * @param ble_char to populate with characteristic found + * @return Result of operation + */ +lb_result_t +lb_get_ble_characteristic_by_uuid(lb_context* lb_ctx, bl_device* dev, const char* uuid, ble_char** ble_characteristic_ret); + +/** + * Populate ble_service with service found by using it's device path under dbus + * + * @param lb_context to use + * @param bl_dev to search the service in + * @param service_path to search for + * @param ble_service to populate with service found + * @return Result of operation + */ +lb_result_t lb_get_ble_service_by_service_path(lb_context* lb_ctx, + bl_device* dev, + const char* service_path, + ble_service** ble_service_ret); + +/** + * Populate ble_service with service found by using it's uuid + * + * @param lb_context to use + * @param bl_dev to search the service in + * @param uuid to search for + * @param ble_service to populate with service found + * @return Result of operation + */ +lb_result_t lb_get_ble_service_by_uuid(lb_context* lb_ctx, bl_device* dev, const char* uuid, ble_service** ble_service_ret); + +/** + * Populate the BLE device with it's services + * + * @param lb_context to use + * @param bl_dev to scan services + * @return Result of operation + */ +lb_result_t lb_get_ble_device_services(lb_context* lb_ctx, bl_device* dev); + +/** + * Get bluetooth device by using it's device path under dbus + * + * @param lb_context to use + * @param device_path to search for + * @param bl_device_ret to populate with the found device + * @return Result of operation + */ +lb_result_t lb_get_device_by_device_path(lb_context* lb_ctx, const char* device_path, bl_device** bl_device_ret); + +/** + * Get bluetooth device by searching for specific name + * + * Will return the first found device with the name specified + * + * @param lb_context to use + * @param name to search for + * @param bl_device_ret to populate with the found device + * @return Result of operation + */ +lb_result_t lb_get_device_by_device_name(lb_context* lb_ctx, const char* name, bl_device** bl_device_ret); + +/** + * Get bluetooth device by searching for specific address + * + * @param lb_context to use + * @param address to search for + * @param bl_device_ret to populate with the found device + * @return Result of operation + */ +lb_result_t lb_get_device_by_device_address(lb_context* lb_ctx, const char* address, bl_device** bl_device_ret); + +/** + * Write to a specific BLE device characteristic using it's uuid + * + * @param lb_context to use + * @param dev BLE device to search the characteristic in + * @param uuid of the characteristic to write to + * @param size of the uint8 array to be written + * @param the array of byte buffer to write to the characteristic + * @return Result of operation + */ +lb_result_t +lb_write_to_characteristic(lb_context* lb_ctx, bl_device* dev, const char* uuid, int size, uint8_t* value); + +/** + * Read from a specific BLE device characteristic using it's uuid + * + * @param lb_context to use + * @param dev BLE device to search the characteristic in + * @param uuid of the characteristic to read from + * @param size of the uint8 array that was read + * @param the array of byte buffer that was read + * @return Result of operation + */ +lb_result_t +lb_read_from_characteristic(lb_context* lb_ctx, bl_device* dev, const char* uuid, size_t* size, uint8_t** result); + +/** + * Register a callback function for an event of characteristic value change + * + * @param lb_context to use + * @param dev BLE device to search the characteristic in + * @param uuid of the characteristic to read from + * @param callback function to be called when char value changed + * @param userdata to pass in the callback function + * @return Result of operation + */ +lb_result_t lb_register_characteristic_read_event(lb_context* lb_ctx, + bl_device* dev, + const char* uuid, + sd_bus_message_handler_t callback, + void* userdata); + +/** + * Special function to parse uart tx line buffer + * + * @param message sd_bus_message to prase the buffer array from + * @param result buffer to accommodate the result + * @param size of the buffer + * @return Result of operation + */ +lb_result_t lb_parse_uart_service_message(sd_bus_message* message, const void** result, size_t* size); +#ifdef __cplusplus +} +#endif diff --git a/api/mraa/types.h b/api/mraa/types.h index d588119f1..45852f312 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -56,6 +56,7 @@ typedef enum { // contains bit 9 so is subplatform MRAA_GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + MRAA_BLE_FIRMATA = 1281, /**< Firmata ble platform */ MRAA_NULL_PLATFORM = 98, /**< Platform with no capabilities that hosts a sub platform */ MRAA_UNKNOWN_PLATFORM = diff --git a/api/mraa/types.hpp b/api/mraa/types.hpp index a1c936f4f..eb19206a1 100644 --- a/api/mraa/types.hpp +++ b/api/mraa/types.hpp @@ -54,6 +54,7 @@ typedef enum { FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + BLE_FIRMATA = 1281, /**< Firmata ble platform */ NULL_PLATFORM = 98, UNKNOWN_PLATFORM = diff --git a/examples/python/hello_gpio.py b/examples/python/hello_gpio.py index 69ec0c756..8e41b5669 100644 --- a/examples/python/hello_gpio.py +++ b/examples/python/hello_gpio.py @@ -25,6 +25,9 @@ import mraa print (mraa.getVersion()) -x = mraa.Gpio(13) +mraa.addSubplatform(mraa.BLE_FIRMATA, "FIRMATA") +x = mraa.Gpio(13 + 512) x.dir(mraa.DIR_OUT) -x.write(1) +for i in range(100): + x.write(1) + x.write(0) diff --git a/include/firmata/firmata.h b/include/firmata/firmata.h index 72961cbd0..d532f9b15 100644 --- a/include/firmata/firmata.h +++ b/include/firmata/firmata.h @@ -25,6 +25,7 @@ #pragma once #include "uart.h" +#include "littleb.h" #define MODE_INPUT 0x00 #define MODE_OUTPUT 0x01 @@ -90,6 +91,7 @@ typedef struct s_pin { typedef struct s_firmata { mraa_uart_context uart; + lb_context* lb_ctx; t_pin pins[128]; int i2cmsg[256][256]; int parse_command_len; @@ -102,6 +104,7 @@ typedef struct s_firmata { } t_firmata; t_firmata* firmata_new(const char* name); +t_firmata* firmata_ble_new(const char* name); void firmata_initPins(t_firmata* firmata); int firmata_askFirmware(t_firmata* firmata); int firmata_pinMode(t_firmata* firmata, int pin, int mode); diff --git a/include/firmata/firmata_ble.h b/include/firmata/firmata_ble.h new file mode 100644 index 000000000..4b3a9194e --- /dev/null +++ b/include/firmata/firmata_ble.h @@ -0,0 +1,61 @@ +/* + * Author: Shiran Ben-Melech + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "mraa_internal.h" +#include "littleb.h" + +lb_result_t (*dl_lb_init)(); +lb_result_t (*dl_lb_destroy)(); +lb_context* (*dl_lb_context_new)(); +lb_result_t (*dl_lb_context_free)(lb_context*); +lb_result_t (*dl_lb_get_bl_devices)(lb_context*, int); +lb_result_t (*dl_lb_connect_device)(lb_context*, bl_device*); +lb_result_t (*dl_lb_disconnect_device)(lb_context*, bl_device*); +lb_result_t (*dl_lb_pair_device)(lb_context*, bl_device*); +lb_result_t (*dl_lb_unpair_device)(lb_context*, bl_device*); +lb_result_t (*dl_lb_get_ble_characteristic_by_characteristic_path)(lb_context*, bl_device*, const char*, ble_char**); +lb_result_t (*dl_lb_get_ble_characteristic_by_uuid)(lb_context*, bl_device*, const char*, ble_char**); +lb_result_t (*dl_lb_get_ble_service_by_service_path)(lb_context* lb_ctx, bl_device*, const char*, ble_service**); +lb_result_t (*dl_lb_get_ble_service_by_uuid)(lb_context*, bl_device*, const char*, ble_service**); +lb_result_t (*dl_lb_get_ble_device_services)(lb_context*, bl_device*); +lb_result_t (*dl_lb_get_device_by_device_path)(lb_context*, const char*, bl_device**); +lb_result_t (*dl_lb_get_device_by_device_name)(lb_context*, const char*, bl_device**); +lb_result_t (*dl_lb_get_device_by_device_address)(lb_context*, const char*, bl_device**); +lb_result_t (*dl_lb_write_to_characteristic)(lb_context*, bl_device*, const char*, int, uint8_t*); +lb_result_t (*dl_lb_read_from_characteristic)(lb_context*, bl_device*, const char*, size_t*, uint8_t**); +lb_result_t (*dl_lb_register_characteristic_read_event)(lb_context*,bl_device*, const char*, sd_bus_message_handler_t, void*); +lb_result_t (*dl_lb_parse_uart_service_message)(sd_bus_message*, const void**, size_t*); + +mraa_result_t mraa_firmata_ble_init(); +void* liblittleb_lib; + +#ifdef __cplusplus +} +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 675d897e3..3b6dbf372 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,10 @@ if (FIRMATA) add_subdirectory (firmata) endif () +if (FIRMATABLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFIRMATABLE=1") +endif () + if (ONEWIRE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DONEWIRE=1") add_subdirectory (uart_ow) @@ -208,7 +212,7 @@ if (BUILDSWIG) endif () add_library (mraa ${mraa_LIB_SRCS}) -target_link_libraries (mraa ${mraa_LIBS}) +target_link_libraries (mraa ${mraa_LIBS} dl) set_target_properties( mraa PROPERTIES diff --git a/src/firmata/CMakeLists.txt b/src/firmata/CMakeLists.txt index 8ebc4330f..5100236cc 100644 --- a/src/firmata/CMakeLists.txt +++ b/src/firmata/CMakeLists.txt @@ -3,6 +3,7 @@ if (FIRMATA) set (mraa_LIB_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO} ${PROJECT_SOURCE_DIR}/src/firmata/firmata.c ${PROJECT_SOURCE_DIR}/src/firmata/firmata_mraa.c + ${PROJECT_SOURCE_DIR}/src/firmata/firmata_ble.c PARENT_SCOPE ) endif () diff --git a/src/firmata/firmata.c b/src/firmata/firmata.c index 7da490f91..be29d7a5b 100644 --- a/src/firmata/firmata.c +++ b/src/firmata/firmata.c @@ -23,6 +23,7 @@ */ #include "firmata/firmata.h" +#include "firmata/firmata_ble.h" #include "mraa_internal.h" #include @@ -59,6 +60,33 @@ firmata_new(const char* name) return res; } +t_firmata* +firmata_ble_new(const char* name) +{ + t_firmata* res; + mraa_result_t ble_res = MRAA_ERROR_UNSPECIFIED; + + res = calloc(1, sizeof(t_firmata)); + if (!res) { + return NULL; + } + + ble_res = mraa_firmata_ble_init(); + res->lb_ctx = dl_lb_context_new(); + if (res->uart == NULL) { + syslog(LOG_ERR, "firmata: UART failed to setup"); + free(res); + return NULL; + } + + firmata_initPins(res); + + firmata_askFirmware(res); + syslog(LOG_INFO, "firmata: Device opened at: %s", name); + + return res; +} + void firmata_close(t_firmata* firmata) { diff --git a/src/firmata/firmata_ble.c b/src/firmata/firmata_ble.c new file mode 100644 index 000000000..76db26777 --- /dev/null +++ b/src/firmata/firmata_ble.c @@ -0,0 +1,93 @@ +/* + * Author: Shiran Ben-Melech + * Copyright (c) 2016 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "firmata.h" +#include "mraa_internal.h" +#include "firmata/firmata.h" +#include "firmata/firmata_ble.h" + +#define PLATFORM_NAME "FIRMATA_BLE" + +static mraa_boolean_t liblittleb_load_success = true; + +void * +mraa_firmata_ble_dlsym(const char *symbol) +{ + void *func = dlsym(liblittleb_lib, symbol); + if (func == NULL) { + syslog(LOG_ERR, "%s", dlerror()); + liblittleb_load_success = false; + } + return func; +} + + +mraa_result_t +mraa_firmata_ble_init() +{ + mraa_result_t mraaStatus = MRAA_ERROR_NO_RESOURCES; + + liblittleb_lib = dlopen("liblittleb.so", RTLD_LAZY); + if (!liblittleb_lib) { + syslog(LOG_WARNING, "liblittleb.so not found, skipping"); + return MRAA_ERROR_FEATURE_NOT_SUPPORTED; + } + + dl_lb_init = mraa_firmata_ble_dlsym("lb_init"); + dl_lb_destroy = mraa_firmata_ble_dlsym("lb_destroy"); + dl_lb_context_new = mraa_firmata_ble_dlsym("lb_context_new"); + dl_lb_context_free = mraa_firmata_ble_dlsym("lb_context_free"); + dl_lb_get_bl_devices = mraa_firmata_ble_dlsym("lb_get_bl_devices"); + dl_lb_connect_device = mraa_firmata_ble_dlsym("lb_connect_device"); + dl_lb_disconnect_device = mraa_firmata_ble_dlsym("lb_disconnect_device"); + dl_lb_pair_device = mraa_firmata_ble_dlsym("lb_pair_device"); + dl_lb_unpair_device = mraa_firmata_ble_dlsym("lb_unpair_device"); + dl_lb_get_ble_characteristic_by_characteristic_path = mraa_firmata_ble_dlsym("lb_get_ble_characteristic_by_characteristic_path"); + dl_lb_get_ble_characteristic_by_uuid = mraa_firmata_ble_dlsym("lb_get_ble_characteristic_by_uuid"); + dl_lb_get_ble_service_by_service_path = mraa_firmata_ble_dlsym("lb_get_ble_service_by_service_path"); + dl_lb_get_ble_service_by_uuid = mraa_firmata_ble_dlsym("lb_get_ble_service_by_uuid"); + dl_lb_get_ble_device_services = mraa_firmata_ble_dlsym("lb_get_ble_device_services"); + dl_lb_get_device_by_device_path = mraa_firmata_ble_dlsym("lb_get_device_by_device_path"); + dl_lb_get_device_by_device_name = mraa_firmata_ble_dlsym("lb_get_device_by_device_name"); + dl_lb_get_device_by_device_address = mraa_firmata_ble_dlsym("lb_get_device_by_device_address"); + dl_lb_write_to_characteristic = mraa_firmata_ble_dlsym("lb_write_to_characteristic"); + dl_lb_read_from_characteristic = mraa_firmata_ble_dlsym("lb_read_from_characteristic"); + dl_lb_register_characteristic_read_event = mraa_firmata_ble_dlsym("lb_register_characteristic_read_event"); + dl_lb_parse_uart_service_message = mraa_firmata_ble_dlsym("lb_parse_uart_service_message"); + + if (!liblittleb_load_success) { + syslog(LOG_ERR, "Failed to find all symbols for FTDI4222 support"); + goto init_exit; + } + + mraaStatus = MRAA_SUCCESS; + +init_exit: + if (mraaStatus == MRAA_SUCCESS) + syslog(LOG_NOTICE, "mraa_firmata_ble_init completed successfully\n"); + return mraaStatus; +} \ No newline at end of file diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index 25dd9f584..c76b1f6fd 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -35,6 +35,16 @@ static t_firmata* firmata_dev; static pthread_t thread_id; static volatile int isr_detected; +static inline +mraa_result_t +mraa_firmata_write_internal() +{ + //if (ble) + // blah + //blah + return MRAA_SUCCESS; +} + mraa_firmata_context mraa_firmata_init(int feature) { @@ -524,6 +534,7 @@ mraa_firmata_plat_init(const char* uart_dev) return NULL; } + firmata_ble_new("FIRMATA"); firmata_dev = firmata_new(uart_dev); if (firmata_dev == NULL) { syslog(LOG_WARNING, "firmata: Failed to open uart to Firmata dev on %s", uart_dev); diff --git a/src/mraa.c b/src/mraa.c index 867a45a04..f59e09203 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -1001,6 +1001,19 @@ mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev) syslog(LOG_NOTICE, "mraa: Failed to add firmata subplatform"); } #endif +#if defined(FIRMATABLE) + //by name & by address - two types + if (subplatformtype == MRAA_BLE_FIRMATA) { + if (plat->sub_platform != NULL) { + return MRAA_ERROR_INVALID_PARAMETER; + } + if (mraa_firmata_platform(plat, uart_dev) == MRAA_BLE_FIRMATA) { + syslog(LOG_NOTICE, "mraa: Added firmata subplatform"); + return MRAA_SUCCESS; + } + syslog(LOG_NOTICE, "mraa: Failed to add firmata subplatform"); + } +#endif return MRAA_ERROR_INVALID_PARAMETER; } From b01c8ae5a196990a22ed6cd28cde5b95bdf04aa7 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Fri, 10 Jun 2016 10:42:12 +0300 Subject: [PATCH 2/8] Added all basic functionality needed for connect write and read over ble Signed-off-by: Shiran Ben-Melech --- api/mraa/types.h | 35 +++---- api/mraa/types.hpp | 36 ++++---- examples/python/hello_gpio.py | 2 +- include/firmata/firmata.h | 7 +- include/firmata/firmata_ble.h | 4 +- include/firmata/firmata_mraa.h | 2 +- src/firmata/firmata.c | 162 ++++++++++++++++++++++++++++++--- src/firmata/firmata_ble.c | 2 +- src/firmata/firmata_mraa.c | 51 +++++------ src/mraa.c | 23 +++-- 10 files changed, 239 insertions(+), 85 deletions(-) diff --git a/api/mraa/types.h b/api/mraa/types.h index 45852f312..800593155 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -37,28 +37,29 @@ extern "C" { * MRAA supported platform types */ typedef enum { - MRAA_INTEL_GALILEO_GEN1 = 0, /**< The Generation 1 Galileo platform (RevD) */ - MRAA_INTEL_GALILEO_GEN2 = 1, /**< The Generation 2 Galileo platform (RevG/H) */ - MRAA_INTEL_EDISON_FAB_C = 2, /**< The Intel Edison (FAB C) */ - MRAA_INTEL_DE3815 = 3, /**< The Intel DE3815 Baytrail NUC */ - MRAA_INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ - MRAA_RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ - MRAA_BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ - MRAA_BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ - MRAA_INTEL_NUC5 = 8, /**< The Intel 5th generations Broadwell NUCs */ - MRAA_96BOARDS = 9, /**< Linaro 96boards */ - MRAA_INTEL_SOFIA_3GR = 10, /**< The Intel SoFIA 3GR */ - MRAA_INTEL_CHERRYHILLS = 11, /**< The Intel Braswell Cherryhills */ - MRAA_UP = 12, /**< The UP Board */ + MRAA_INTEL_GALILEO_GEN1 = 0, /**< The Generation 1 Galileo platform (RevD) */ + MRAA_INTEL_GALILEO_GEN2 = 1, /**< The Generation 2 Galileo platform (RevG/H) */ + MRAA_INTEL_EDISON_FAB_C = 2, /**< The Intel Edison (FAB C) */ + MRAA_INTEL_DE3815 = 3, /**< The Intel DE3815 Baytrail NUC */ + MRAA_INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ + MRAA_RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ + MRAA_BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ + MRAA_BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ + MRAA_INTEL_NUC5 = 8, /**< The Intel 5th generations Broadwell NUCs */ + MRAA_96BOARDS = 9, /**< Linaro 96boards */ + MRAA_INTEL_SOFIA_3GR = 10, /**< The Intel SoFIA 3GR */ + MRAA_INTEL_CHERRYHILLS = 11, /**< The Intel Braswell Cherryhills */ + MRAA_UP = 12, /**< The UP Board */ // USB platform extenders start at 256 - MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ + MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ // contains bit 9 so is subplatform - MRAA_GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ - MRAA_BLE_FIRMATA = 1281, /**< Firmata ble platform */ + MRAA_GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + MRAA_BLE_FIRMATA_BY_NAME = 1281, /**< Firmata ble platform by name */ + MRAA_BLE_FIRMATA_BY_ADDRESS = 1282, /**< Firmata ble platform by address*/ - MRAA_NULL_PLATFORM = 98, /**< Platform with no capabilities that hosts a sub platform */ + MRAA_NULL_PLATFORM = 98, /**< Platform with no capabilities that hosts a sub platform */ MRAA_UNKNOWN_PLATFORM = 99 /**< An unknown platform type, typically will load INTEL_GALILEO_GEN1 */ } mraa_platform_t; diff --git a/api/mraa/types.hpp b/api/mraa/types.hpp index eb19206a1..76240a0b4 100644 --- a/api/mraa/types.hpp +++ b/api/mraa/types.hpp @@ -38,23 +38,25 @@ namespace mraa * MRAA supported platform types */ typedef enum { - INTEL_GALILEO_GEN1 = 0, /**< The Generation 1 Galileo platform (RevD) */ - INTEL_GALILEO_GEN2 = 1, /**< The Generation 2 Galileo platform (RevG/H) */ - INTEL_EDISON_FAB_C = 2, /**< The Intel Edison (FAB C) */ - INTEL_DE3815 = 3, /**< The Intel DE3815 Baytrail NUC */ - INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ - RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ - BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ - BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ - INTEL_NUC5 = 8, /**< The Intel 5th generations Broadwell NUCs */ - A96BOARDS = 9, /**< Linaro 96boards, A prefix for 'ARM' since not allowed numerical */ - INTEL_SOFIA_3GR = 10, /**< The Intel SoFIA 3GR */ - INTEL_CHERRYHILLS = 11, /**< The Intel Braswell Cherryhills */ - - FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ - - GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ - BLE_FIRMATA = 1281, /**< Firmata ble platform */ + INTEL_GALILEO_GEN1 = 0, /**< The Generation 1 Galileo platform (RevD) */ + INTEL_GALILEO_GEN2 = 1, /**< The Generation 2 Galileo platform (RevG/H) */ + INTEL_EDISON_FAB_C = 2, /**< The Intel Edison (FAB C) */ + INTEL_DE3815 = 3, /**< The Intel DE3815 Baytrail NUC */ + INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ + RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ + BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ + BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ + INTEL_NUC5 = 8, /**< The Intel 5th generations Broadwell NUCs */ + A96BOARDS = 9, /**< Linaro 96boards, A prefix for 'ARM' since not allowed numerical */ + INTEL_SOFIA_3GR = 10, /**< The Intel SoFIA 3GR */ + INTEL_CHERRYHILLS = 11, /**< The Intel Braswell Cherryhills */ + + FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ + + GENERIC_FIRMATA = 1280, /**< Firmata uart platform/bridge */ + BLE_FIRMATA_BY_NAME = 1281, /**< Firmata ble platform by name */ + BLE_FIRMATA_BY_ADDRESS = 1282, /**< Firmata ble platform by address */ + NULL_PLATFORM = 98, UNKNOWN_PLATFORM = diff --git a/examples/python/hello_gpio.py b/examples/python/hello_gpio.py index 8e41b5669..aa718c7a0 100644 --- a/examples/python/hello_gpio.py +++ b/examples/python/hello_gpio.py @@ -25,7 +25,7 @@ import mraa print (mraa.getVersion()) -mraa.addSubplatform(mraa.BLE_FIRMATA, "FIRMATA") +mraa.addSubplatform(mraa.BLE_FIRMATA_BY_NAME, "FIRMATA") x = mraa.Gpio(13 + 512) x.dir(mraa.DIR_OUT) for i in range(100): diff --git a/include/firmata/firmata.h b/include/firmata/firmata.h index d532f9b15..73e0c35ee 100644 --- a/include/firmata/firmata.h +++ b/include/firmata/firmata.h @@ -25,7 +25,7 @@ #pragma once #include "uart.h" -#include "littleb.h" +#include "firmata_ble.h" #define MODE_INPUT 0x00 #define MODE_OUTPUT 0x01 @@ -92,6 +92,7 @@ typedef struct s_pin { typedef struct s_firmata { mraa_uart_context uart; lb_context* lb_ctx; + bl_device* bl_dev; t_pin pins[128]; int i2cmsg[256][256]; int parse_command_len; @@ -104,7 +105,7 @@ typedef struct s_firmata { } t_firmata; t_firmata* firmata_new(const char* name); -t_firmata* firmata_ble_new(const char* name); +t_firmata* firmata_ble_new(const char* name, mraa_platform_t type); void firmata_initPins(t_firmata* firmata); int firmata_askFirmware(t_firmata* firmata); int firmata_pinMode(t_firmata* firmata, int pin, int mode); @@ -112,6 +113,8 @@ int firmata_digitalWrite(t_firmata* firmata, int pin, int value); int firmata_analogWrite(t_firmata* firmata, int pin, int value); int firmata_analogRead(t_firmata* firmata, int pin); int firmata_pull(t_firmata* firmata); +int firmata_write_internal(t_firmata* firmata_dev, const char* buf, size_t len); void firmata_parse(t_firmata* firmata, const uint8_t* buf, int len); void firmata_endParse(t_firmata* firmata); void firmata_close(t_firmata* firmata); +void firmata_ble_close(t_firmata* firmata); diff --git a/include/firmata/firmata_ble.h b/include/firmata/firmata_ble.h index 4b3a9194e..ef8f1239c 100644 --- a/include/firmata/firmata_ble.h +++ b/include/firmata/firmata_ble.h @@ -31,6 +31,8 @@ extern "C" { #include "mraa_internal.h" #include "littleb.h" +void* liblittleb_lib; + lb_result_t (*dl_lb_init)(); lb_result_t (*dl_lb_destroy)(); lb_context* (*dl_lb_context_new)(); @@ -54,7 +56,7 @@ lb_result_t (*dl_lb_register_characteristic_read_event)(lb_context*,bl_device*, lb_result_t (*dl_lb_parse_uart_service_message)(sd_bus_message*, const void**, size_t*); mraa_result_t mraa_firmata_ble_init(); -void* liblittleb_lib; + #ifdef __cplusplus } diff --git a/include/firmata/firmata_mraa.h b/include/firmata/firmata_mraa.h index a80d73a32..527c2ea4b 100644 --- a/include/firmata/firmata_mraa.h +++ b/include/firmata/firmata_mraa.h @@ -30,7 +30,7 @@ extern "C" { #include "mraa_internal.h" -mraa_platform_t mraa_firmata_platform(mraa_board_t* board, const char* uart_dev); +mraa_platform_t mraa_firmata_platform(mraa_board_t* board, const char* uart_dev, mraa_platform_t type); #ifdef __cplusplus diff --git a/src/firmata/firmata.c b/src/firmata/firmata.c index be29d7a5b..5091a5733 100644 --- a/src/firmata/firmata.c +++ b/src/firmata/firmata.c @@ -30,6 +30,53 @@ #include #include +static int +test_callback(sd_bus_message* message, void* userdata, sd_bus_error* error) +{ + + int r, i; + size_t size = 0; + uint8_t* result = NULL; + t_firmata* firmata = (t_firmata*) userdata; + + + printf("callback called\n"); + + r = dl_lb_parse_uart_service_message(message, (const void**) &result, &size); + if (r < 0) { + fprintf(stderr, "ERROR: couldn't parse uart message\n"); + return LB_ERROR_UNSPECIFIED; + } + + printf("message is:\n"); + for (i = 0; i < size; i++) { + printf("%x ", result[i]); + } + printf("\n"); + + //firmata_parse(firmata, result, size); + + return LB_SUCCESS; +} + +inline +int +firmata_write_internal(t_firmata* firmata_dev, const char* buf, size_t len) +{ + lb_result_t res = LB_ERROR_UNSPECIFIED; + if (firmata_dev->uart != NULL) { + mraa_uart_write(firmata_dev->uart, buf, len); + } + else if (firmata_dev->lb_ctx != NULL) { + res = dl_lb_write_to_characteristic(firmata_dev->lb_ctx, firmata_dev->bl_dev, "6e400002-b5a3-f393-e0a9-e50e24dcca9e", len, (uint8_t*)buf); + if (res < 0) { + fprintf(stderr, "ERROR: lb_write_to_characteristic\n"); + return MRAA_ERROR_UNSPECIFIED; + } + } + return MRAA_SUCCESS; +} + t_firmata* firmata_new(const char* name) { @@ -61,10 +108,10 @@ firmata_new(const char* name) } t_firmata* -firmata_ble_new(const char* name) +firmata_ble_new(const char* name, mraa_platform_t type) { t_firmata* res; - mraa_result_t ble_res = MRAA_ERROR_UNSPECIFIED; + lb_result_t ble_res = LB_ERROR_UNSPECIFIED; res = calloc(1, sizeof(t_firmata)); if (!res) { @@ -72,13 +119,77 @@ firmata_ble_new(const char* name) } ble_res = mraa_firmata_ble_init(); - res->lb_ctx = dl_lb_context_new(); - if (res->uart == NULL) { - syslog(LOG_ERR, "firmata: UART failed to setup"); + if (ble_res < 0) { + syslog(LOG_ERR, "firmata: littleb failed to setup"); free(res); return NULL; } + ble_res = dl_lb_init(); + if (ble_res < 0) { + fprintf(stderr, "ERROR: lb_init\n"); + free(res); + return NULL; } + + res->lb_ctx = dl_lb_context_new(); + if (res->lb_ctx == NULL) { + fprintf(stderr, "ERROR: lb_context_new\n"); + free(res); + return NULL; + } + + ble_res = dl_lb_get_bl_devices(res->lb_ctx, 5); + if (ble_res < 0) { + fprintf(stderr, "ERROR: lb_get_bl_devices\n"); + firmata_ble_close(res); + } + + // search for our specific device named "FIRMATA" + res->bl_dev = NULL; + if (type == MRAA_BLE_FIRMATA_BY_NAME) { + ble_res = dl_lb_get_device_by_device_name(res->lb_ctx, name, &res->bl_dev); + } + else if (type == MRAA_BLE_FIRMATA_BY_ADDRESS) { + ble_res = dl_lb_get_device_by_device_address(res->lb_ctx, name, &res->bl_dev); + } + if (ble_res < 0) { + fprintf(stderr, "ERROR: Device FIRMATA not found\n"); + firmata_ble_close(res); + free(res); + return NULL; + } + + ble_res = dl_lb_connect_device(res->lb_ctx, res->bl_dev); + if (ble_res < 0) { + fprintf(stderr, "ERROR: lb_connect_device\n"); + firmata_ble_close(res); + free(res); + return NULL; + } + + // ble_res = lb_pair_device(res->lb_ctx, res->bl_dev); + // if (ble_res < 0) { + // fprintf(stderr, "ERROR: lb_pair_device\n"); + // free(res); + // return NULL; + //} + + ble_res = dl_lb_get_ble_device_services(res->lb_ctx, res->bl_dev); + if (ble_res < 0) { + fprintf(stderr, "ERROR: lb_get_ble_device_services\n"); + firmata_ble_close(res); + free(res); + return NULL; + } + + ble_res = dl_lb_register_characteristic_read_event(res->lb_ctx, res->bl_dev, + "6e400003-b5a3-f393-e0a9-e50e24dcca9e", test_callback, res); + if (ble_res < 0) { + fprintf(stderr, "ERROR: lb_register_characteristic_read_event\n"); + firmata_ble_close(res); + free(res); + return NULL; } + firmata_initPins(res); firmata_askFirmware(res); @@ -87,6 +198,33 @@ firmata_ble_new(const char* name) return res; } +void +firmata_ble_close(t_firmata* firmata) +{ + lb_result_t r = LB_ERROR_UNSPECIFIED; + + // r = lb_unpair_device(lb_ctx, firmata); + // if (r < 0) { + // fprintf(stderr, "ERROR: lb_unpair_device\n"); + // exit(r); + //} + + r = dl_lb_disconnect_device(firmata->lb_ctx, firmata->bl_dev); + if (r < 0) { + fprintf(stderr, "ERROR: lb_disconnect_device\n"); + } + + r = dl_lb_context_free(firmata->lb_ctx); + if (r < 0) { + fprintf(stderr, "ERROR: lb_context_free\n"); + } + + r = dl_lb_destroy(); + if (r < 0) { + fprintf(stderr, "ERROR: lb_destroy\n"); + } +} + void firmata_close(t_firmata* firmata) { @@ -217,7 +355,7 @@ firmata_endParse(t_firmata* firmata) buf[len++] = 1; } firmata->isReady = 1; - mraa_uart_write(firmata->uart, buf, len); + firmata_write_internal(firmata, buf, len); } else if (firmata->parse_buff[1] == FIRMATA_CAPABILITY_RESPONSE) { int pin, i, n; for (pin = 0; pin < 128; pin++) { @@ -245,7 +383,7 @@ firmata_endParse(t_firmata* firmata) buf[len++] = pin; buf[len++] = FIRMATA_END_SYSEX; } - mraa_uart_write(firmata->uart, buf, len); + firmata_write_internal(firmata, buf, len); } } else if (firmata->parse_buff[1] == FIRMATA_ANALOG_MAPPING_RESPONSE) { int pin = 0; @@ -318,7 +456,7 @@ firmata_askFirmware(t_firmata* firmata) buf[0] = FIRMATA_START_SYSEX; buf[1] = FIRMATA_REPORT_FIRMWARE; // read firmata name & version buf[2] = FIRMATA_END_SYSEX; - res = mraa_uart_write(firmata->uart, buf, 3); + res = firmata_write_internal(firmata, buf, 3); return (res); } @@ -332,7 +470,7 @@ firmata_pinMode(t_firmata* firmata, int pin, int mode) buff[0] = FIRMATA_SET_PIN_MODE; buff[1] = pin; buff[2] = mode; - res = mraa_uart_write(firmata->uart, buff, 3); + res = firmata_write_internal(firmata, buff, 3); return (res); } @@ -345,7 +483,7 @@ firmata_analogWrite(t_firmata* firmata, int pin, int value) buff[0] = 0xE0 | pin; buff[1] = value & 0x7F; buff[2] = (value >> 7) & 0x7F; - res = mraa_uart_write(firmata->uart, buff, 3); + res = firmata_write_internal(firmata, buff, 3); return (res); } @@ -357,7 +495,7 @@ firmata_analogRead(t_firmata *firmata, int pin) uint8_t buff[2]; buff[0] = FIRMATA_REPORT_ANALOG | pin; buff[1] = value; - res = mraa_uart_write(firmata->uart, buff, 2); + res = firmata_write_internal(firmata, buff, 2); return res; } @@ -384,6 +522,6 @@ firmata_digitalWrite(t_firmata* firmata, int pin, int value) buff[0] = FIRMATA_DIGITAL_MESSAGE | port_num; buff[1] = port_val & 0x7F; buff[2] = (port_val >> 7) & 0x7F; - res = mraa_uart_write(firmata->uart, buff, 3); + res = firmata_write_internal(firmata, buff, 3); return (res); } diff --git a/src/firmata/firmata_ble.c b/src/firmata/firmata_ble.c index 76db26777..23ab9e9ea 100644 --- a/src/firmata/firmata_ble.c +++ b/src/firmata/firmata_ble.c @@ -80,7 +80,7 @@ mraa_firmata_ble_init() dl_lb_parse_uart_service_message = mraa_firmata_ble_dlsym("lb_parse_uart_service_message"); if (!liblittleb_load_success) { - syslog(LOG_ERR, "Failed to find all symbols for FTDI4222 support"); + syslog(LOG_ERR, "Failed to find all symbols for littleb support"); goto init_exit; } diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index c76b1f6fd..8a4532f7d 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -35,16 +35,6 @@ static t_firmata* firmata_dev; static pthread_t thread_id; static volatile int isr_detected; -static inline -mraa_result_t -mraa_firmata_write_internal() -{ - //if (ble) - // blah - //blah - return MRAA_SUCCESS; -} - mraa_firmata_context mraa_firmata_init(int feature) { @@ -61,7 +51,7 @@ mraa_firmata_init(int feature) mraa_result_t mraa_firmata_write_sysex(mraa_firmata_context dev, char* msg, int length) { - return mraa_uart_write(firmata_dev->uart, msg, length); + return firmata_write_internal(firmata_dev, msg, length); } mraa_result_t @@ -107,7 +97,7 @@ mraa_firmata_i2c_init_bus_replace(mraa_i2c_context dev) buff[1] = FIRMATA_I2C_CONFIG; buff[2] = delay & 0xFF, (delay >> 8) & 0xFF; buff[3] = FIRMATA_END_SYSEX; - mraa_uart_write(firmata_dev->uart, buff, 4); + firmata_write_internal(firmata_dev, buff, 4); return MRAA_SUCCESS; } @@ -144,7 +134,7 @@ mraa_firmata_send_i2c_read_req(mraa_i2c_context dev, int length) buffer[5] = (length >> 7) & 0x7f; buffer[6] = FIRMATA_END_SYSEX; - if (mraa_uart_write(firmata_dev->uart, buffer, 7) != 7) { + if (firmata_write_internal(firmata_dev, buffer, 7) != 7) { free(buffer); return MRAA_ERROR_UNSPECIFIED; } @@ -176,7 +166,7 @@ mraa_firmata_send_i2c_read_reg_req(mraa_i2c_context dev, uint8_t command, int le buffer[7] = (length >> 7) & 0x7f; buffer[8] = FIRMATA_END_SYSEX; - if (mraa_uart_write(firmata_dev->uart, buffer, 9) != 9) { + if (firmata_write_internal(firmata_dev, buffer, 9) != 9) { free(buffer); return MRAA_ERROR_UNSPECIFIED; } @@ -293,7 +283,7 @@ mraa_firmata_i2c_write(mraa_i2c_context dev, const uint8_t* data, int bytesToWri ii = ii+2; } buffer[buffer_size-1] = FIRMATA_END_SYSEX; - mraa_uart_write(firmata_dev->uart, buffer, buffer_size); + firmata_write_internal(firmata_dev, buffer, buffer_size); free(buffer); return MRAA_SUCCESS; } @@ -312,7 +302,7 @@ mraa_firmata_i2c_write_byte(mraa_i2c_context dev, uint8_t data) buffer[4] = data & 0x7F; buffer[5] = (data >> 7) & 0x7F; buffer[6] = FIRMATA_END_SYSEX; - mraa_uart_write(firmata_dev->uart, buffer, 7); + firmata_write_internal(firmata_dev, buffer, 7); free(buffer); return MRAA_SUCCESS; } @@ -333,7 +323,7 @@ mraa_firmata_i2c_write_byte_data(mraa_i2c_context dev, const uint8_t data, const buffer[6] = data & 0x7F; buffer[7] = (data >> 7) & 0x7F; buffer[8] = FIRMATA_END_SYSEX; - mraa_uart_write(firmata_dev->uart, buffer, 9); + firmata_write_internal(firmata_dev, buffer, 9); free(buffer); return MRAA_SUCCESS; } @@ -527,15 +517,19 @@ mraa_firmata_pull_handler(void* vp) } mraa_board_t* -mraa_firmata_plat_init(const char* uart_dev) +mraa_firmata_plat_init(const char* uart_dev, mraa_platform_t type) { mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); if (b == NULL) { return NULL; } - firmata_ble_new("FIRMATA"); - firmata_dev = firmata_new(uart_dev); + if (type == MRAA_GENERIC_FIRMATA) { + firmata_dev = firmata_new(uart_dev); + } + else if (type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS) { + firmata_dev = firmata_ble_new(uart_dev, type); + } if (firmata_dev == NULL) { syslog(LOG_WARNING, "firmata: Failed to open uart to Firmata dev on %s", uart_dev); fprintf(stderr, "Mraa expected to find a Firmata device on %s, is the port in use?\n", uart_dev); @@ -546,14 +540,19 @@ mraa_firmata_plat_init(const char* uart_dev) // if this isn't working then we have an issue with our uart int retry = 20; while (!firmata_dev->isReady && retry--) { - firmata_pull(firmata_dev); + firmata_pull(firmata_dev); } if (!retry) { syslog(LOG_ERR, "firmata: Failed to find a valid Firmata board on %s", uart_dev); - firmata_close(firmata_dev); + if (type == MRAA_GENERIC_FIRMATA) { + firmata_close(firmata_dev); + } + else if (type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS) { + firmata_ble_close(firmata_dev); + } free(b); - return NULL; + return NULL; } pthread_create(&thread_id, NULL, mraa_firmata_pull_handler, NULL); @@ -688,7 +687,7 @@ mraa_firmata_plat_init(const char* uart_dev) } mraa_platform_t -mraa_firmata_platform(mraa_board_t* board, const char* uart_dev) +mraa_firmata_platform(mraa_board_t* board, const char* uart_dev, mraa_platform_t type) { /** * Firmata boards are not something we can detect so we just trust the user @@ -697,7 +696,7 @@ mraa_firmata_platform(mraa_board_t* board, const char* uart_dev) */ mraa_board_t* sub_plat = NULL; - sub_plat = mraa_firmata_plat_init(uart_dev); + sub_plat = mraa_firmata_plat_init(uart_dev, type); if (sub_plat != NULL) { sub_plat->platform_type = MRAA_GENERIC_FIRMATA; board->sub_platform = sub_plat; @@ -705,4 +704,4 @@ mraa_firmata_platform(mraa_board_t* board, const char* uart_dev) } return MRAA_NULL_PLATFORM; -} +} \ No newline at end of file diff --git a/src/mraa.c b/src/mraa.c index f59e09203..a59c16a6f 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -987,14 +987,14 @@ mraa_get_iio_device_count() } mraa_result_t -mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev) +mraa_add_subplatform(mraa_platform_t subplatformtype, const char* dev) { #if defined(FIRMATA) if (subplatformtype == MRAA_GENERIC_FIRMATA) { if (plat->sub_platform != NULL) { return MRAA_ERROR_INVALID_PARAMETER; } - if (mraa_firmata_platform(plat, uart_dev) == MRAA_GENERIC_FIRMATA) { + if (mraa_firmata_platform(plat, dev, MRAA_GENERIC_FIRMATA) == MRAA_GENERIC_FIRMATA) { syslog(LOG_NOTICE, "mraa: Added firmata subplatform"); return MRAA_SUCCESS; } @@ -1002,16 +1002,25 @@ mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev) } #endif #if defined(FIRMATABLE) - //by name & by address - two types - if (subplatformtype == MRAA_BLE_FIRMATA) { + else if (subplatformtype == MRAA_BLE_FIRMATA_BY_NAME) { if (plat->sub_platform != NULL) { return MRAA_ERROR_INVALID_PARAMETER; } - if (mraa_firmata_platform(plat, uart_dev) == MRAA_BLE_FIRMATA) { - syslog(LOG_NOTICE, "mraa: Added firmata subplatform"); + if (mraa_firmata_platform(plat, dev, MRAA_BLE_FIRMATA_BY_NAME) == MRAA_BLE_FIRMATA_BY_NAME) { + syslog(LOG_NOTICE, "mraa: Added firmata ble subplatform by name"); return MRAA_SUCCESS; } - syslog(LOG_NOTICE, "mraa: Failed to add firmata subplatform"); + syslog(LOG_NOTICE, "mraa: Failed to add firmata ble subplatform by name"); + } + else if (subplatformtype == MRAA_BLE_FIRMATA_BY_ADDRESS) { + if (plat->sub_platform != NULL) { + return MRAA_ERROR_INVALID_PARAMETER; + } + if (mraa_firmata_platform(plat, dev, MRAA_BLE_FIRMATA_BY_ADDRESS) == MRAA_BLE_FIRMATA_BY_ADDRESS) { + syslog(LOG_NOTICE, "mraa: Added firmata ble subplatform by address"); + return MRAA_SUCCESS; + } + syslog(LOG_NOTICE, "mraa: Failed to add firmata ble subplatform by address"); } #endif From 814b7455c5c5c4df0c01cd8d289f8cef3205f9e3 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Sun, 12 Jun 2016 12:29:33 +0300 Subject: [PATCH 3/8] removed debug prints renamed callback removed firmata pull thread when using ble Signed-off-by: Shiran Ben-Melech --- api/mraa/littleb.h | 320 ---------------------------------- examples/python/hello_gpio.py | 6 +- src/firmata/firmata.c | 15 +- src/firmata/firmata_mraa.c | 4 +- 4 files changed, 11 insertions(+), 334 deletions(-) delete mode 100644 api/mraa/littleb.h diff --git a/api/mraa/littleb.h b/api/mraa/littleb.h deleted file mode 100644 index 12591ece6..000000000 --- a/api/mraa/littleb.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Author: Shiran Ben-Melech - * Copyright (c) 2016 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include - -#define MAX_LEN 256 -#define MAX_OBJECTS 256 - -static const char* BLUEZ_DEST = "org.bluez"; -static const char* BLUEZ_DEVICE = "org.bluez.Device1"; -static const char* BLUEZ_GATT_SERVICE = "org.bluez.GattService1"; -static const char* BLUEZ_GATT_CHARACTERISTICS = "org.bluez.GattCharacteristic1"; - -/** - * LB return codes - */ -typedef enum { - LB_SUCCESS = 0, /**< Expected response */ - LB_ERROR_FEATURE_NOT_IMPLEMENTED = 1, /**< Feature TODO */ - LB_ERROR_FEATURE_NOT_SUPPORTED = 2, /**< Feature not supported by HW */ - LB_ERROR_INVALID_DEVICE = 3, /**< Not a BL or BLE device */ - LB_ERROR_INVALID_BUS = 4, /**< sd bus invalid */ - LB_ERROR_NO_RESOURCES = 5, /**< No resource of that type avail */ - LB_ERROR_MEMEORY_ALLOCATION = 6, /**< Memory allocation fail */ - LB_ERROR_SD_BUS_CALL_FAIL = 7, /**< sd_bus call failure */ - - LB_ERROR_UNSPECIFIED = 99 /**< Unknown Error */ -} lb_result_t; - -typedef struct ble_characteristic { - const char* char_path; /**< device path under dbus */ - const char* uuid; /**< uuid of the characteristic. */ -} ble_char; - -typedef struct ble_service { - const char* service_path; /**< device path under dbus */ - const char* uuid; /**< uuid of the service. */ - bool primary; /**< is the service primary in the device */ - ble_char** characteristics; /**< list of the characteristics inside the service */ - int characteristics_size; /**< count of characteristics in the service */ -} ble_service; - -typedef struct bl_device { - const char* device_path; /**< device path under dbus */ - const char* address; /**< address of the bluetooth device */ - const char* name; /**< name of the bluetooth device */ - ble_service** services; /**< list of the service inside the device */ - int services_size; /**< count of services in the device */ -} bl_device; - - -typedef struct lb_context { - sd_bus* bus; /**< system bus to be used */ - bl_device** devices; /**< list of the devices found in a scan */ - int devices_size; /**< count of devices found*/ -} lb_context; - -typedef struct event_callback_pair { - const char* event; - sd_bus_message_handler_t* callback; -} event_pair; - - -/** - * Initialize littleb. - * - * Set event and event loop configuration - * - * @return Result of operation - */ -lb_result_t lb_init(); - -/** - * Destroy littleb - * - * @return Result of operation - */ -lb_result_t lb_destroy(); - -/** - * Create new littleb context to contain devices found - * - * @param ADD - * @return new lb_context or NULL if failed - */ -lb_context* lb_context_new(); - -/** - * Free littleb context created with lb_context_new - * - * @param lb_context to be freed - * @return Result of operation - */ -lb_result_t lb_context_free(lb_context* lb_ctx); - -/** - * Populate internal list of bl devices found in a scan of specified length - * - * @param lb_context to use - * @param seconds to perform device scan - * @return Result of operation - */ -lb_result_t lb_get_bl_devices(lb_context* lb_ctx, int seconds); - -/** - * Connect to a specific bluetooth device - * - * bl_device can be found by name, path or address using lb_get_device functions - * - * @param lb_context to use - * @param bl_device to connect to - * @return Result of operation - */ -lb_result_t lb_connect_device(lb_context* lb_ctx, bl_device* dev); - -/** - * Disconnect from a specific bluetooth device - * - * @param lb_context to use - * @param bl_device to disconnect from - * @return Result of operation - */ -lb_result_t lb_disconnect_device(lb_context* lb_ctx, bl_device* dev); - -/** - * Pair with specific bluetooth device - * - * @param lb_context to use - * @param bl_device to pair with - * @return Result of operation - */ -lb_result_t lb_pair_device(lb_context* lb_ctx, bl_device* dev); - -/** - * Cancel pairing with specific bluetooth device - * - * @param lb_context to use - * @param bl_device to cancel pair with - * @return Result of operation - */ -lb_result_t lb_unpair_device(lb_context* lb_ctx, bl_device* dev); - -/** - * Populate ble_char with characteristic found by using it's device path under dbus - * - * @param lb_context to use - * @param bl_dev to search the characteristic in - * @param characteristic_path to search for - * @param ble_char to populate with characteristic found - * @return Result of operation - */ -lb_result_t lb_get_ble_characteristic_by_characteristic_path(lb_context* lb_ctx, - bl_device* dev, - const char* characteristic_path, - ble_char** ble_characteristic_ret); - -/** - * Populate ble_char with characteristic found by using it's uuid - * - * @param lb_context to use - * @param bl_dev to search the characteristic in - * @param uuid to search for - * @param ble_char to populate with characteristic found - * @return Result of operation - */ -lb_result_t -lb_get_ble_characteristic_by_uuid(lb_context* lb_ctx, bl_device* dev, const char* uuid, ble_char** ble_characteristic_ret); - -/** - * Populate ble_service with service found by using it's device path under dbus - * - * @param lb_context to use - * @param bl_dev to search the service in - * @param service_path to search for - * @param ble_service to populate with service found - * @return Result of operation - */ -lb_result_t lb_get_ble_service_by_service_path(lb_context* lb_ctx, - bl_device* dev, - const char* service_path, - ble_service** ble_service_ret); - -/** - * Populate ble_service with service found by using it's uuid - * - * @param lb_context to use - * @param bl_dev to search the service in - * @param uuid to search for - * @param ble_service to populate with service found - * @return Result of operation - */ -lb_result_t lb_get_ble_service_by_uuid(lb_context* lb_ctx, bl_device* dev, const char* uuid, ble_service** ble_service_ret); - -/** - * Populate the BLE device with it's services - * - * @param lb_context to use - * @param bl_dev to scan services - * @return Result of operation - */ -lb_result_t lb_get_ble_device_services(lb_context* lb_ctx, bl_device* dev); - -/** - * Get bluetooth device by using it's device path under dbus - * - * @param lb_context to use - * @param device_path to search for - * @param bl_device_ret to populate with the found device - * @return Result of operation - */ -lb_result_t lb_get_device_by_device_path(lb_context* lb_ctx, const char* device_path, bl_device** bl_device_ret); - -/** - * Get bluetooth device by searching for specific name - * - * Will return the first found device with the name specified - * - * @param lb_context to use - * @param name to search for - * @param bl_device_ret to populate with the found device - * @return Result of operation - */ -lb_result_t lb_get_device_by_device_name(lb_context* lb_ctx, const char* name, bl_device** bl_device_ret); - -/** - * Get bluetooth device by searching for specific address - * - * @param lb_context to use - * @param address to search for - * @param bl_device_ret to populate with the found device - * @return Result of operation - */ -lb_result_t lb_get_device_by_device_address(lb_context* lb_ctx, const char* address, bl_device** bl_device_ret); - -/** - * Write to a specific BLE device characteristic using it's uuid - * - * @param lb_context to use - * @param dev BLE device to search the characteristic in - * @param uuid of the characteristic to write to - * @param size of the uint8 array to be written - * @param the array of byte buffer to write to the characteristic - * @return Result of operation - */ -lb_result_t -lb_write_to_characteristic(lb_context* lb_ctx, bl_device* dev, const char* uuid, int size, uint8_t* value); - -/** - * Read from a specific BLE device characteristic using it's uuid - * - * @param lb_context to use - * @param dev BLE device to search the characteristic in - * @param uuid of the characteristic to read from - * @param size of the uint8 array that was read - * @param the array of byte buffer that was read - * @return Result of operation - */ -lb_result_t -lb_read_from_characteristic(lb_context* lb_ctx, bl_device* dev, const char* uuid, size_t* size, uint8_t** result); - -/** - * Register a callback function for an event of characteristic value change - * - * @param lb_context to use - * @param dev BLE device to search the characteristic in - * @param uuid of the characteristic to read from - * @param callback function to be called when char value changed - * @param userdata to pass in the callback function - * @return Result of operation - */ -lb_result_t lb_register_characteristic_read_event(lb_context* lb_ctx, - bl_device* dev, - const char* uuid, - sd_bus_message_handler_t callback, - void* userdata); - -/** - * Special function to parse uart tx line buffer - * - * @param message sd_bus_message to prase the buffer array from - * @param result buffer to accommodate the result - * @param size of the buffer - * @return Result of operation - */ -lb_result_t lb_parse_uart_service_message(sd_bus_message* message, const void** result, size_t* size); -#ifdef __cplusplus -} -#endif diff --git a/examples/python/hello_gpio.py b/examples/python/hello_gpio.py index aa718c7a0..e4381b049 100644 --- a/examples/python/hello_gpio.py +++ b/examples/python/hello_gpio.py @@ -23,11 +23,15 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import mraa +import time print (mraa.getVersion()) mraa.addSubplatform(mraa.BLE_FIRMATA_BY_NAME, "FIRMATA") x = mraa.Gpio(13 + 512) x.dir(mraa.DIR_OUT) -for i in range(100): +print "Blinking" +for i in range(10): x.write(1) + time.sleep(0) x.write(0) + time.sleep(1) diff --git a/src/firmata/firmata.c b/src/firmata/firmata.c index 5091a5733..26790f9c1 100644 --- a/src/firmata/firmata.c +++ b/src/firmata/firmata.c @@ -31,7 +31,7 @@ #include static int -test_callback(sd_bus_message* message, void* userdata, sd_bus_error* error) +firmata_uart_read_handler(sd_bus_message* message, void* userdata, sd_bus_error* error) { int r, i; @@ -39,22 +39,13 @@ test_callback(sd_bus_message* message, void* userdata, sd_bus_error* error) uint8_t* result = NULL; t_firmata* firmata = (t_firmata*) userdata; - - printf("callback called\n"); - r = dl_lb_parse_uart_service_message(message, (const void**) &result, &size); if (r < 0) { fprintf(stderr, "ERROR: couldn't parse uart message\n"); return LB_ERROR_UNSPECIFIED; } - printf("message is:\n"); - for (i = 0; i < size; i++) { - printf("%x ", result[i]); - } - printf("\n"); - - //firmata_parse(firmata, result, size); + firmata_parse(firmata, result, size); return LB_SUCCESS; } @@ -183,7 +174,7 @@ firmata_ble_new(const char* name, mraa_platform_t type) } ble_res = dl_lb_register_characteristic_read_event(res->lb_ctx, res->bl_dev, - "6e400003-b5a3-f393-e0a9-e50e24dcca9e", test_callback, res); + "6e400003-b5a3-f393-e0a9-e50e24dcca9e", firmata_uart_read_handler, res); if (ble_res < 0) { fprintf(stderr, "ERROR: lb_register_characteristic_read_event\n"); firmata_ble_close(res); diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index 8a4532f7d..4ae4c2f05 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -555,7 +555,9 @@ mraa_firmata_plat_init(const char* uart_dev, mraa_platform_t type) return NULL; } - pthread_create(&thread_id, NULL, mraa_firmata_pull_handler, NULL); + if (!(type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS)) { + pthread_create(&thread_id, NULL, mraa_firmata_pull_handler, NULL); + } b->platform_name = "firmata"; // do we support 2.5? Or are we more 2.3? From 9eaa282dafc4ebbbcee977d63d1ee555d887e469 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Mon, 13 Jun 2016 11:48:10 +0300 Subject: [PATCH 4/8] fixed mraa_firmata_plat_init Signed-off-by: Shiran Ben-Melech --- src/firmata/firmata_mraa.c | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index 4ae4c2f05..b47bfb62e 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -526,39 +526,39 @@ mraa_firmata_plat_init(const char* uart_dev, mraa_platform_t type) if (type == MRAA_GENERIC_FIRMATA) { firmata_dev = firmata_new(uart_dev); - } - else if (type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS) { - firmata_dev = firmata_ble_new(uart_dev, type); - } - if (firmata_dev == NULL) { - syslog(LOG_WARNING, "firmata: Failed to open uart to Firmata dev on %s", uart_dev); - fprintf(stderr, "Mraa expected to find a Firmata device on %s, is the port in use?\n", uart_dev); - free(b); - return NULL; - } - - // if this isn't working then we have an issue with our uart - int retry = 20; - while (!firmata_dev->isReady && retry--) { - firmata_pull(firmata_dev); - } + if (firmata_dev == NULL) { + syslog(LOG_WARNING, "firmata: Failed to open uart to Firmata dev on %s", uart_dev); + fprintf(stderr, "Mraa expected to find a Firmata device on %s, is the port in use?\n", uart_dev); + free(b); + return NULL; + } - if (!retry) { - syslog(LOG_ERR, "firmata: Failed to find a valid Firmata board on %s", uart_dev); - if (type == MRAA_GENERIC_FIRMATA) { - firmata_close(firmata_dev); + // if this isn't working then we have an issue with our uart + int retry = 20; + while (!firmata_dev->isReady && retry--) { + firmata_pull(firmata_dev); } - else if (type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS) { - firmata_ble_close(firmata_dev); + if (!retry) { + syslog(LOG_ERR, "firmata: Failed to find a valid Firmata board on %s", uart_dev); + firmata_close(firmata_dev); + free(b); + return NULL; } - free(b); - return NULL; - } - if (!(type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS)) { pthread_create(&thread_id, NULL, mraa_firmata_pull_handler, NULL); } + else if (type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS) { + firmata_dev = firmata_ble_new(uart_dev, type); + if (firmata_dev == NULL) { + syslog(LOG_WARNING, "firmata: Failed to open ble to Firmata dev on %s", uart_dev); + fprintf(stderr, "Mraa expected to find a Firmata ble device named %s, is the device available?\n", uart_dev); + firmata_ble_close(firmata_dev); + free(b); + return NULL; + } + } + b->platform_name = "firmata"; // do we support 2.5? Or are we more 2.3? // or should we return the flashed sketch name? @@ -700,7 +700,7 @@ mraa_firmata_platform(mraa_board_t* board, const char* uart_dev, mraa_platform_t sub_plat = mraa_firmata_plat_init(uart_dev, type); if (sub_plat != NULL) { - sub_plat->platform_type = MRAA_GENERIC_FIRMATA; + sub_plat->platform_type = type; board->sub_platform = sub_plat; return sub_plat->platform_type; } From 77bd06cbc63b3d567989f259f27ba81d3ea1ef81 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Mon, 13 Jun 2016 16:57:16 +0300 Subject: [PATCH 5/8] added firmata_ble close to mraa_firmata close Signed-off-by: Shiran Ben-Melech --- src/firmata/firmata_mraa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index b47bfb62e..ebe0a9935 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -84,6 +84,7 @@ mraa_result_t mraa_firmata_close(mraa_firmata_context dev) { mraa_firmata_response_stop(dev); + firmata_close(firmata_dev); free(dev); return MRAA_SUCCESS; } From 70838cc4a6d0d7c905019787c5384a9adfb05900 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Tue, 14 Jun 2016 14:24:10 +0300 Subject: [PATCH 6/8] Changed all fprintf to syslog fixed some small issues clang-format on changed files Signed-off-by: Shiran Ben-Melech --- CMakeLists.txt | 1 - examples/python/hello_gpio_ble.py | 37 ++++++++++++ examples/python/rgblcd_ble.py | 41 +++++++++++++ src/CMakeLists.txt | 4 -- src/firmata/firmata.c | 84 +++++++++++++------------- src/firmata/firmata_mraa.c | 37 ++++++------ src/mraa.c | 98 +++++++++++++++++-------------- 7 files changed, 195 insertions(+), 107 deletions(-) create mode 100644 examples/python/hello_gpio_ble.py create mode 100644 examples/python/rgblcd_ble.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 697f44f0b..5b3910bb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,6 @@ option (BUILDSWIGNODE "Build swig node modules." ON) option (BUILDSWIGJAVA "Build Java API." OFF) option (USBPLAT "Detection USB platform." OFF) option (FIRMATA "Add Firmata support to mraa." OFF) -option (FIRMATABLE "Add littleb" OFF) option (ONEWIRE "Add Onewire support to mraa." ON) option (IMRAA "Add Imraa support to mraa." OFF) option (FTDI4222 "Build with FTDI FT4222 subplatform support." OFF) diff --git a/examples/python/hello_gpio_ble.py b/examples/python/hello_gpio_ble.py new file mode 100644 index 000000000..01531ce5f --- /dev/null +++ b/examples/python/hello_gpio_ble.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +# Author: Thomas Ingleby +# Copyright (c) 2014 Intel Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import mraa +import time + +print (mraa.getVersion()) +mraa.addSubplatform(mraa.BLE_FIRMATA_BY_NAME, "FIRMATA") +x = mraa.Gpio(3 + 512) +x.dir(mraa.DIR_OUT) +print "Blinking" +for i in range(5): + x.write(1) + time.sleep(1) + x.write(0) + time.sleep(1) diff --git a/examples/python/rgblcd_ble.py b/examples/python/rgblcd_ble.py new file mode 100644 index 000000000..670fd3940 --- /dev/null +++ b/examples/python/rgblcd_ble.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +# Author: Brendan Le Foll +# Copyright (c) 2014 Intel Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + +import mraa + +mraa.addSubplatform(mraa.BLE_FIRMATA_BY_NAME, "FIRMATA") + +# This example will change the LCD backlight on the Grove-LCD RGB backlight +# to a nice shade of purple +x = mraa.I2c(512+0) +x.address(0x62) + +# initialise device +x.writeReg(0, 0) +x.writeReg(1, 0) + +# sent RGB color data +x.writeReg(0x08, 0xAA) +x.writeReg(0x04, 255) +x.writeReg(0x02, 255) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3b6dbf372..5e4ef612f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,10 +9,6 @@ if (FIRMATA) add_subdirectory (firmata) endif () -if (FIRMATABLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFIRMATABLE=1") -endif () - if (ONEWIRE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DONEWIRE=1") add_subdirectory (uart_ow) diff --git a/src/firmata/firmata.c b/src/firmata/firmata.c index 26790f9c1..4d2e32463 100644 --- a/src/firmata/firmata.c +++ b/src/firmata/firmata.c @@ -41,27 +41,26 @@ firmata_uart_read_handler(sd_bus_message* message, void* userdata, sd_bus_error* r = dl_lb_parse_uart_service_message(message, (const void**) &result, &size); if (r < 0) { - fprintf(stderr, "ERROR: couldn't parse uart message\n"); + syslog(LOG_ERR, "ERROR: couldn't parse uart message\n"); return LB_ERROR_UNSPECIFIED; } firmata_parse(firmata, result, size); - + return LB_SUCCESS; } -inline -int +inline int firmata_write_internal(t_firmata* firmata_dev, const char* buf, size_t len) { lb_result_t res = LB_ERROR_UNSPECIFIED; if (firmata_dev->uart != NULL) { mraa_uart_write(firmata_dev->uart, buf, len); - } - else if (firmata_dev->lb_ctx != NULL) { - res = dl_lb_write_to_characteristic(firmata_dev->lb_ctx, firmata_dev->bl_dev, "6e400002-b5a3-f393-e0a9-e50e24dcca9e", len, (uint8_t*)buf); + } else if (firmata_dev->lb_ctx != NULL) { + res = dl_lb_write_to_characteristic(firmata_dev->lb_ctx, firmata_dev->bl_dev, + "6e400002-b5a3-f393-e0a9-e50e24dcca9e", len, (uint8_t*) buf); if (res < 0) { - fprintf(stderr, "ERROR: lb_write_to_characteristic\n"); + syslog(LOG_ERR, "ERROR: lb_write_to_characteristic\n"); return MRAA_ERROR_UNSPECIFIED; } } @@ -83,7 +82,7 @@ firmata_new(const char* name) if (res->uart == NULL) { syslog(LOG_ERR, "firmata: UART failed to setup"); free(res); - return NULL; + return NULL; } firmata_initPins(res); @@ -102,84 +101,88 @@ t_firmata* firmata_ble_new(const char* name, mraa_platform_t type) { t_firmata* res; - lb_result_t ble_res = LB_ERROR_UNSPECIFIED; + int ble_res = LB_ERROR_UNSPECIFIED; res = calloc(1, sizeof(t_firmata)); if (!res) { return NULL; } + res->bl_dev = NULL; + ble_res = mraa_firmata_ble_init(); if (ble_res < 0) { syslog(LOG_ERR, "firmata: littleb failed to setup"); free(res); - return NULL; + return NULL; } ble_res = dl_lb_init(); if (ble_res < 0) { - fprintf(stderr, "ERROR: lb_init\n"); + syslog(LOG_ERR, "ERROR: lb_init\n"); free(res); - return NULL; } + return NULL; + } res->lb_ctx = dl_lb_context_new(); if (res->lb_ctx == NULL) { - fprintf(stderr, "ERROR: lb_context_new\n"); + syslog(LOG_ERR, "ERROR: lb_context_new\n"); free(res); - return NULL; + return NULL; } ble_res = dl_lb_get_bl_devices(res->lb_ctx, 5); if (ble_res < 0) { - fprintf(stderr, "ERROR: lb_get_bl_devices\n"); + syslog(LOG_ERR, "ERROR: lb_get_bl_devices\n"); firmata_ble_close(res); + free(res); + return NULL; } - // search for our specific device named "FIRMATA" - res->bl_dev = NULL; if (type == MRAA_BLE_FIRMATA_BY_NAME) { ble_res = dl_lb_get_device_by_device_name(res->lb_ctx, name, &res->bl_dev); - } - else if (type == MRAA_BLE_FIRMATA_BY_ADDRESS) { + } else if (type == MRAA_BLE_FIRMATA_BY_ADDRESS) { ble_res = dl_lb_get_device_by_device_address(res->lb_ctx, name, &res->bl_dev); } if (ble_res < 0) { - fprintf(stderr, "ERROR: Device FIRMATA not found\n"); + syslog(LOG_ERR, "ERROR: Device FIRMATA not found\n"); firmata_ble_close(res); free(res); - return NULL; + return NULL; } ble_res = dl_lb_connect_device(res->lb_ctx, res->bl_dev); if (ble_res < 0) { - fprintf(stderr, "ERROR: lb_connect_device\n"); + syslog(LOG_ERR, "ERROR: lb_connect_device\n"); firmata_ble_close(res); free(res); - return NULL; + return NULL; } // ble_res = lb_pair_device(res->lb_ctx, res->bl_dev); // if (ble_res < 0) { - // fprintf(stderr, "ERROR: lb_pair_device\n"); + // syslog(LOG_ERR, "ERROR: lb_pair_device\n"); // free(res); - // return NULL; + // return NULL; //} ble_res = dl_lb_get_ble_device_services(res->lb_ctx, res->bl_dev); if (ble_res < 0) { - fprintf(stderr, "ERROR: lb_get_ble_device_services\n"); + syslog(LOG_ERR, "ERROR: lb_get_ble_device_services\n"); firmata_ble_close(res); free(res); - return NULL; + return NULL; } ble_res = dl_lb_register_characteristic_read_event(res->lb_ctx, res->bl_dev, - "6e400003-b5a3-f393-e0a9-e50e24dcca9e", firmata_uart_read_handler, res); + "6e400003-b5a3-f393-e0a9-e50e24dcca9e", + firmata_uart_read_handler, res); if (ble_res < 0) { - fprintf(stderr, "ERROR: lb_register_characteristic_read_event\n"); + syslog(LOG_ERR, "ERROR: lb_register_characteristic_read_event\n"); firmata_ble_close(res); free(res); - return NULL; } + return NULL; + } firmata_initPins(res); @@ -193,26 +196,26 @@ void firmata_ble_close(t_firmata* firmata) { lb_result_t r = LB_ERROR_UNSPECIFIED; - + // r = lb_unpair_device(lb_ctx, firmata); // if (r < 0) { - // fprintf(stderr, "ERROR: lb_unpair_device\n"); + // syslog(LOG_ERR, "ERROR: lb_unpair_device\n"); // exit(r); //} r = dl_lb_disconnect_device(firmata->lb_ctx, firmata->bl_dev); if (r < 0) { - fprintf(stderr, "ERROR: lb_disconnect_device\n"); + syslog(LOG_ERR, "ERROR: lb_disconnect_device\n"); } r = dl_lb_context_free(firmata->lb_ctx); if (r < 0) { - fprintf(stderr, "ERROR: lb_context_free\n"); + syslog(LOG_ERR, "ERROR: lb_context_free\n"); } r = dl_lb_destroy(); if (r < 0) { - fprintf(stderr, "ERROR: lb_destroy\n"); + syslog(LOG_ERR, "ERROR: lb_destroy\n"); } } @@ -392,15 +395,16 @@ firmata_endParse(t_firmata* firmata) firmata->pins[pin].value |= (firmata->parse_buff[5] << 7); if (firmata->parse_count > 7) firmata->pins[pin].value |= (firmata->parse_buff[6] << 14); - // disable this to check the firmata_devs responses + // disable this to check the firmata_devs responses } else if (firmata->parse_buff[1] == FIRMATA_I2C_REPLY) { int addr = (firmata->parse_buff[2] & 0x7f) | ((firmata->parse_buff[3] & 0x7f) << 7); int reg = (firmata->parse_buff[4] & 0x7f) | ((firmata->parse_buff[5] & 0x7f) << 7); int i = 6; int ii = 0; for (ii; ii < (firmata->parse_count - 7) / 2; ii++) { - firmata->i2cmsg[addr][reg+ii] = (firmata->parse_buff[i] & 0x7f) | ((firmata->parse_buff[i+1] & 0x7f) << 7); - i = i+2; + firmata->i2cmsg[addr][reg + ii] = + (firmata->parse_buff[i] & 0x7f) | ((firmata->parse_buff[i + 1] & 0x7f) << 7); + i = i + 2; } } else { if (firmata->devs != NULL) { @@ -479,7 +483,7 @@ firmata_analogWrite(t_firmata* firmata, int pin, int value) } int -firmata_analogRead(t_firmata *firmata, int pin) +firmata_analogRead(t_firmata* firmata, int pin) { int res; int value = 1; diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index ebe0a9935..ae2c356d5 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -59,7 +59,7 @@ mraa_firmata_response(mraa_firmata_context dev, void (*fptr)(uint8_t*, int)) { if (dev->added == 0) { struct _firmata** ptr; - ptr = realloc(firmata_dev->devs, (firmata_dev->dev_count+1) * sizeof(struct _firmata*)); + ptr = realloc(firmata_dev->devs, (firmata_dev->dev_count + 1) * sizeof(struct _firmata*)); if (ptr == NULL) { return MRAA_ERROR_NO_RESOURCES; } @@ -107,7 +107,7 @@ static mraa_result_t mraa_firmata_i2c_address(mraa_i2c_context dev, uint8_t addr) { // only thing needed and it's already done - //dev->addr = (int) addr; + // dev->addr = (int) addr; return MRAA_SUCCESS; } @@ -141,7 +141,7 @@ mraa_firmata_send_i2c_read_req(mraa_i2c_context dev, int length) } // this needs a lock :) - memset(&firmata_dev->i2cmsg[dev->addr][0], -1, sizeof(int)*length); + memset(&firmata_dev->i2cmsg[dev->addr][0], -1, sizeof(int) * length); free(buffer); return MRAA_SUCCESS; @@ -173,7 +173,7 @@ mraa_firmata_send_i2c_read_reg_req(mraa_i2c_context dev, uint8_t command, int le } // this needs a lock :) - memset(&firmata_dev->i2cmsg[dev->addr][command], -1, sizeof(int)*length); + memset(&firmata_dev->i2cmsg[dev->addr][command], -1, sizeof(int) * length); free(buffer); return MRAA_SUCCESS; @@ -210,7 +210,7 @@ mraa_firmata_i2c_read_word_data(mraa_i2c_context dev, uint8_t command) if (mraa_firmata_i2c_wait(dev->addr, command) == MRAA_SUCCESS) { uint8_t rawdata[2]; rawdata[0] = firmata_dev->i2cmsg[dev->addr][command]; - rawdata[1] = firmata_dev->i2cmsg[dev->addr][command+1]; + rawdata[1] = firmata_dev->i2cmsg[dev->addr][command + 1]; uint16_t data = (uint16_t) rawdata; uint8_t high = (data & 0xFF00) >> 8; data = (data << 8) & 0xFF00; @@ -227,7 +227,7 @@ mraa_firmata_i2c_read_bytes_data(mraa_i2c_context dev, uint8_t command, uint8_t* { if (mraa_firmata_send_i2c_read_reg_req(dev, command, length) == MRAA_SUCCESS) { if (mraa_firmata_i2c_wait(dev->addr, command) == MRAA_SUCCESS) { - memcpy(data, &firmata_dev->i2cmsg[dev->addr][command], sizeof(int)*length); + memcpy(data, &firmata_dev->i2cmsg[dev->addr][command], sizeof(int) * length); return length; } } @@ -266,7 +266,7 @@ static mraa_result_t mraa_firmata_i2c_write(mraa_i2c_context dev, const uint8_t* data, int bytesToWrite) { // buffer needs 5 bytes for firmata, and 2 bytes for every byte of data - int buffer_size = (bytesToWrite*2) + 5; + int buffer_size = (bytesToWrite * 2) + 5; uint8_t* buffer = calloc(buffer_size, 0); if (buffer == NULL) { return MRAA_ERROR_NO_RESOURCES; @@ -278,12 +278,12 @@ mraa_firmata_i2c_write(mraa_i2c_context dev, const uint8_t* data, int bytesToWri buffer[2] = dev->addr; buffer[3] = I2C_MODE_WRITE << 3; // we need to write until FIRMATA_END_SYSEX - for (i; i < (buffer_size-1); i++) { + for (i; i < (buffer_size - 1); i++) { buffer[ii] = data[i] & 0x7F; - buffer[ii+1] = (data[i] >> 7) & 0x7f; - ii = ii+2; + buffer[ii + 1] = (data[i] >> 7) & 0x7f; + ii = ii + 2; } - buffer[buffer_size-1] = FIRMATA_END_SYSEX; + buffer[buffer_size - 1] = FIRMATA_END_SYSEX; firmata_write_internal(firmata_dev, buffer, buffer_size); free(buffer); return MRAA_SUCCESS; @@ -470,7 +470,7 @@ mraa_firmata_pwm_init_internal_replace(void* func_table, int pin) static mraa_result_t mraa_firmata_pwm_write_replace(mraa_pwm_context dev, float percentage) { - int value = (int)((percentage - 1) / 8000); + int value = (int) ((percentage - 1) / 8000); firmata_analogWrite(firmata_dev, dev->pin, value); firmata_dev->pins[dev->pin].value = value; return MRAA_SUCCESS; @@ -503,15 +503,15 @@ mraa_firmata_pull_handler(void* vp) { int i, isr_now, isr_prev; isr_prev = 0; - while(1) { + while (1) { isr_now = 0; firmata_pull(firmata_dev); // would prefer to send board pointer as argument - for(i = 0; i < 14; i++) { + for (i = 0; i < 14; i++) { isr_now |= (firmata_dev->pins[i].value & 1) << i; } // might want to lock here? - isr_detected = isr_prev ^ isr_now; //both edges for now + isr_detected = isr_prev ^ isr_now; // both edges for now isr_prev = isr_now; usleep(100); } @@ -543,7 +543,7 @@ mraa_firmata_plat_init(const char* uart_dev, mraa_platform_t type) syslog(LOG_ERR, "firmata: Failed to find a valid Firmata board on %s", uart_dev); firmata_close(firmata_dev); free(b); - return NULL; + return NULL; } pthread_create(&thread_id, NULL, mraa_firmata_pull_handler, NULL); @@ -553,8 +553,9 @@ mraa_firmata_plat_init(const char* uart_dev, mraa_platform_t type) firmata_dev = firmata_ble_new(uart_dev, type); if (firmata_dev == NULL) { syslog(LOG_WARNING, "firmata: Failed to open ble to Firmata dev on %s", uart_dev); - fprintf(stderr, "Mraa expected to find a Firmata ble device named %s, is the device available?\n", uart_dev); - firmata_ble_close(firmata_dev); + fprintf(stderr, "Mraa expected to find a Firmata ble device named %s, is the device " + "available?\n", + uart_dev); free(b); return NULL; } diff --git a/src/mraa.c b/src/mraa.c index a59c16a6f..00198041e 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -184,7 +184,8 @@ imraa_init() return MRAA_ERROR_NO_RESOURCES; } - syslog(LOG_NOTICE, "libmraa initialised for platform '%s' of type %d", mraa_get_platform_name(), mraa_get_platform_type()); + syslog(LOG_NOTICE, "libmraa initialised for platform '%s' of type %d", mraa_get_platform_name(), + mraa_get_platform_type()); return MRAA_SUCCESS; } @@ -217,7 +218,6 @@ mraa_deinit() free(sub_plat); } free(plat); - } if (plat_iio != NULL) { free(plat_iio); @@ -267,7 +267,7 @@ mraa_iio_detect() plat_iio->iio_device_count = num_iio_devices; plat_iio->iio_devices = calloc(num_iio_devices, sizeof(struct _iio)); struct _iio* device; - for (i=0; i < num_iio_devices; i++) { + for (i = 0; i < num_iio_devices; i++) { device = &plat_iio->iio_devices[i]; device->num = i; snprintf(filepath, 64, "/sys/bus/iio/devices/iio:device%d/name", i); @@ -280,7 +280,7 @@ mraa_iio_detect() len = strlen(name); // use strndup device->name = malloc((sizeof(char) * len) + sizeof(char)); - strncpy(device->name, name, len+1); + strncpy(device->name, name, len + 1); } close(fd); } @@ -298,22 +298,23 @@ mraa_setup_mux_mapped(mraa_pin_t meta) for (mi = 0; mi < meta.mux_total; mi++) { - switch(meta.mux[mi].pincmd) { - case PINCMD_UNDEFINED: // used for backward compatibility - if(meta.mux[mi].pin != last_pin) { + switch (meta.mux[mi].pincmd) { + case PINCMD_UNDEFINED: // used for backward compatibility + if (meta.mux[mi].pin != last_pin) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); } mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); - if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE; + if (mux_i == NULL) + return MRAA_ERROR_INVALID_HANDLE; last_pin = meta.mux[mi].pin; } // this function will sometimes fail, however this is not critical as // long as the write succeeds - Test case galileo gen2 pin2 mraa_gpio_dir(mux_i, MRAA_GPIO_OUT); ret = mraa_gpio_write(mux_i, meta.mux[mi].value); - if(ret != MRAA_SUCCESS) { + if (ret != MRAA_SUCCESS) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); @@ -323,19 +324,20 @@ mraa_setup_mux_mapped(mraa_pin_t meta) break; case PINCMD_SET_VALUE: - if(meta.mux[mi].pin != last_pin) { + if (meta.mux[mi].pin != last_pin) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); } mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); - if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE; + if (mux_i == NULL) + return MRAA_ERROR_INVALID_HANDLE; last_pin = meta.mux[mi].pin; } ret = mraa_gpio_write(mux_i, meta.mux[mi].value); - if(ret != MRAA_SUCCESS) { + if (ret != MRAA_SUCCESS) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); @@ -345,19 +347,20 @@ mraa_setup_mux_mapped(mraa_pin_t meta) break; case PINCMD_SET_DIRECTION: - if(meta.mux[mi].pin != last_pin) { + if (meta.mux[mi].pin != last_pin) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); } mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); - if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE; + if (mux_i == NULL) + return MRAA_ERROR_INVALID_HANDLE; last_pin = meta.mux[mi].pin; } ret = mraa_gpio_dir(mux_i, meta.mux[mi].value); - if(ret != MRAA_SUCCESS) { + if (ret != MRAA_SUCCESS) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); @@ -367,22 +370,23 @@ mraa_setup_mux_mapped(mraa_pin_t meta) break; case PINCMD_SET_IN_VALUE: - if(meta.mux[mi].pin != last_pin) { + if (meta.mux[mi].pin != last_pin) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); } mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); - if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE; + if (mux_i == NULL) + return MRAA_ERROR_INVALID_HANDLE; last_pin = meta.mux[mi].pin; } ret = mraa_gpio_dir(mux_i, MRAA_GPIO_IN); - if(ret == MRAA_SUCCESS) + if (ret == MRAA_SUCCESS) ret = mraa_gpio_write(mux_i, meta.mux[mi].value); - if(ret != MRAA_SUCCESS) { + if (ret != MRAA_SUCCESS) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); @@ -392,22 +396,23 @@ mraa_setup_mux_mapped(mraa_pin_t meta) break; case PINCMD_SET_OUT_VALUE: - if(meta.mux[mi].pin != last_pin) { + if (meta.mux[mi].pin != last_pin) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); } mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); - if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE; + if (mux_i == NULL) + return MRAA_ERROR_INVALID_HANDLE; last_pin = meta.mux[mi].pin; } ret = mraa_gpio_dir(mux_i, MRAA_GPIO_OUT); - if(ret == MRAA_SUCCESS) + if (ret == MRAA_SUCCESS) ret = mraa_gpio_write(mux_i, meta.mux[mi].value); - if(ret != MRAA_SUCCESS) { + if (ret != MRAA_SUCCESS) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); @@ -417,19 +422,20 @@ mraa_setup_mux_mapped(mraa_pin_t meta) break; case PINCMD_SET_MODE: - if(meta.mux[mi].pin != last_pin) { + if (meta.mux[mi].pin != last_pin) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); } mux_i = mraa_gpio_init_raw(meta.mux[mi].pin); - if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE; + if (mux_i == NULL) + return MRAA_ERROR_INVALID_HANDLE; last_pin = meta.mux[mi].pin; } ret = mraa_gpio_mode(mux_i, meta.mux[mi].value); - if(ret != MRAA_SUCCESS) { + if (ret != MRAA_SUCCESS) { if (mux_i != NULL) { mraa_gpio_owner(mux_i, 0); mraa_gpio_close(mux_i); @@ -442,7 +448,9 @@ mraa_setup_mux_mapped(mraa_pin_t meta) break; default: - syslog(LOG_NOTICE, "mraa_setup_mux_mapped: wrong command %d on pin %d with value %d", meta.mux[mi].pincmd, meta.mux[mi].pin, meta.mux[mi].value); + syslog(LOG_NOTICE, + "mraa_setup_mux_mapped: wrong command %d on pin %d with value %d", + meta.mux[mi].pincmd, meta.mux[mi].pin, meta.mux[mi].value); break; } } @@ -536,7 +544,8 @@ mraa_pin_mode_test(int pin, mraa_pinmodes_t mode) pin = mraa_get_sub_platform_index(pin); } - if (current_plat == NULL || current_plat->platform_type == MRAA_UNKNOWN_PLATFORM || current_plat->platform_type == MRAA_NULL_PLATFORM) { + if (current_plat == NULL || current_plat->platform_type == MRAA_UNKNOWN_PLATFORM || + current_plat->platform_type == MRAA_NULL_PLATFORM) { return 0; } if (pin > (current_plat->phy_pin_count - 1) || pin < 0) @@ -713,9 +722,9 @@ mraa_get_platform_pin_count(uint8_t platform_offset) return mraa_get_pin_count(); else { if (mraa_has_sub_platform()) - return plat->sub_platform->phy_pin_count; + return plat->sub_platform->phy_pin_count; else - return 0; + return 0; } } @@ -750,9 +759,9 @@ mraa_get_default_i2c_bus(uint8_t platform_offset) return plat->def_i2c_bus; } else { if (mraa_has_sub_platform()) - return plat->sub_platform->def_i2c_bus; + return plat->sub_platform->def_i2c_bus; else - return -1; + return -1; } } @@ -999,10 +1008,7 @@ mraa_add_subplatform(mraa_platform_t subplatformtype, const char* dev) return MRAA_SUCCESS; } syslog(LOG_NOTICE, "mraa: Failed to add firmata subplatform"); - } -#endif -#if defined(FIRMATABLE) - else if (subplatformtype == MRAA_BLE_FIRMATA_BY_NAME) { + } else if (subplatformtype == MRAA_BLE_FIRMATA_BY_NAME) { if (plat->sub_platform != NULL) { return MRAA_ERROR_INVALID_PARAMETER; } @@ -1011,8 +1017,7 @@ mraa_add_subplatform(mraa_platform_t subplatformtype, const char* dev) return MRAA_SUCCESS; } syslog(LOG_NOTICE, "mraa: Failed to add firmata ble subplatform by name"); - } - else if (subplatformtype == MRAA_BLE_FIRMATA_BY_ADDRESS) { + } else if (subplatformtype == MRAA_BLE_FIRMATA_BY_ADDRESS) { if (plat->sub_platform != NULL) { return MRAA_ERROR_INVALID_PARAMETER; } @@ -1078,8 +1083,9 @@ mraa_add_from_lockfile(const char* imraa_lock_file) int id = -1; const char* uartdev = NULL; for (i = 0; i < subplat_num; i++) { - struct json_object *ioobj = json_object_array_get_idx(ioarray, i); - json_object_object_foreach(ioobj, key, val) { + struct json_object* ioobj = json_object_array_get_idx(ioarray, i); + json_object_object_foreach(ioobj, key, val) + { if (strcmp(key, "id") == 0) { id = atoi(json_object_get_string(val)); } else if (strcmp(key, "uart") == 0) { @@ -1223,11 +1229,13 @@ mraa_init_io(const char* desc) } else if (strncmp(type, "PWM", 3) == 0) { if (raw) { if (mraa_init_io_helper(&str, &id, delim) != MRAA_SUCCESS) { - syslog(LOG_ERR, "mraa_init_io: Pwm, unable to convert the chip id string into a useable Int"); + syslog(LOG_ERR, "mraa_init_io: Pwm, unable to convert the chip id string into a " + "useable Int"); return NULL; } if (mraa_init_io_helper(&str, &pin, delim) != MRAA_SUCCESS) { - syslog(LOG_ERR, "mraa_init_io: Pwm, unable to convert the pin string into a useable Int"); + syslog(LOG_ERR, + "mraa_init_io: Pwm, unable to convert the pin string into a useable Int"); return NULL; } return (void*) mraa_pwm_init_raw(id, pin); @@ -1236,11 +1244,13 @@ mraa_init_io(const char* desc) } else if (strncmp(type, "SPI", 3) == 0) { if (raw) { if (mraa_init_io_helper(&str, &id, delim) != MRAA_SUCCESS) { - syslog(LOG_ERR, "mraa_init_io: Spi, unable to convert the bus string into a useable Int"); + syslog(LOG_ERR, + "mraa_init_io: Spi, unable to convert the bus string into a useable Int"); return NULL; } if (mraa_init_io_helper(&str, &pin, delim) != MRAA_SUCCESS) { - syslog(LOG_ERR, "mraa_init_io: Spi, unable to convert the cs string into a useable Int"); + syslog(LOG_ERR, + "mraa_init_io: Spi, unable to convert the cs string into a useable Int"); return NULL; } return (void*) mraa_spi_init_raw(id, pin); From f35e6bb3820e1497c32b3ed1a0f5815cfd7b0b8b Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Wed, 15 Jun 2016 15:59:51 +0300 Subject: [PATCH 7/8] Added back FIRMATABLE option to cmake and sources to avoid compilation errors when littleb is missing revert hello_gpio.py to original example Signed-off-by: Shiran Ben-Melech --- CMakeLists.txt | 1 + examples/python/hello_gpio.py | 11 ++--------- include/firmata/firmata.h | 4 ++++ src/CMakeLists.txt | 4 ++++ src/firmata/CMakeLists.txt | 13 ++++++++++--- src/firmata/firmata.c | 7 ++++++- src/firmata/firmata_mraa.c | 3 +++ 7 files changed, 30 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b3910bb3..8ef917a1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ option (BUILDSWIGNODE "Build swig node modules." ON) option (BUILDSWIGJAVA "Build Java API." OFF) option (USBPLAT "Detection USB platform." OFF) option (FIRMATA "Add Firmata support to mraa." OFF) +option (FIRMATABLE "Add Firmata BLE support to mraa." OFF) option (ONEWIRE "Add Onewire support to mraa." ON) option (IMRAA "Add Imraa support to mraa." OFF) option (FTDI4222 "Build with FTDI FT4222 subplatform support." OFF) diff --git a/examples/python/hello_gpio.py b/examples/python/hello_gpio.py index e4381b049..69ec0c756 100644 --- a/examples/python/hello_gpio.py +++ b/examples/python/hello_gpio.py @@ -23,15 +23,8 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import mraa -import time print (mraa.getVersion()) -mraa.addSubplatform(mraa.BLE_FIRMATA_BY_NAME, "FIRMATA") -x = mraa.Gpio(13 + 512) +x = mraa.Gpio(13) x.dir(mraa.DIR_OUT) -print "Blinking" -for i in range(10): - x.write(1) - time.sleep(0) - x.write(0) - time.sleep(1) +x.write(1) diff --git a/include/firmata/firmata.h b/include/firmata/firmata.h index 73e0c35ee..c1a2d879d 100644 --- a/include/firmata/firmata.h +++ b/include/firmata/firmata.h @@ -25,7 +25,9 @@ #pragma once #include "uart.h" +#ifdef FIRMATABLE #include "firmata_ble.h" +#endif #define MODE_INPUT 0x00 #define MODE_OUTPUT 0x01 @@ -91,8 +93,10 @@ typedef struct s_pin { typedef struct s_firmata { mraa_uart_context uart; +#ifdef FIRMATABLE lb_context* lb_ctx; bl_device* bl_dev; +#endif t_pin pins[128]; int i2cmsg[256][256]; int parse_command_len; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5e4ef612f..09effe2e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,10 @@ set (mraa_LIB_INCLUDE_DIRS if (FIRMATA) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFIRMATA=1") add_subdirectory (firmata) + + if (FIRMATABLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFIRMATABLE=1") + endif() endif () if (ONEWIRE) diff --git a/src/firmata/CMakeLists.txt b/src/firmata/CMakeLists.txt index 5100236cc..be899018f 100644 --- a/src/firmata/CMakeLists.txt +++ b/src/firmata/CMakeLists.txt @@ -1,9 +1,16 @@ if (FIRMATA) message (STATUS "INFO - Adding firmata backend support") - set (mraa_LIB_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO} + set (mraa_firmata_LIBS ${PROJECT_SOURCE_DIR}/src/firmata/firmata.c ${PROJECT_SOURCE_DIR}/src/firmata/firmata_mraa.c - ${PROJECT_SOURCE_DIR}/src/firmata/firmata_ble.c - PARENT_SCOPE ) + if (FIRMATABLE) + message (STATUS "INFO - Adding firmata ble backend support") + set (mraa_firmata_LIBS ${mraa_firmata_LIBS} + ${PROJECT_SOURCE_DIR}/src/firmata/firmata_ble.c + ) + endif () + set (mraa_LIB_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO} ${mraa_firmata_LIBS} + PARENT_SCOPE + ) endif () diff --git a/src/firmata/firmata.c b/src/firmata/firmata.c index 4d2e32463..5d2f176d6 100644 --- a/src/firmata/firmata.c +++ b/src/firmata/firmata.c @@ -56,7 +56,9 @@ firmata_write_internal(t_firmata* firmata_dev, const char* buf, size_t len) lb_result_t res = LB_ERROR_UNSPECIFIED; if (firmata_dev->uart != NULL) { mraa_uart_write(firmata_dev->uart, buf, len); - } else if (firmata_dev->lb_ctx != NULL) { + } +#ifdef FIRMATABLE + else if (firmata_dev->lb_ctx != NULL) { res = dl_lb_write_to_characteristic(firmata_dev->lb_ctx, firmata_dev->bl_dev, "6e400002-b5a3-f393-e0a9-e50e24dcca9e", len, (uint8_t*) buf); if (res < 0) { @@ -64,6 +66,7 @@ firmata_write_internal(t_firmata* firmata_dev, const char* buf, size_t len) return MRAA_ERROR_UNSPECIFIED; } } +#endif return MRAA_SUCCESS; } @@ -97,6 +100,7 @@ firmata_new(const char* name) return res; } +#ifdef FIRMATABLE t_firmata* firmata_ble_new(const char* name, mraa_platform_t type) { @@ -218,6 +222,7 @@ firmata_ble_close(t_firmata* firmata) syslog(LOG_ERR, "ERROR: lb_destroy\n"); } } +#endif void firmata_close(t_firmata* firmata) diff --git a/src/firmata/firmata_mraa.c b/src/firmata/firmata_mraa.c index ae2c356d5..4f440f1e6 100644 --- a/src/firmata/firmata_mraa.c +++ b/src/firmata/firmata_mraa.c @@ -550,6 +550,9 @@ mraa_firmata_plat_init(const char* uart_dev, mraa_platform_t type) } else if (type == MRAA_BLE_FIRMATA_BY_NAME || type == MRAA_BLE_FIRMATA_BY_ADDRESS) { +#ifndef FIRMATABLE + return NULL; +#endif firmata_dev = firmata_ble_new(uart_dev, type); if (firmata_dev == NULL) { syslog(LOG_WARNING, "firmata: Failed to open ble to Firmata dev on %s", uart_dev); From d8727262144901b9ac6fab909f195d93ff2067c2 Mon Sep 17 00:00:00 2001 From: Shiran Ben-Melech Date: Thu, 16 Jun 2016 15:35:42 +0300 Subject: [PATCH 8/8] changed firmata ble related code to match new littleb api Signed-off-by: Shiran Ben-Melech --- include/firmata/firmata.h | 4 ++-- include/firmata/firmata_ble.h | 36 +++++++++++++++++------------------ src/firmata/firmata.c | 10 +++++----- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/firmata/firmata.h b/include/firmata/firmata.h index c1a2d879d..ab40f8403 100644 --- a/include/firmata/firmata.h +++ b/include/firmata/firmata.h @@ -94,8 +94,8 @@ typedef struct s_pin { typedef struct s_firmata { mraa_uart_context uart; #ifdef FIRMATABLE - lb_context* lb_ctx; - bl_device* bl_dev; + lb_context lb_ctx; + lb_bl_device* bl_dev; #endif t_pin pins[128]; int i2cmsg[256][256]; diff --git a/include/firmata/firmata_ble.h b/include/firmata/firmata_ble.h index ef8f1239c..aa6a205cd 100644 --- a/include/firmata/firmata_ble.h +++ b/include/firmata/firmata_ble.h @@ -35,24 +35,24 @@ void* liblittleb_lib; lb_result_t (*dl_lb_init)(); lb_result_t (*dl_lb_destroy)(); -lb_context* (*dl_lb_context_new)(); -lb_result_t (*dl_lb_context_free)(lb_context*); -lb_result_t (*dl_lb_get_bl_devices)(lb_context*, int); -lb_result_t (*dl_lb_connect_device)(lb_context*, bl_device*); -lb_result_t (*dl_lb_disconnect_device)(lb_context*, bl_device*); -lb_result_t (*dl_lb_pair_device)(lb_context*, bl_device*); -lb_result_t (*dl_lb_unpair_device)(lb_context*, bl_device*); -lb_result_t (*dl_lb_get_ble_characteristic_by_characteristic_path)(lb_context*, bl_device*, const char*, ble_char**); -lb_result_t (*dl_lb_get_ble_characteristic_by_uuid)(lb_context*, bl_device*, const char*, ble_char**); -lb_result_t (*dl_lb_get_ble_service_by_service_path)(lb_context* lb_ctx, bl_device*, const char*, ble_service**); -lb_result_t (*dl_lb_get_ble_service_by_uuid)(lb_context*, bl_device*, const char*, ble_service**); -lb_result_t (*dl_lb_get_ble_device_services)(lb_context*, bl_device*); -lb_result_t (*dl_lb_get_device_by_device_path)(lb_context*, const char*, bl_device**); -lb_result_t (*dl_lb_get_device_by_device_name)(lb_context*, const char*, bl_device**); -lb_result_t (*dl_lb_get_device_by_device_address)(lb_context*, const char*, bl_device**); -lb_result_t (*dl_lb_write_to_characteristic)(lb_context*, bl_device*, const char*, int, uint8_t*); -lb_result_t (*dl_lb_read_from_characteristic)(lb_context*, bl_device*, const char*, size_t*, uint8_t**); -lb_result_t (*dl_lb_register_characteristic_read_event)(lb_context*,bl_device*, const char*, sd_bus_message_handler_t, void*); +lb_context (*dl_lb_context_new)(); +lb_result_t (*dl_lb_context_free)(lb_context); +lb_result_t (*dl_lb_get_bl_devices)(lb_context, int); +lb_result_t (*dl_lb_connect_device)(lb_context, lb_bl_device*); +lb_result_t (*dl_lb_disconnect_device)(lb_context, lb_bl_device*); +lb_result_t (*dl_lb_pair_device)(lb_context, lb_bl_device*); +lb_result_t (*dl_lb_unpair_device)(lb_context, lb_bl_device*); +lb_result_t (*dl_lb_get_ble_characteristic_by_characteristic_path)(lb_context, lb_bl_device*, const char*, lb_ble_char**); +lb_result_t (*dl_lb_get_ble_characteristic_by_uuid)(lb_context, lb_bl_device*, const char*, lb_ble_char**); +lb_result_t (*dl_lb_get_ble_service_by_service_path)(lb_context lb_ctx, lb_bl_device*, const char*, lb_ble_service**); +lb_result_t (*dl_lb_get_ble_service_by_uuid)(lb_context, lb_bl_device*, const char*, lb_ble_service**); +lb_result_t (*dl_lb_get_ble_device_services)(lb_context, lb_bl_device*); +lb_result_t (*dl_lb_get_device_by_device_path)(lb_context, const char*, lb_bl_device**); +lb_result_t (*dl_lb_get_device_by_device_name)(lb_context, const char*, lb_bl_device**); +lb_result_t (*dl_lb_get_device_by_device_address)(lb_context, const char*, lb_bl_device**); +lb_result_t (*dl_lb_write_to_characteristic)(lb_context, lb_bl_device*, const char*, int, uint8_t*); +lb_result_t (*dl_lb_read_from_characteristic)(lb_context, lb_bl_device*, const char*, size_t*, uint8_t**); +lb_result_t (*dl_lb_register_characteristic_read_event)(lb_context,lb_bl_device*, const char*, sd_bus_message_handler_t, void*); lb_result_t (*dl_lb_parse_uart_service_message)(sd_bus_message*, const void**, size_t*); mraa_result_t mraa_firmata_ble_init(); diff --git a/src/firmata/firmata.c b/src/firmata/firmata.c index 5d2f176d6..08467ce99 100644 --- a/src/firmata/firmata.c +++ b/src/firmata/firmata.c @@ -42,7 +42,7 @@ firmata_uart_read_handler(sd_bus_message* message, void* userdata, sd_bus_error* r = dl_lb_parse_uart_service_message(message, (const void**) &result, &size); if (r < 0) { syslog(LOG_ERR, "ERROR: couldn't parse uart message\n"); - return LB_ERROR_UNSPECIFIED; + return -MRAA_ERROR_UNSPECIFIED; } firmata_parse(firmata, result, size); @@ -53,17 +53,17 @@ firmata_uart_read_handler(sd_bus_message* message, void* userdata, sd_bus_error* inline int firmata_write_internal(t_firmata* firmata_dev, const char* buf, size_t len) { - lb_result_t res = LB_ERROR_UNSPECIFIED; + int r = MRAA_ERROR_UNSPECIFIED; if (firmata_dev->uart != NULL) { mraa_uart_write(firmata_dev->uart, buf, len); } #ifdef FIRMATABLE else if (firmata_dev->lb_ctx != NULL) { - res = dl_lb_write_to_characteristic(firmata_dev->lb_ctx, firmata_dev->bl_dev, + r = dl_lb_write_to_characteristic(firmata_dev->lb_ctx, firmata_dev->bl_dev, "6e400002-b5a3-f393-e0a9-e50e24dcca9e", len, (uint8_t*) buf); - if (res < 0) { + if (r < 0) { syslog(LOG_ERR, "ERROR: lb_write_to_characteristic\n"); - return MRAA_ERROR_UNSPECIFIED; + return -MRAA_ERROR_UNSPECIFIED; } } #endif