1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2017 Glenn Ruben Bakke
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26 
27 #ifndef UBLUEPY_H__
28 #define UBLUEPY_H__
29 
30 /* Examples:
31 
32 Advertisment:
33 
34 from ubluepy import Peripheral
35 p = Peripheral()
36 p.advertise(device_name="MicroPython")
37 
38 DB setup:
39 
40 from ubluepy import Service, Characteristic, UUID, Peripheral, constants
41 from board import LED
42 
43 def event_handler(id, handle, data):
44     print("BLE event:", id, "handle:", handle)
45     print(data)
46 
47     if id == constants.EVT_GAP_CONNECTED:
48         # connected
49         LED(2).on()
50     elif id == constants.EVT_GAP_DISCONNECTED:
51         # disconnect
52         LED(2).off()
53     elif id == 80:
54         print("id 80, data:", data)
55 
56 # u0 = UUID("0x180D") # HRM service
57 # u1 = UUID("0x2A37") # HRM measurement
58 
59 u0 = UUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e")
60 u1 = UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
61 u2 = UUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e")
62 s = Service(u0)
63 c0 = Characteristic(u1, props = Characteristic.PROP_WRITE | Characteristic.PROP_WRITE_WO_RESP)
64 c1 = Characteristic(u2, props = Characteristic.PROP_NOTIFY, attrs = Characteristic.ATTR_CCCD)
65 s.addCharacteristic(c0)
66 s.addCharacteristic(c1)
67 p = Peripheral()
68 p.addService(s)
69 p.setConnectionHandler(event_handler)
70 p.advertise(device_name="micr", services=[s])
71 
72 */
73 
74 #include "py/obj.h"
75 
76 extern const mp_obj_type_t ubluepy_uuid_type;
77 extern const mp_obj_type_t ubluepy_service_type;
78 extern const mp_obj_type_t ubluepy_characteristic_type;
79 extern const mp_obj_type_t ubluepy_peripheral_type;
80 extern const mp_obj_type_t ubluepy_scanner_type;
81 extern const mp_obj_type_t ubluepy_scan_entry_type;
82 extern const mp_obj_type_t ubluepy_constants_type;
83 extern const mp_obj_type_t ubluepy_constants_ad_types_type;
84 
85 typedef enum {
86     UBLUEPY_UUID_16_BIT = 1,
87     UBLUEPY_UUID_128_BIT
88 } ubluepy_uuid_type_t;
89 
90 typedef enum {
91     UBLUEPY_SERVICE_PRIMARY = 1,
92     UBLUEPY_SERVICE_SECONDARY = 2
93 } ubluepy_service_type_t;
94 
95 typedef enum {
96     UBLUEPY_ADDR_TYPE_PUBLIC = 0,
97     UBLUEPY_ADDR_TYPE_RANDOM_STATIC = 1,
98 #if 0
99     UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = 2,
100     UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = 3,
101 #endif
102 } ubluepy_addr_type_t;
103 
104 typedef enum {
105     UBLUEPY_ROLE_PERIPHERAL,
106     UBLUEPY_ROLE_CENTRAL
107 } ubluepy_role_type_t;
108 
109 typedef struct _ubluepy_uuid_obj_t {
110     mp_obj_base_t       base;
111     ubluepy_uuid_type_t type;
112     uint8_t             value[2];
113     uint8_t             uuid_vs_idx;
114 } ubluepy_uuid_obj_t;
115 
116 typedef struct _ubluepy_peripheral_obj_t {
117     mp_obj_base_t       base;
118     ubluepy_role_type_t role;
119     volatile uint16_t   conn_handle;
120     mp_obj_t            delegate;
121     mp_obj_t            notif_handler;
122     mp_obj_t            conn_handler;
123     mp_obj_t            service_list;
124 } ubluepy_peripheral_obj_t;
125 
126 typedef struct _ubluepy_service_obj_t {
127     mp_obj_base_t              base;
128     uint16_t                   handle;
129     uint8_t                    type;
130     ubluepy_uuid_obj_t       * p_uuid;
131     ubluepy_peripheral_obj_t * p_periph;
132     mp_obj_t                   char_list;
133     uint16_t                   start_handle;
134     uint16_t                   end_handle;
135 } ubluepy_service_obj_t;
136 
137 typedef struct _ubluepy_characteristic_obj_t {
138     mp_obj_base_t           base;
139     uint16_t                handle;
140     ubluepy_uuid_obj_t    * p_uuid;
141     uint16_t                service_handle;
142     uint16_t                user_desc_handle;
143     uint16_t                cccd_handle;
144     uint16_t                sccd_handle;
145     uint8_t                 props;
146     uint8_t                 attrs;
147     ubluepy_service_obj_t * p_service;
148     mp_obj_t                value_data;
149 } ubluepy_characteristic_obj_t;
150 
151 typedef struct _ubluepy_descriptor_obj_t {
152     mp_obj_base_t           base;
153     uint16_t                handle;
154     ubluepy_uuid_obj_t    * p_uuid;
155 } ubluepy_descriptor_obj_t;
156 
157 typedef struct _ubluepy_delegate_obj_t {
158     mp_obj_base_t        base;
159 } ubluepy_delegate_obj_t;
160 
161 typedef struct _ubluepy_advertise_data_t {
162     uint8_t *  p_device_name;
163     uint8_t    device_name_len;
164     mp_obj_t * p_services;
165     uint8_t    num_of_services;
166     uint8_t *  p_data;
167     uint8_t    data_len;
168     bool       connectable;
169 } ubluepy_advertise_data_t;
170 
171 typedef struct _ubluepy_scanner_obj_t {
172     mp_obj_base_t base;
173     mp_obj_t      adv_reports;
174 } ubluepy_scanner_obj_t;
175 
176 typedef struct _ubluepy_scan_entry_obj_t {
177     mp_obj_base_t base;
178     mp_obj_t      addr;
179     uint8_t       addr_type;
180     bool          connectable;
181     int8_t        rssi;
182     mp_obj_t      data;
183 } ubluepy_scan_entry_obj_t;
184 
185 typedef enum _ubluepy_prop_t {
186     UBLUEPY_PROP_BROADCAST      = 0x01,
187     UBLUEPY_PROP_READ           = 0x02,
188     UBLUEPY_PROP_WRITE_WO_RESP  = 0x04,
189     UBLUEPY_PROP_WRITE          = 0x08,
190     UBLUEPY_PROP_NOTIFY         = 0x10,
191     UBLUEPY_PROP_INDICATE       = 0x20,
192     UBLUEPY_PROP_AUTH_SIGNED_WR = 0x40,
193 } ubluepy_prop_t;
194 
195 typedef enum _ubluepy_attr_t {
196     UBLUEPY_ATTR_CCCD           = 0x01,
197     UBLUEPY_ATTR_SCCD           = 0x02,
198 } ubluepy_attr_t;
199 
200 #endif // UBLUEPY_H__
201