You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/07/28 00:18:56 UTC

[17/28] incubator-mynewt-core git commit: BLEuart app

BLEuart app

- Add a new exampel for BLE uart app
- Make a library for the same
- Currently the library is string based, soon to become binary.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/a4494fef
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/a4494fef
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/a4494fef

Branch: refs/heads/sterly_refactor
Commit: a4494fefbff6eff4a1b1401ebb586e31f7c9d2bd
Parents: f06c2d2
Author: Vipul Rahane <vi...@runtime.io>
Authored: Thu Jul 21 18:50:42 2016 -0700
Committer: Sterling Hughes <st...@apache.org>
Committed: Wed Jul 27 17:18:28 2016 -0700

----------------------------------------------------------------------
 apps/bleuart/pkg.yml                   |  41 ++++
 apps/bleuart/src/main.c                | 354 ++++++++++++++++++++++++++++
 libs/bleuart/include/bleuart/bleuart.h |  34 +++
 libs/bleuart/pkg.yml                   |  34 +++
 libs/bleuart/src/bleuart.c             | 204 ++++++++++++++++
 5 files changed, 667 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a4494fef/apps/bleuart/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bleuart/pkg.yml b/apps/bleuart/pkg.yml
new file mode 100644
index 0000000..a79077f
--- /dev/null
+++ b/apps/bleuart/pkg.yml
@@ -0,0 +1,41 @@
+# 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.
+#
+pkg.name: apps/bleuart
+pkg.type: app
+pkg.description: Simple BLE uart application.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - libs/os
+    - sys/log
+    - net/nimble/controller
+    - net/nimble/host
+    - net/nimble/host/services/mandatory
+    - net/nimble/host/store/ram
+    - libs/console/full
+    - libs/baselibc
+    - libs/newtmgr
+    - libs/newtmgr/transport/ble
+    - libs/bleuart
+
+pkg.cflags:
+    # Disable unused roles; bleuart is a peripheral-only app.
+    - "-DNIMBLE_OPT_ROLE_OBSERVER=0"
+    - "-DNIMBLE_OPT_ROLE_CENTRAL=0"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a4494fef/apps/bleuart/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bleuart/src/main.c b/apps/bleuart/src/main.c
new file mode 100755
index 0000000..8cae471
--- /dev/null
+++ b/apps/bleuart/src/main.c
@@ -0,0 +1,354 @@
+/**
+ * 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 <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include "bsp/bsp.h"
+#include "os/os.h"
+#include "bsp/bsp.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_cputime.h"
+#include <imgmgr/imgmgr.h>
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/host_hci.h"
+#include "host/ble_hs.h"
+#include "host/ble_hs_adv.h"
+#include "host/ble_uuid.h"
+#include "host/ble_att.h"
+#include "host/ble_gap.h"
+#include "host/ble_gatt.h"
+#include "host/ble_l2cap.h"
+#include "host/ble_sm.h"
+#include "controller/ble_ll.h"
+/* Newtmgr include */
+#include "newtmgr/newtmgr.h"
+#include "nmgrble/newtmgr_ble.h"
+#include "bleuart/bleuart.h"
+
+/* RAM persistence layer. */
+#include "store/ram/ble_store_ram.h"
+
+/* Mandatory services. */
+#include "services/mandatory/ble_svc_gap.h"
+#include "services/mandatory/ble_svc_gatt.h"
+
+/** Mbuf settings. */
+#define MBUF_NUM_MBUFS      (12)
+#define MBUF_BUF_SIZE       OS_ALIGN(BLE_MBUF_PAYLOAD_SIZE, 4)
+#define MBUF_MEMBLOCK_SIZE  (MBUF_BUF_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD)
+#define MBUF_MEMPOOL_SIZE   OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE)
+
+#define MAX_CONSOLE_INPUT 120
+static os_membuf_t bleuart_mbuf_mpool_data[MBUF_MEMPOOL_SIZE];
+struct os_mbuf_pool bleuart_mbuf_pool;
+struct os_mempool bleuart_mbuf_mpool;
+
+/** Priority of the nimble host and controller tasks. */
+#define BLE_LL_TASK_PRI             (OS_TASK_PRI_HIGHEST)
+
+/** bleuart task settings. */
+#define bleuart_TASK_PRIO           1
+#define bleuart_STACK_SIZE          (OS_STACK_ALIGN(336))
+
+#define NEWTMGR_TASK_PRIO (4)
+#define NEWTMGR_TASK_STACK_SIZE (OS_STACK_ALIGN(512))
+os_stack_t newtmgr_stack[NEWTMGR_TASK_STACK_SIZE];
+
+struct os_eventq bleuart_evq;
+struct os_task bleuart_task;
+bssnz_t os_stack_t bleuart_stack[bleuart_STACK_SIZE];
+
+/** Our global device address (public) */
+uint8_t g_dev_addr[BLE_DEV_ADDR_LEN] = {0xba, 0xaa, 0xad, 0xba, 0xaa, 0xad};
+
+/** Our random address (in case we need it) */
+uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
+
+static int bleuart_gap_event(struct ble_gap_event *event, void *arg);
+
+/**
+ * Enables advertising with the following parameters:
+ *     o General discoverable mode.
+ *     o Undirected connectable mode.
+ */
+static void
+bleuart_advertise(void)
+{
+    struct ble_gap_adv_params adv_params;
+    struct ble_hs_adv_fields fields;
+    //const char *name;
+    int rc;
+
+    /**
+     *  Set the advertisement data included in our advertisements:
+     *     o Flags (indicates advertisement type and other general info).
+     *     o Advertising tx power.
+     *     o Device name.
+     *     o 16-bit service UUIDs (alert notifications).
+     */
+
+    memset(&fields, 0, sizeof fields);
+
+    /* Indicate that the flags field should be included; specify a value of 0
+     * to instruct the stack to fill the value in for us.
+     */
+    fields.flags_is_present = 1;
+    fields.flags = 0;
+
+    /* Indicate that the TX power level field should be included; have the
+     * stack fill this one automatically as well.  This is done by assiging the
+     * special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
+     */
+    fields.tx_pwr_lvl_is_present = 1;
+    fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+
+    fields.uuids128 = (void *)gatt_svr_svc_uart;
+    fields.num_uuids128 = 1;
+    fields.uuids128_is_complete = 1;
+
+    rc = ble_gap_adv_set_fields(&fields);
+    if (rc != 0) {
+        return;
+    }
+
+    /* Begin advertising. */
+    memset(&adv_params, 0, sizeof adv_params);
+    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
+    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+    rc = ble_gap_adv_start(BLE_ADDR_TYPE_PUBLIC, 0, NULL, BLE_HS_FOREVER,
+                           &adv_params, bleuart_gap_event, NULL);
+    if (rc != 0) {
+        return;
+    }
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that forms.
+ * bleuart uses the same callback for all connections.
+ *
+ * @param event                 The type of event being signalled.
+ * @param ctxt                  Various information pertaining to the event.
+ * @param arg                   Application-specified argument; unuesd by
+ *                                  bleuart.
+ *
+ * @return                      0 if the application successfully handled the
+ *                                  event; nonzero on failure.  The semantics
+ *                                  of the return code is specific to the
+ *                                  particular GAP event being signalled.
+ */
+static int
+bleuart_gap_event(struct ble_gap_event *event, void *arg)
+{
+    struct ble_gap_conn_desc desc;
+    int rc;
+
+    switch (event->type) {
+    case BLE_GAP_EVENT_CONNECT:
+        /* A new connection was established or a connection attempt failed. */
+        if (event->connect.status == 0) {
+            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+            assert(rc == 0);
+            bleuart_set_conn_handle(event->connect.conn_handle);
+        }
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            bleuart_advertise();
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        /* Connection terminated; resume advertising. */
+        bleuart_advertise();
+        return 0;
+
+    }
+
+    return 0;
+}
+
+/**
+ * Event loop for the main bleuart task.
+ */
+static void
+bleuart_task_handler(void *unused)
+{
+    struct os_event *ev;
+    struct os_callout_func *cf;
+    int rc;
+
+    rc = ble_hs_start();
+    assert(rc == 0);
+
+    /* Begin advertising. */
+    bleuart_advertise();
+
+    while (1) {
+        ev = os_eventq_get(&bleuart_evq);
+
+        /* Check if the event is a nmgr ble mqueue event */
+        rc = nmgr_ble_proc_mq_evt(ev);
+        if (!rc) {
+            continue;
+        }
+
+        switch (ev->ev_type) {
+        case OS_EVENT_T_TIMER:
+            cf = (struct os_callout_func *)ev;
+            assert(cf->cf_func);
+            cf->cf_func(CF_ARG(cf));
+            break;
+        default:
+            assert(0);
+            break;
+        }
+    }
+}
+
+/**
+ * main
+ *
+ * The main function for the project. This function initializes the os, calls
+ * init_tasks to initialize tasks (and possibly other objects), then starts the
+ * OS. We should not return from os start.
+ *
+ * @return int NOTE: this function should never return!
+ */
+int
+main(void)
+{
+    struct ble_hs_cfg cfg;
+    uint32_t seed;
+    int rc;
+    int i;
+
+    /* Initialize OS */
+    os_init();
+
+    /* Set cputime to count at 1 usec increments */
+    rc = cputime_init(1000000);
+    assert(rc == 0);
+
+    /* Seed random number generator with least significant bytes of device
+     * address.
+     */
+    seed = 0;
+    for (i = 0; i < 4; ++i) {
+        seed |= g_dev_addr[i];
+        seed <<= 8;
+    }
+    srand(seed);
+
+    /* Initialize msys mbufs. */
+    rc = os_mempool_init(&bleuart_mbuf_mpool, MBUF_NUM_MBUFS,
+                         MBUF_MEMBLOCK_SIZE, bleuart_mbuf_mpool_data,
+                         "bleuart_mbuf_data");
+    assert(rc == 0);
+
+    rc = os_mbuf_pool_init(&bleuart_mbuf_pool, &bleuart_mbuf_mpool,
+                           MBUF_MEMBLOCK_SIZE, MBUF_NUM_MBUFS);
+    assert(rc == 0);
+
+    rc = os_msys_register(&bleuart_mbuf_pool);
+    assert(rc == 0);
+
+    os_task_init(&bleuart_task, "bleuart", bleuart_task_handler,
+                 NULL, bleuart_TASK_PRIO, OS_WAIT_FOREVER,
+                 bleuart_stack, bleuart_STACK_SIZE);
+
+    /* Initialize the BLE LL */
+    rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE);
+    assert(rc == 0);
+
+    /* Initialize the BLE host. */
+    cfg = ble_hs_cfg_dflt;
+    cfg.max_hci_bufs = 3;
+    cfg.max_connections = 1;
+    cfg.max_gattc_procs = 2;
+    cfg.max_l2cap_chans = 3;
+    cfg.max_l2cap_sig_procs = 1;
+    cfg.sm_bonding = 1;
+    cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
+    cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
+    cfg.store_read_cb = ble_store_ram_read;
+    cfg.store_write_cb = ble_store_ram_write;
+
+    /* Populate config with the required GATT server settings. */
+    cfg.max_attrs = 0;
+    cfg.max_services = 0;
+    cfg.max_client_configs = 0;
+
+    rc = ble_svc_gap_init(&cfg);
+    assert(rc == 0);
+
+    rc = ble_svc_gatt_init(&cfg);
+    assert(rc == 0);
+
+    /* Nmgr ble GATT server initialization */
+    rc = nmgr_ble_gatt_svr_init(&bleuart_evq, &cfg);
+    assert(rc == 0);
+
+    rc = bleuart_gatt_svr_init(&cfg);
+    assert(rc == 0);
+
+    /* Initialize eventq */
+    os_eventq_init(&bleuart_evq);
+
+    rc = ble_hs_init(&bleuart_evq, &cfg);
+    assert(rc == 0);
+
+    bleuart_init(MAX_CONSOLE_INPUT);
+
+    nmgr_task_init(NEWTMGR_TASK_PRIO, newtmgr_stack, NEWTMGR_TASK_STACK_SIZE);
+    imgmgr_module_init();
+
+    /* Register GATT attributes (services, characteristics, and
+     * descriptors).
+     */
+    rc = ble_svc_gap_register();
+    assert(rc == 0);
+
+    rc = ble_svc_gatt_register();
+    assert(rc == 0);
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set("Mynewt_BLEuart");
+    assert(rc == 0);
+
+    /* Nmgr ble GATT server initialization */
+    rc = nmgr_ble_svc_register();
+    assert(rc == 0);
+
+    /* bleuart GATT server initialization */
+    rc = bleuart_svc_register();
+    assert(rc == 0);
+
+    /* Start the OS */
+    os_start();
+
+    /* os start should never return. If it does, this should be an error */
+    assert(0);
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a4494fef/libs/bleuart/include/bleuart/bleuart.h
----------------------------------------------------------------------
diff --git a/libs/bleuart/include/bleuart/bleuart.h b/libs/bleuart/include/bleuart/bleuart.h
new file mode 100644
index 0000000..14ae930
--- /dev/null
+++ b/libs/bleuart/include/bleuart/bleuart.h
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+#ifndef _BLEUART_H_
+#define _BLEUART_H_
+
+int
+bleuart_init(int max_input);
+int
+bleuart_svc_register(void);
+int
+bleuart_gatt_svr_init(struct ble_hs_cfg *cfg);
+void
+bleuart_set_conn_handle(uint16_t conn_handle);
+
+extern const uint8_t gatt_svr_svc_uart[16];
+
+#endif /* _BLEUART_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a4494fef/libs/bleuart/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/bleuart/pkg.yml b/libs/bleuart/pkg.yml
new file mode 100644
index 0000000..5173293
--- /dev/null
+++ b/libs/bleuart/pkg.yml
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+pkg.name: libs/bleuart
+pkg.description: BLE uart service.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - ble
+    - bluetooth
+    - uart
+
+pkg.deps:
+    - libs/os
+    - net/nimble/host
+
+pkg.req_apis:
+    - console

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a4494fef/libs/bleuart/src/bleuart.c
----------------------------------------------------------------------
diff --git a/libs/bleuart/src/bleuart.c b/libs/bleuart/src/bleuart.c
new file mode 100644
index 0000000..07b0855
--- /dev/null
+++ b/libs/bleuart/src/bleuart.c
@@ -0,0 +1,204 @@
+/**
+ * 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 <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "host/ble_hs.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;
+
+/* Console max input */
+uint16_t console_max_input;
+
+uint16_t g_console_conn_handle;
+/**
+ * The vendor specific "bleuart" service consists of one write no-rsp characteristic
+ *     o "write no-rsp": a single-byte characteristic that can always be read, but
+ *       can only be written over an encrypted connection.
+ *     o "read": a single-byte characteristic taht can always be read but can
+ *       only be written over an encrypted connection
+ */
+
+/* {6E400001-B5A3-F393-E0A9-E50E24DCCA9E} */
+const uint8_t gatt_svr_svc_uart[16] = {
+    0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+    0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e
+};
+
+/* {6E400002-B5A3-F393-E0A9-E50E24DCCA9E} */
+const uint8_t gatt_svr_chr_uart_write[16] = {
+    0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+    0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e
+};
+
+
+/* {6E400003-B5A3-F393-E0A9-E50E24DCCA9E} */
+const uint8_t gatt_svr_chr_uart_read[16] = {
+    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,
+        .uuid128 = (void *)gatt_svr_svc_uart,
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = gatt_svr_chr_uart_read,
+            .val_handle = &g_bleuart_attr_read_handle,
+            .access_cb = gatt_svr_chr_access_uart_write,
+            .flags = BLE_GATT_CHR_F_NOTIFY,
+        }, {
+            /* Characteristic: Write */
+            .uuid128 = (void *)gatt_svr_chr_uart_write,
+            .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)
+{
+    switch (ctxt->op) {
+        case BLE_GATT_ACCESS_OP_WRITE_CHR:
+              console_write(ctxt->att->write.data, ctxt->att->write.len);
+              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(struct ble_hs_cfg *cfg)
+{
+    int rc;
+
+    rc = ble_gatts_count_cfg(gatt_svr_svcs, cfg);
+    if (rc != 0) {
+        goto err;
+    }
+
+err:
+    return rc;
+}
+
+/**
+ * Register ble uart service
+ *
+ * @return 0 on success; non-zero on failure
+ */
+int
+bleuart_svc_register(void)
+{
+
+    int rc;
+    rc = ble_gatts_register_svcs(gatt_svr_svcs, NULL, NULL);
+    return rc;
+
+}
+
+/**
+ * Reads console and sends data over BLE
+ */
+static void
+bleuart_uart_read(void)
+{
+    int rc;
+    int off;
+    int full_line;
+
+    off = 0;
+    while (1) {
+        rc = console_read(console_buf + off,
+                          console_max_input - off, &full_line);
+        if (rc <= 0 && !full_line) {
+            continue;
+        }
+        off += rc;
+        if (!full_line) {
+            continue;
+        }
+
+        ble_gattc_notify_custom(g_console_conn_handle, g_bleuart_attr_read_handle,
+                                console_buf, off);
+        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
+ */
+int
+bleuart_init(int max_input)
+{
+    int rc;
+
+    rc = console_init(bleuart_uart_read);
+    assert(rc == 0);
+
+    console_buf = malloc(max_input);
+    console_max_input = max_input;
+    assert(console_buf);
+    return 0;
+}