/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include #include #include #include #include "sysinit/sysinit.h" #include "host/ble_hs.h" #include "host/ble_uuid.h" #include "bleuart/bleuart.h" #include "os/endian.h" #include "console/console.h" /* ble uart attr read handle */ uint16_t g_bleuart_attr_read_handle; /* ble uart attr write handle */ uint16_t g_bleuart_attr_write_handle; /* Pointer to a console buffer */ char *console_buf; uint16_t g_console_conn_handle; /** * The vendor specific "bleuart" service consists of one write no-rsp characteristic * and one notification only read charateristic * o "write no-rsp": a single-byte characteristic that can be written only * over a non-encrypted connection * o "read": a single-byte characteristic that can always be read only via * notifications */ /* {6E400001-B5A3-F393-E0A9-E50E24DCCA9E} */ const ble_uuid128_t gatt_svr_svc_uart_uuid = BLE_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e); /* {6E400002-B5A3-F393-E0A9-E50E24DCCA9E} */ const ble_uuid128_t gatt_svr_chr_uart_write_uuid = BLE_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e); /* {6E400003-B5A3-F393-E0A9-E50E24DCCA9E} */ const ble_uuid128_t gatt_svr_chr_uart_read_uuid = BLE_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e); static int gatt_svr_chr_access_uart_write(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); static const struct ble_gatt_svc_def gatt_svr_svcs[] = { { /* Service: uart */ .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &gatt_svr_svc_uart_uuid.u, .characteristics = (struct ble_gatt_chr_def[]) { { .uuid = &gatt_svr_chr_uart_read_uuid.u, .val_handle = &g_bleuart_attr_read_handle, .access_cb = gatt_svr_chr_access_uart_write, .flags = BLE_GATT_CHR_F_NOTIFY, }, { /* Characteristic: Write */ .uuid = &gatt_svr_chr_uart_write_uuid.u, .access_cb = gatt_svr_chr_access_uart_write, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_NO_RSP, .val_handle = &g_bleuart_attr_write_handle, }, { 0, /* No more characteristics in this service */ } }, }, { 0, /* No more services */ }, }; static int gatt_svr_chr_access_uart_write(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { struct os_mbuf *om = ctxt->om; switch (ctxt->op) { case BLE_GATT_ACCESS_OP_WRITE_CHR: while(om) { console_write((char *)om->om_data, om->om_len); om = SLIST_NEXT(om, om_next); } console_write("\n", 1); return 0; default: assert(0); return BLE_ATT_ERR_UNLIKELY; } } /** * bleuart GATT server initialization * * @param eventq * @return 0 on success; non-zero on failure */ int bleuart_gatt_svr_init(void) { int rc; rc = ble_gatts_count_cfg(gatt_svr_svcs); if (rc != 0) { goto err; } rc = ble_gatts_add_svcs(gatt_svr_svcs); if (rc != 0) { return rc; } err: return rc; } /** * Reads console and sends data over BLE */ static void bleuart_uart_read(void) { int rc; int off; int full_line; struct os_mbuf *om; off = 0; while (1) { rc = console_read(console_buf + off, MYNEWT_VAL(BLEUART_MAX_INPUT) - off, &full_line); if (rc <= 0 && !full_line) { continue; } off += rc; if (!full_line) { continue; } om = ble_hs_mbuf_from_flat(console_buf, off); if (!om) { return; } ble_gatts_notify_custom(g_console_conn_handle, g_bleuart_attr_read_handle, om); off = 0; break; } } /** * Sets the global connection handle * * @param connection handle */ void bleuart_set_conn_handle(uint16_t conn_handle) { g_console_conn_handle = conn_handle; } /** * BLEuart console initialization * * @param Maximum input */ void bleuart_init(void) { int rc; /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); rc = console_init(bleuart_uart_read); SYSINIT_PANIC_ASSERT(rc == 0); console_buf = malloc(MYNEWT_VAL(BLEUART_MAX_INPUT)); SYSINIT_PANIC_ASSERT(console_buf != NULL); }