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;
+}