OSDN Git Service

Remove obsolete LOCAL_MODULE_TAGS
[android-x86/external-bluetooth-bluez.git] / tools / userchan-tester.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2014-2015  Intel Corporation. All rights reserved.
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <stdbool.h>
33
34 #include <glib.h>
35
36 #include "lib/bluetooth.h"
37 #include "lib/hci.h"
38 #include "lib/mgmt.h"
39
40 #include "monitor/bt.h"
41 #include "emulator/bthost.h"
42 #include "emulator/hciemu.h"
43
44 #include "src/shared/tester.h"
45 #include "src/shared/mgmt.h"
46 #include "src/shared/hci.h"
47 #include "src/shared/util.h"
48
49 struct test_data {
50         struct mgmt *mgmt;
51         uint16_t mgmt_index;
52         struct hciemu *hciemu;
53         enum hciemu_type hciemu_type;
54         const void *test_data;
55         unsigned int remove_id;
56 };
57
58 static void mgmt_debug(const char *str, void *user_data)
59 {
60         const char *prefix = user_data;
61
62         tester_print("%s%s", prefix, str);
63 }
64
65 static void read_info_callback(uint8_t status, uint16_t length,
66                                         const void *param, void *user_data)
67 {
68         struct test_data *data = tester_get_data();
69         const struct mgmt_rp_read_info *rp = param;
70         char addr[18];
71         uint16_t manufacturer;
72         uint32_t supported_settings, current_settings;
73
74         tester_print("Read Info callback");
75         tester_print("  Status: 0x%02x", status);
76
77         if (status || !param) {
78                 tester_pre_setup_failed();
79                 return;
80         }
81
82         ba2str(&rp->bdaddr, addr);
83         manufacturer = btohs(rp->manufacturer);
84         supported_settings = btohl(rp->supported_settings);
85         current_settings = btohl(rp->current_settings);
86
87         tester_print("  Address: %s", addr);
88         tester_print("  Version: 0x%02x", rp->version);
89         tester_print("  Manufacturer: 0x%04x", manufacturer);
90         tester_print("  Supported settings: 0x%08x", supported_settings);
91         tester_print("  Current settings: 0x%08x", current_settings);
92         tester_print("  Class: 0x%02x%02x%02x",
93                         rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
94         tester_print("  Name: %s", rp->name);
95         tester_print("  Short name: %s", rp->short_name);
96
97         if (strcmp(hciemu_get_address(data->hciemu), addr)) {
98                 tester_pre_setup_failed();
99                 return;
100         }
101
102         tester_pre_setup_complete();
103 }
104
105 static void index_added_callback(uint16_t index, uint16_t length,
106                                         const void *param, void *user_data)
107 {
108         struct test_data *data = tester_get_data();
109
110         tester_print("Index Added callback");
111         tester_print("  Index: 0x%04x", index);
112
113         if (data->mgmt_index != MGMT_INDEX_NONE)
114                 return;
115
116         data->mgmt_index = index;
117
118         mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
119                                         read_info_callback, NULL, NULL);
120 }
121
122 static void index_removed_callback(uint16_t index, uint16_t length,
123                                         const void *param, void *user_data)
124 {
125         struct test_data *data = tester_get_data();
126
127         tester_print("Index Removed callback");
128         tester_print("  Index: 0x%04x", index);
129
130         if (index != data->mgmt_index)
131                 return;
132
133         if (data->remove_id) {
134                 mgmt_unregister(data->mgmt, data->remove_id);
135                 data->remove_id = 0;
136                 tester_test_passed();
137                 return;
138         }
139
140         mgmt_unregister_index(data->mgmt, data->mgmt_index);
141
142         mgmt_unref(data->mgmt);
143         data->mgmt = NULL;
144
145         tester_post_teardown_complete();
146 }
147
148 static void read_index_list_callback(uint8_t status, uint16_t length,
149                                         const void *param, void *user_data)
150 {
151         struct test_data *data = tester_get_data();
152
153         tester_print("Read Index List callback");
154         tester_print("  Status: 0x%02x", status);
155
156         if (status || !param) {
157                 tester_pre_setup_failed();
158                 return;
159         }
160
161         mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
162                                         index_added_callback, NULL, NULL);
163
164         data->hciemu = hciemu_new(data->hciemu_type);
165         if (!data->hciemu) {
166                 tester_warn("Failed to setup HCI emulation");
167                 tester_pre_setup_failed();
168         }
169
170         tester_print("New hciemu instance created");
171 }
172
173 static void test_pre_setup(const void *test_data)
174 {
175         struct test_data *data = tester_get_data();
176
177         data->mgmt = mgmt_new_default();
178         if (!data->mgmt) {
179                 tester_warn("Failed to setup management interface");
180                 tester_pre_setup_failed();
181                 return;
182         }
183
184         if (tester_use_debug())
185                 mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL);
186
187         mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
188                                         read_index_list_callback, NULL, NULL);
189 }
190
191 static void test_post_teardown(const void *test_data)
192 {
193         struct test_data *data = tester_get_data();
194
195         mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, data->mgmt_index,
196                                         index_removed_callback,
197                                         NULL, NULL);
198
199         hciemu_unref(data->hciemu);
200         data->hciemu = NULL;
201 }
202
203 static void test_data_free(void *test_data)
204 {
205         struct test_data *data = test_data;
206
207         free(data);
208 }
209
210 static void setup_powered_client_callback(uint8_t status, uint16_t length,
211                                         const void *param, void *user_data)
212 {
213         if (status != MGMT_STATUS_SUCCESS) {
214                 tester_setup_failed();
215                 return;
216         }
217
218         tester_print("Controller powered on");
219
220         tester_setup_complete();
221 }
222
223 static void setup_powered(const void *test_data)
224 {
225         struct test_data *data = tester_get_data();
226         unsigned char param[] = { 0x01 };
227
228         tester_print("Powering on controller");
229
230         mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
231                         sizeof(param), param, setup_powered_client_callback,
232                         NULL, NULL);
233 }
234
235 static void toggle_powered(const void *test_data);
236
237 static void toggle_powered_client_callback(uint8_t status, uint16_t length,
238                                         const void *param, void *user_data)
239 {
240         bool power = PTR_TO_INT(user_data);
241
242         if (status != MGMT_STATUS_SUCCESS) {
243                 tester_setup_failed();
244                 return;
245         }
246
247         tester_print("Controller powered %s", power ? "on" : "off");
248
249         if (power)
250                 toggle_powered(false);
251         else
252                 tester_setup_complete();
253 }
254
255 static void toggle_powered(const void *test_data)
256 {
257         struct test_data *data = tester_get_data();
258         bool power = PTR_TO_INT(test_data);
259         unsigned char param[1];
260
261         param[0] = power ? 0x01 : 0x00;
262
263         tester_print("Powering %s controller", power ? "on" : "off");
264
265         mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
266                         sizeof(param), param, toggle_powered_client_callback,
267                         INT_TO_PTR(power), NULL);
268 }
269
270 static void test_open_success(const void *test_data)
271 {
272         struct test_data *data = tester_get_data();
273         struct bt_hci *hci;
274
275         data->remove_id = mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED,
276                                         data->mgmt_index,
277                                         index_removed_callback,
278                                         NULL, NULL);
279
280         hci = bt_hci_new_user_channel(data->mgmt_index);
281         if (hci) {
282                 bt_hci_unref(hci);
283                 return;
284         }
285
286         mgmt_unregister(data->mgmt, data->remove_id);
287         data->remove_id = 0;
288
289         tester_test_failed();
290 }
291
292 static void test_open_failed(const void *test_data)
293 {
294         struct test_data *data = tester_get_data();
295         struct bt_hci *hci;
296
297         hci = bt_hci_new_user_channel(data->mgmt_index);
298         if (!hci) {
299                 tester_test_passed();
300                 return;
301         }
302
303         bt_hci_unref(hci);
304         tester_test_failed();
305 }
306
307 #define test_user(name, data, setup, func) \
308         do { \
309                 struct test_data *user; \
310                 user = malloc(sizeof(struct test_data)); \
311                 if (!user) \
312                         break; \
313                 user->hciemu_type = HCIEMU_TYPE_BREDR; \
314                 user->mgmt_index = MGMT_INDEX_NONE; \
315                 user->test_data = data; \
316                 user->remove_id = 0; \
317                 tester_add_full(name, data, \
318                                 test_pre_setup, setup, func, NULL, \
319                                 test_post_teardown, 2, user, test_data_free); \
320         } while (0)
321
322 int main(int argc, char *argv[])
323 {
324         tester_init(&argc, &argv);
325
326         test_user("User channel open - Success", NULL,
327                                         NULL, test_open_success);
328         test_user("User channel open - Failed", NULL,
329                                         setup_powered, test_open_failed);
330         test_user("User channel open - Power Toggle Success", INT_TO_PTR(true),
331                                         toggle_powered, test_open_success);
332
333         return tester_run();
334 }