You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/12/24 00:34:32 UTC

[3/6] incubator-mynewt-larva git commit: Initial implementation of GATT server.

Initial implementation of GATT server.


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

Branch: refs/heads/master
Commit: e949b8ab29bcb1f48f786c3c82e431f07cd49be3
Parents: 2c857eb
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Dec 23 13:45:27 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Dec 23 15:33:32 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gatt.h |  27 +++++
 net/nimble/host/src/ble_gatt_priv.h     |   7 +-
 net/nimble/host/src/ble_gatts.c         | 147 +++++++++++++++++++++++++++
 3 files changed, 179 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/e949b8ab/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
index 7b59d26..cbb0338 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -18,10 +18,12 @@
 #define H_BLE_GATT_
 
 #include <inttypes.h>
+#include "host/ble_att.h"
 struct ble_hs_conn;
 struct ble_att_error_rsp;
 struct ble_att_clt_adata;
 
+/*** @client. */
 struct ble_gatt_service {
     uint16_t start_handle;
     uint16_t end_handle;
@@ -69,4 +71,29 @@ int ble_gatt_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
 int ble_gatt_exchange_mtu(uint16_t conn_handle);
 int ble_gatt_init(void);
 
+/*** @server. */
+struct ble_gatt_desc_def {
+    uint8_t *uuid128;
+    ble_att_svr_handle_func *access_cb;
+};
+
+struct ble_gatt_char_def {
+    uint8_t properties;
+    uint8_t *uuid128;
+    ble_att_svr_handle_func *access_cb;
+};
+
+#define BLE_GATT_SVC_TYPE_END       0
+#define BLE_GATT_SVC_TYPE_PRIMARY   1
+#define BLE_GATT_SVC_TYPE_SECONDAY  2
+
+struct ble_gatt_svc_def {
+    uint8_t type;
+    uint8_t *uuid128;
+    struct ble_gatt_svc_def **includes; /* Terminated with null. */
+    struct ble_gatt_char_def *characteristics;
+};
+
+int ble_gatt_register_services(const struct ble_gatt_svc_def *svcs);
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/e949b8ab/net/nimble/host/src/ble_gatt_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt_priv.h b/net/nimble/host/src/ble_gatt_priv.h
index 8a7e850..51dfc27 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -22,10 +22,10 @@
 #define BLE_GATT_CHR_DECL_SZ_16     5
 #define BLE_GATT_CHR_DECL_SZ_128    19
 
-/*** @gen */
+/*** @gen. */
 void ble_gatt_connection_broken(uint16_t conn_handle);
 
-/*** @client */
+/*** @client. */
 int ble_gattc_disc_all_services(uint16_t conn_handle,
                                ble_gatt_disc_service_fn *cb,
                                void *cb_arg);
@@ -64,4 +64,7 @@ void ble_gattc_connection_broken(uint16_t conn_handle);
 
 int ble_gattc_init(void);
 
+/*** @server. */
+int ble_gatts_register_services(const struct ble_gatt_svc_def *svcs);
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/e949b8ab/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
new file mode 100644
index 0000000..8dbc435
--- /dev/null
+++ b/net/nimble/host/src/ble_gatts.c
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+#include "ble_hs_priv.h"
+#include "ble_gatt_priv.h"
+
+#define BLE_GATTS_MAX_SERVICES  32 /* XXX: Make this configurable. */
+
+struct ble_gatts_svc_entry {
+    const struct ble_gatt_svc_def *svc;
+    uint16_t handle;    /* 0 means unregistered. */
+};
+
+static struct ble_gatts_svc_entry
+    ble_gatts_svc_entries[BLE_GATTS_MAX_SERVICES];
+static int ble_gatts_num_svc_entries;
+
+static int
+ble_gatts_svc_access(struct ble_att_svr_entry *entry, uint8_t op,
+                     union ble_att_svr_handle_arg *arg)
+{
+    return 0;
+}
+
+static int
+ble_gatts_service_includes_satisfied(const struct ble_gatt_svc_def *svc)
+{
+    const struct ble_gatt_svc_def *incl;
+    int i;
+
+    if (svc->includes == NULL) {
+        /* No included services. */
+        return 1;
+    }
+
+    for (incl = *svc->includes; incl != NULL; incl++) {
+        for (i = 0; i < ble_gatts_num_svc_entries; i++) {
+            if (ble_gatts_svc_entries[i].handle == 0) {
+                return 0;
+            } else {
+                break;
+            }
+        }
+    }
+
+    return 1;
+}
+
+static int
+ble_gatts_register_service(const struct ble_gatt_svc_def *svc,
+                           uint16_t *out_handle)
+{
+    int rc;
+
+    if (!ble_gatts_service_includes_satisfied(svc)) {
+        return BLE_HS_EAGAIN;
+    }
+
+    rc = ble_att_svr_register(svc->uuid128, HA_FLAG_PERM_READ, out_handle,
+                              ble_gatts_svc_access);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+ble_gatts_register_round(int *out_num_registered)
+{
+    struct ble_gatts_svc_entry *entry;
+    uint16_t handle;
+    int rc;
+    int i;
+
+    *out_num_registered = 0;
+    for (i = 0; i < ble_gatts_num_svc_entries; i++) {
+        entry = ble_gatts_svc_entries + i;
+
+        if (entry->handle == 0) {
+            rc = ble_gatts_register_service(entry->svc, &handle);
+            switch (rc) {
+            case 0:
+                /* Service successfully registered. */
+                entry->handle = handle;
+                (*out_num_registered)++;
+                /* XXX: Call callback. */
+                break;
+
+            case BLE_HS_EAGAIN:
+                /* Service could not be registered due to unsatisfied includes.
+                 * Try again on the next itereation.
+                 */
+                break;
+
+            default:
+                return rc;
+            }
+        }
+    }
+
+    if (*out_num_registered == 0) {
+        return BLE_HS_EAPP; // XXX
+    }
+
+    return 0;
+}
+
+int
+ble_gatts_register_services(const struct ble_gatt_svc_def *svcs)
+{
+    int total_registered;
+    int cur_registered;
+    int rc;
+    int i;
+
+    for (i = 0; svcs[i].type != BLE_GATT_SVC_TYPE_END; i++) {
+        ble_gatts_svc_entries[i].svc = svcs + i;
+        ble_gatts_svc_entries[i].handle = 0;
+    }
+    ble_gatts_num_svc_entries = i;
+
+    total_registered = 0;
+    while (total_registered < ble_gatts_num_svc_entries) {
+        rc = ble_gatts_register_round(&cur_registered);
+        if (rc != 0) {
+            return rc;
+        }
+        total_registered += cur_registered;
+    }
+
+    return 0;
+}