xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/services/ias/src/ble_svc_ias.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <assert.h>
21 #include <string.h>
22 #include "sysinit/sysinit.h"
23 #include "host/ble_hs.h"
24 #include "services/ias/ble_svc_ias.h"
25 
26 /* Callback function */
27 static ble_svc_ias_event_fn *ble_svc_ias_cb_fn;
28 
29 /* Alert level */
30 static uint8_t ble_svc_ias_alert_level;
31 
32 /* Write characteristic function */
33 static int
34 ble_svc_ias_chr_write(struct os_mbuf *om, uint16_t min_len,
35                       uint16_t max_len, void *dst,
36                       uint16_t *len);
37 
38 /* Access function */
39 static int
40 ble_svc_ias_access(uint16_t conn_handle, uint16_t attr_handle,
41                    struct ble_gatt_access_ctxt *ctxt, void *arg);
42 
43 static const struct ble_gatt_svc_def ble_svc_ias_defs[] = {
44     {
45         /*** Service: Immediate Alert Service (IAS). */
46         .type = BLE_GATT_SVC_TYPE_PRIMARY,
47         .uuid = BLE_UUID16_DECLARE(BLE_SVC_IAS_UUID16),
48         .characteristics = (struct ble_gatt_chr_def[]) { {
49             /*** Characteristic: Alert Level. */
50             .uuid = BLE_UUID16_DECLARE(BLE_SVC_IAS_CHR_UUID16_ALERT_LEVEL),
51             .access_cb = ble_svc_ias_access,
52             .flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
53         }, {
54             0, /* No more characteristics in this service. */
55         } },
56     },
57 
58     {
59         0, /* No more services. */
60     },
61 };
62 
63 /**
64  * Writes the received value from a characteristic write to
65  * the given destination.
66  */
67 static int
ble_svc_ias_chr_write(struct os_mbuf * om,uint16_t min_len,uint16_t max_len,void * dst,uint16_t * len)68 ble_svc_ias_chr_write(struct os_mbuf *om, uint16_t min_len,
69                       uint16_t max_len, void *dst,
70                       uint16_t *len)
71 {
72     uint16_t om_len;
73     int rc;
74 
75     om_len = OS_MBUF_PKTLEN(om);
76     if (om_len < min_len || om_len > max_len) {
77         return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
78     }
79 
80     rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
81     if (rc != 0) {
82         return BLE_ATT_ERR_UNLIKELY;
83     }
84 
85     return 0;
86 }
87 
88 /**
89  * Simple write access callback for the alert level
90  * characteristic.
91  */
92 static int
ble_svc_ias_access(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)93 ble_svc_ias_access(uint16_t conn_handle, uint16_t attr_handle,
94                    struct ble_gatt_access_ctxt *ctxt, void *arg)
95 {
96     int rc;
97 
98     assert(ctxt->chr == &ble_svc_ias_defs[0].characteristics[0]);
99 
100     switch (ctxt->op) {
101     case BLE_GATT_ACCESS_OP_WRITE_CHR:
102         rc = ble_svc_ias_chr_write(ctxt->om,
103                                    sizeof ble_svc_ias_alert_level,
104                                    sizeof ble_svc_ias_alert_level,
105                                    &ble_svc_ias_alert_level, NULL);
106 	/* Call the IAS event function */
107 	if (ble_svc_ias_cb_fn) {
108 		ble_svc_ias_cb_fn(ble_svc_ias_alert_level);
109 	}
110         return rc;
111 
112     default:
113         assert(0);
114         return BLE_ATT_ERR_UNLIKELY;
115     }
116 
117     return 0;
118 }
119 
120 /**
121  * Designates the specified function as the IAS callback.  This callback is
122  * necessary for this service to function properly.
123  *
124  * @param cb                        The callback function to call when
125  *                                      the client signals an alert.
126  */
127 void
ble_svc_ias_set_cb(ble_svc_ias_event_fn * cb)128 ble_svc_ias_set_cb(ble_svc_ias_event_fn *cb)
129 {
130     ble_svc_ias_cb_fn = cb;
131 }
132 
133 /**
134  * Initialize the IAS package.
135  */
136 void
ble_svc_ias_init(void)137 ble_svc_ias_init(void)
138 {
139     int rc;
140 
141     /* Ensure this function only gets called by sysinit. */
142     SYSINIT_ASSERT_ACTIVE();
143 
144     rc = ble_gatts_count_cfg(ble_svc_ias_defs);
145     SYSINIT_PANIC_ASSERT(rc == 0);
146 
147     rc = ble_gatts_add_svcs(ble_svc_ias_defs);
148     SYSINIT_PANIC_ASSERT(rc == 0);
149 }
150