xref: /btstack/test/gatt_server/gatt_server_test.cpp (revision a8c93a4e4ef0233ef2d1c5c7fb0de644c0650505)
1 
2 // *****************************************************************************
3 //
4 // test rfcomm query tests
5 //
6 // *****************************************************************************
7 
8 
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "CppUTest/TestHarness.h"
15 #include "CppUTest/CommandLineTestRunner.h"
16 
17 #include "hci.h"
18 #include "ble/att_db.h"
19 #include "ble/att_db_util.h"
20 #include "ble/att_server.h"
21 #include "btstack_util.h"
22 #include "bluetooth.h"
23 #include "btstack_tlv.h"
24 #include "mock_btstack_tlv.h"
25 
26 #include "bluetooth_gatt.h"
27 
28 static uint8_t battery_level = 100;
29 static const uint8_t uuid128_with_bluetooth_base[] = { 0x00, 0x00, 0xBB, 0xBB, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
30 static const uint8_t uuid128_no_bluetooth_base[] =   { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00 };
31 
32 extern "C" void l2cap_can_send_fixed_channel_packet_now_set_status(uint8_t status);
33 extern "C" void mock_call_att_server_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
34 extern "C" void att_init_connection(uint16_t con_handle);
35 
36 static uint8_t att_request[255];
37 static uint16_t att_write_request(uint16_t request_type, uint16_t attribute_handle, uint16_t value_length, const uint8_t * value){
38     att_request[0] = request_type;
39     little_endian_store_16(att_request, 1, attribute_handle);
40     (void)memcpy(&att_request[3], value, value_length);
41     return 3 + value_length;
42 }
43 
44 static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
45     UNUSED(connection_handle);
46     UNUSED(att_handle);
47     UNUSED(offset);
48     UNUSED(buffer);
49     UNUSED(buffer_size);
50 
51     return 0;
52 }
53 
54 static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
55     UNUSED(connection_handle);
56     UNUSED(att_handle);
57     UNUSED(transaction_mode);
58     UNUSED(offset);
59     UNUSED(buffer);
60     UNUSED(buffer_size);
61 
62     return 0;
63 }
64 
65 static void att_client_indication_callback(void * context){
66 }
67 
68 TEST_GROUP(ATT_SERVER){
69     uint16_t att_con_handle;
70     mock_btstack_tlv_t tlv_context;
71     const btstack_tlv_t * tlv_impl;
72 
73     void setup(void){
74         att_con_handle = 0x00;
75 
76         att_init_connection(att_con_handle);
77         tlv_impl = mock_btstack_tlv_init_instance(&tlv_context);
78         btstack_tlv_set_instance(tlv_impl, &tlv_context);
79 
80         l2cap_can_send_fixed_channel_packet_now_set_status(1);
81 
82         // init att db util and add a service and characteristic
83         att_db_util_init();
84         // 0x180F
85         att_db_util_add_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE);
86         // 0x2A19
87         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL,       ATT_PROPERTY_WRITE | ATT_PROPERTY_READ | ATT_PROPERTY_INDICATE, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
88         // 0x2A1B
89         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_STATE, ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
90         // 0x2A1A
91         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_POWER_STATE, ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1);
92         // 0x2A49
93         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_FEATURE, ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
94         // 0x2A35
95         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_MEASUREMENT, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1);
96 
97 
98         att_db_util_add_characteristic_uuid128(uuid128_no_bluetooth_base, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
99         // 0x2A38btstack_tlv_set_instance
100         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
101 
102 
103         att_db_util_add_characteristic_uuid128(uuid128_with_bluetooth_base, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
104         // 0x2AAB
105         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME, ATT_PROPERTY_WRITE_WITHOUT_RESPONSE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
106         // 0x2A5C
107         att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CSC_FEATURE, ATT_PROPERTY_AUTHENTICATED_SIGNED_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1);
108         // setup ATT server
109         att_server_init(att_db_util_get_address(), att_read_callback, att_write_callback);
110     }
111 
112     void teardown(void) {
113         mock_btstack_tlv_deinit(&tlv_context);
114     }
115 };
116 
117 
118 TEST(ATT_SERVER, gatt_server_get_value_handle_for_characteristic_with_uuid16){
119     // att_dump_attributes();
120     uint16_t value_handle;
121 
122     // start handle > value handle
123     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0xf000, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL);
124     CHECK_EQUAL(0, value_handle);
125 
126     // end handle < value handle
127     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0x02, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL);
128     CHECK_EQUAL(0, value_handle);
129 
130     // search value handle for unknown UUID
131     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xffff);
132     CHECK_EQUAL(0, value_handle);
133 
134     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0);
135     CHECK_EQUAL(0, value_handle);
136 
137     // search value handle after one with uuid128_no_bluetooth_base
138     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION);
139     CHECK_EQUAL(0x0014, value_handle);
140 
141     // search value handle after one with uuid128_with_bluetooth_base
142     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME);
143     CHECK_EQUAL(0x001a, value_handle);
144 
145     // search value handle registered with bluetooth_base
146     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xbbbb);
147     CHECK_EQUAL(0x0017, value_handle);
148 
149     // correct read
150     value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL);
151     CHECK_EQUAL(0x03, value_handle);
152 }
153 
154 
155 TEST(ATT_SERVER, att_server_indicate){
156     static uint8_t value[] = {0x55};
157     uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL);
158     uint8_t status;
159 
160     // invalid connection handle
161     status = att_server_indicate(0x50, value_handle, &value[0], 0);
162     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
163 
164     // L2CAP cannot send
165     l2cap_can_send_fixed_channel_packet_now_set_status(0);
166     status = att_server_indicate(att_con_handle, value_handle, &value[0], 0);
167     CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status);
168     l2cap_can_send_fixed_channel_packet_now_set_status(1);
169 
170     // correct command
171     status = att_server_indicate(att_con_handle, value_handle, &value[0], 0);
172     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
173 
174     // already in progress
175     status = att_server_indicate(att_con_handle, value_handle, &value[0], 0);
176     CHECK_EQUAL(ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS, status);
177 }
178 
179 TEST(ATT_SERVER, att_server_notify){
180     static uint8_t value[] = {0x55};
181     uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL);
182     uint8_t status;
183 
184     // invalid connection handle
185     status = att_server_notify(0x50, value_handle, &value[0], 0);
186     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
187 
188     // L2CAP cannot send
189     l2cap_can_send_fixed_channel_packet_now_set_status(0);
190     status = att_server_notify(att_con_handle, value_handle, &value[0], 0);
191     CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status);
192     l2cap_can_send_fixed_channel_packet_now_set_status(1);
193 
194     // correct command
195     status = att_server_notify(att_con_handle, value_handle, &value[0], 0);
196     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
197 }
198 
199 TEST(ATT_SERVER, att_server_get_mtu){
200     // invalid connection handle
201     uint8_t mtu = att_server_get_mtu(0x50);
202     CHECK_EQUAL(0, mtu);
203 
204     mtu = att_server_get_mtu(att_con_handle);
205     CHECK_EQUAL(23, mtu);
206 }
207 
208 TEST(ATT_SERVER, att_server_request_can_send_now_event){
209     att_server_request_can_send_now_event(att_con_handle);
210 
211 }
212 
213 TEST(ATT_SERVER, att_server_can_send_packet_now){
214     int status = att_server_can_send_packet_now(att_con_handle);
215     CHECK_EQUAL(1, status);
216 
217     status = att_server_can_send_packet_now(0x50);
218     CHECK_EQUAL(0, status);
219 }
220 
221 static btstack_context_callback_registration_t indication_callback;
222 
223 TEST(ATT_SERVER, att_server_request_to_send_indication){
224 
225     indication_callback.callback = &att_client_indication_callback;
226     int status = att_server_request_to_send_indication(&indication_callback, 0x55);
227     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
228 
229     l2cap_can_send_fixed_channel_packet_now_set_status(0);
230 
231     status = att_server_request_to_send_indication(&indication_callback, att_con_handle);
232     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
233 
234     status = att_server_request_to_send_indication(&indication_callback, att_con_handle);
235     CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
236 }
237 
238 TEST(ATT_SERVER, opcode_ATT_WRITE_REQUEST){
239     uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL);
240     uint8_t buffer[] = {1, 0};
241     uint16_t att_request_len = att_write_request(ATT_WRITE_REQUEST, value_handle, sizeof(buffer), buffer);
242     mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len);
243 }
244 
245 int main (int argc, const char * argv[]){
246     return CommandLineTestRunner::RunAllTests(argc, argv);
247 }
248