xref: /nrf52832-nimble/packages/NimBLE-latest/apps/bleuart/src/bleuart.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 <stdio.h>
23 #include <errno.h>
24 
25 /* BLE */
26 #include "nimble/ble.h"
27 #include "host/ble_hs.h"
28 #include "host/ble_hs_adv.h"
29 #include "host/ble_uuid.h"
30 #include "host/ble_att.h"
31 #include "host/ble_gap.h"
32 #include "host/ble_gatt.h"
33 #include "host/ble_l2cap.h"
34 #include "host/ble_sm.h"
35 
36 /* bluetooth transport. */
37 #include "nimble/ble_hci_trans.h"
38 
39 /* Mandatory services. */
40 #include "services/gap/ble_svc_gap.h"
41 #include "services/gatt/ble_svc_gatt.h"
42 
43 /* Newtmgr include */
44 #include "bleuart/bleuart.h"
45 
46 #include <rtthread.h>
47 #include <rtdevice.h>
48 
49 static int bleuart_gap_event(struct ble_gap_event *event, void *arg);
50 
51 /**
52  * Enables advertising with the following parameters:
53  *     o General discoverable mode.
54  *     o Undirected connectable mode.
55  */
56 static void
bleuart_advertise(void)57 bleuart_advertise(void)
58 {
59     struct ble_gap_adv_params adv_params;
60     struct ble_hs_adv_fields fields;
61     int rc;
62 
63     /*
64      *  Set the advertisement data included in our advertisements:
65      *     o Flags (indicates advertisement type and other general info).
66      *     o Advertising tx power.
67      *     o 128 bit UUID
68      */
69 
70     memset(&fields, 0, sizeof fields);
71 
72     /* Advertise two flags:
73      *     o Discoverability in forthcoming advertisement (general)
74      *     o BLE-only (BR/EDR unsupported).
75      */
76     fields.flags = BLE_HS_ADV_F_DISC_GEN |
77                    BLE_HS_ADV_F_BREDR_UNSUP;
78 
79     /* Indicate that the TX power level field should be included; have the
80      * stack fill this value automatically.  This is done by assiging the
81      * special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
82      */
83     fields.tx_pwr_lvl_is_present = 1;
84     fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
85 
86     fields.uuids128 = BLE_UUID128(&gatt_svr_svc_uart_uuid.u);
87     fields.num_uuids128 = 1;
88     fields.uuids128_is_complete = 1;
89 
90     rc = ble_gap_adv_set_fields(&fields);
91     if (rc != 0) {
92         return;
93     }
94 
95     memset(&fields, 0, sizeof fields);
96     fields.name = (uint8_t *)ble_svc_gap_device_name();
97     fields.name_len = strlen((char *)fields.name);
98     fields.name_is_complete = 1;
99 
100     rc = ble_gap_adv_rsp_set_fields(&fields);
101     if (rc != 0) {
102         return;
103     }
104 
105     /* Begin advertising. */
106     memset(&adv_params, 0, sizeof adv_params);
107     adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
108     adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
109     rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
110                            &adv_params, bleuart_gap_event, NULL);
111     if (rc != 0) {
112         return;
113     }
114 }
115 
116 /**
117  * The nimble host executes this callback when a GAP event occurs.  The
118  * application associates a GAP event callback with each connection that forms.
119  * bleuart uses the same callback for all connections.
120  *
121  * @param event                 The type of event being signalled.
122  * @param ctxt                  Various information pertaining to the event.
123  * @param arg                   Application-specified argument; unuesd by
124  *                                  bleuart.
125  *
126  * @return                      0 if the application successfully handled the
127  *                                  event; nonzero on failure.  The semantics
128  *                                  of the return code is specific to the
129  *                                  particular GAP event being signalled.
130  */
131 static int
bleuart_gap_event(struct ble_gap_event * event,void * arg)132 bleuart_gap_event(struct ble_gap_event *event, void *arg)
133 {
134     struct ble_gap_conn_desc desc;
135     int rc;
136 
137     switch (event->type) {
138     case BLE_GAP_EVENT_CONNECT:
139         /* A new connection was established or a connection attempt failed. */
140         if (event->connect.status == 0) {
141             rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
142             assert(rc == 0);
143             bleuart_set_conn_handle(event->connect.conn_handle);
144         }
145 
146         if (event->connect.status != 0) {
147             /* Connection failed; resume advertising. */
148             bleuart_advertise();
149         }
150         return 0;
151 
152     case BLE_GAP_EVENT_DISCONNECT:
153         /* Connection terminated; resume advertising. */
154         bleuart_advertise();
155         return 0;
156 
157 
158     case BLE_GAP_EVENT_ADV_COMPLETE:
159         /* Advertising terminated; resume advertising. */
160         bleuart_advertise();
161         return 0;
162 
163     case BLE_GAP_EVENT_REPEAT_PAIRING:
164         /* We already have a bond with the peer, but it is attempting to
165          * establish a new secure link.  This app sacrifices security for
166          * convenience: just throw away the old bond and accept the new link.
167          */
168 
169         /* Delete the old bond. */
170         rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
171         assert(rc == 0);
172         ble_store_util_delete_peer(&desc.peer_id_addr);
173 
174         /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
175          * continue with the pairing operation.
176          */
177         return BLE_GAP_REPEAT_PAIRING_RETRY;
178     }
179 
180     return 0;
181 }
182 
183 static void
bleuart_on_sync(void)184 bleuart_on_sync(void)
185 {
186     /* Begin advertising. */
187     bleuart_advertise();
188 }
189 
190 /**
191  * main
192  *
193  * The main task for the project. This function initializes the packages,
194  * then starts serving events from default event queue.
195  *
196  * @return int NOTE: this function should never return!
197  */
bleuart_entry(void)198 int bleuart_entry(void)
199 {
200     int rc;
201     static int init_flag = 0;
202 
203     if (init_flag == 0)
204     {
205         init_flag = 1;
206 
207         /* Initialize the BLE host. */
208         ble_hs_cfg.sync_cb = bleuart_on_sync;
209         ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
210 
211         rc = bleuart_gatt_svr_init();
212         assert(rc == 0);
213 
214         /* Set the default device name. */
215         rc = ble_svc_gap_device_name_set("Mynewt_BLEuart");
216         assert(rc == 0);
217 
218         /* startup bluetooth host stack*/
219         ble_hs_thread_startup();
220     }
221 
222     bleuart_init();
223 
224     return 0;
225 }
226 
227 MSH_CMD_EXPORT_ALIAS(bleuart_entry, bleuart, "bluetooth uart sample");
228