Cody sync.: merge tizen 2.4 code from spin git
[platform/core/connectivity/bluetooth-frwk.git] / test / gatt-test / bluetooth-gatt-test.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 /**
25  * @file       bluetooth-gatt-test.c
26  * @brief      This is the source file for bluetooth framework test suite.
27  */
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <stdint.h>
35 #include <string.h>
36 #include <glib.h>
37 #include <dbus/dbus-glib.h>
38
39 #include "bluetooth-api.h"
40
41
42 #define PRT(format, args...) printf("%s:%d() "format, __FUNCTION__, __LINE__, ##args)
43 #define TC_PRT(format, args...) PRT(format"\n", ##args)
44
45 #define TC_PASS 1
46 #define TC_FAIL 0
47
48 GMainLoop *main_loop = NULL;
49
50 typedef struct
51 {
52         const char *tc_name;
53         int tc_code;
54 } tc_table_t;
55
56 tc_table_t tc_table[] =
57 {
58         {"Send alert to remote le device"               , 1},
59         {"Set Link loss alert"          , 2},
60
61         /* -----------------------------------------*/
62         {"Finish"                                       , 0x00ff},
63         {NULL                                   , 0x0000},
64
65 };
66
67 #define tc_result(success, tc_index) \
68         TC_PRT("Test case [%d - %s] %s", tc_table[tc_index].tc_code, tc_table[tc_index].tc_name, ((success == TC_PASS)?"Success":"Failed"));
69
70 char *g_alert_char_handle = NULL;
71 guint8 g_alert_level = 0;
72
73 #define IMMEDIATE_ALERT_UUID    "00001802-0000-1000-8000-00805f9b34fb"
74 #define LINK_LOSS_UUID          "00001803-0000-1000-8000-00805f9b34fb"
75 #define ALERT_LEVEL_CHR_UUID    "2a06"
76
77 #define BD_ADDR_FILE "/opt/remote-bd"
78
79 void tc_usage_print(void)
80 {
81         int i = 0;
82
83         while (tc_table[i].tc_name) {
84                 if (tc_table[i].tc_code != 0x00ff) {
85                         TC_PRT("Key %d : usage %s", tc_table[i].tc_code,
86                                                         tc_table[i].tc_name);
87                 } else {
88                         TC_PRT("Key %d : usage %s\n\n", 0x00ff,
89                                                         tc_table[i].tc_name);
90                 }
91
92                 i++;
93         }
94 }
95
96 static void convert_addr_string_to_addr_type(bluetooth_device_address_t *addr,
97                                                         const char *address)
98 {
99         char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
100
101         if (!address || !addr)
102                 return;
103
104         addr->addr[0] = strtol(address, &ptr5, 16);
105         addr->addr[1] = strtol(ptr5 + 1, &ptr4, 16);
106         addr->addr[2] = strtol(ptr4 + 1, &ptr3, 16);
107         addr->addr[3] = strtol(ptr3 + 1, &ptr2, 16);
108         addr->addr[4] = strtol(ptr2 + 1, &ptr1, 16);
109         addr->addr[5] = strtol(ptr1 + 1, NULL, 16);
110 }
111
112 char * get_bd_from_file(char *filename)
113 {
114         int fd;
115         char *buf;
116
117         if ((fd = open(filename, O_RDONLY)) < 0) {
118                 perror("Can't open file");
119                 return NULL;
120         }
121
122         buf = g_malloc0(20);
123         /* Fix : NULL_RETURNS */
124         if (buf == NULL) {
125                 close(fd);
126                 return NULL;
127         }
128
129         if (read(fd, buf, 17) < 17) {
130                 perror("Can't load firmware");
131                 g_free(buf);
132                 close(fd);
133                 return NULL;
134         }
135
136         close(fd);
137
138         return buf;
139 }
140
141 static void __accept_bdaddress(bluetooth_device_address_t *device_address)
142 {
143         char str_address[20] = {0};
144         char *addr;
145
146         addr = get_bd_from_file(BD_ADDR_FILE);
147         if (addr) {
148                 TC_PRT("Remote bd adress from file: %s", addr);
149                 convert_addr_string_to_addr_type(device_address, addr);
150                 return;
151         }
152
153         TC_PRT("Enter bd address: ");
154         int ret = 0;
155         ret = scanf("%s", str_address);
156         if (ret < 0)
157                 TC_PRT("Some read error");
158         TC_PRT("You have entered bd address %s\n", str_address);
159         convert_addr_string_to_addr_type(device_address, str_address);
160 }
161
162 static void __accept_alert_level()
163 {
164         TC_PRT("Enter alert level \n 0 - no alert 1 - mild alert 2 - High alert : ");
165         int ret = 0;
166         ret = scanf("%c", &g_alert_level);
167         if (ret < 0)
168                 TC_PRT("Some read error");
169         TC_PRT("You have selected alert level %hu ", g_alert_level);
170 }
171
172 int test_input_callback(void *data)
173 {
174         int ret = 0;
175         int test_id = (int)data;
176         bluetooth_device_address_t device_address;
177         bt_gatt_service_property_t service;
178
179         switch (test_id) {
180         case 0x00ff:
181                 TC_PRT("Finished");
182                 g_main_loop_quit(main_loop);
183                 break;
184         case 1:
185                 TC_PRT("Immediate Alert");
186                 __accept_bdaddress(&device_address);
187
188                 __accept_alert_level();
189
190                 if (g_alert_char_handle) {
191                         if (bluetooth_gatt_set_characteristics_value(g_alert_char_handle,
192                                                 &g_alert_level, 1) != BLUETOOTH_ERROR_NONE)
193                                 TC_PRT("Set char val failed");
194
195                         return 0;
196                 }
197
198                 ret = bluetooth_gatt_get_service_from_uuid(&device_address,
199                                                         IMMEDIATE_ALERT_UUID,
200                                                         &service);
201                 if (ret != BLUETOOTH_ERROR_NONE) {
202                         TC_PRT(" bluetooth_gatt_get_service_from_uuid FAILED");
203                         return 0;
204                 }
205
206                 ret = bluetooth_gatt_get_char_from_uuid(service.handle,
207                                                         ALERT_LEVEL_CHR_UUID);
208                 if (ret != BLUETOOTH_ERROR_NONE) {
209                         TC_PRT(" bluetooth_gatt_get_char_from_uuid FAILED");
210                         return 0;
211                 }
212
213                 break;
214         case 2:
215                 TC_PRT("Proximity Link loss alert");
216                 __accept_bdaddress(&device_address);
217
218                 __accept_alert_level();
219
220                 /* TODO */
221                 break;
222         default:
223                 break;
224         }
225
226         return 0;
227 }
228
229 void startup()
230 {
231         TC_PRT("bluetooth framework TC startup");
232
233         if (!g_thread_supported())
234                 g_thread_init(NULL);
235
236         dbus_g_thread_init();
237
238         g_type_init();
239         main_loop = g_main_loop_new(NULL, FALSE);
240 }
241
242 void cleanup()
243 {
244         TC_PRT("bluetooth framework TC cleanup");
245         if ( main_loop != NULL)
246                 g_main_loop_unref(main_loop);
247 }
248
249 static void __handle_alert_char(char *char_handle,
250                                         bt_gatt_char_property_t *char_pty)
251 {
252         if (char_pty->val == NULL)
253                 TC_PRT("Read only char");
254         else
255                 TC_PRT("Current Alert level [%d]", char_pty->val[0]);
256
257         g_alert_char_handle = g_strdup(char_handle);
258
259         if (bluetooth_gatt_set_characteristics_value(char_handle,
260                                 &g_alert_level, 1) != BLUETOOTH_ERROR_NONE)
261                 TC_PRT("Set char val failed");
262
263 }
264
265 static gboolean __handle_char(char *char_handle,
266                                         bt_gatt_char_property_t *char_pty)
267 {
268         TC_PRT("char uuid %s", char_pty->uuid);
269
270         if (g_strstr_len(char_pty->uuid, -1, ALERT_LEVEL_CHR_UUID) != NULL) {
271                 TC_PRT("Alert char recieved");
272                 __handle_alert_char(char_handle, char_pty);
273                 return TRUE;
274         } /* Add else if for other chars*/
275
276         return FALSE;
277 }
278
279 void bt_event_callback(int event, bluetooth_event_param_t* param,
280                                                         void *user_data)
281 {
282         TC_PRT(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
283         TC_PRT("bt event callback 0x%04x", event);
284         switch(event) {
285         case BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID:
286         {
287                 TC_PRT("BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID");
288                 if (param->result != 0) {
289                         TC_PRT("Failed!!!");
290                         return;
291                 }
292                 bt_gatt_char_property_t *char_pty = param->param_data;
293
294                 __handle_char(char_pty->handle, char_pty);
295
296         }
297         break;
298         default:
299                 TC_PRT("received event [0x%04x]", event);
300                 break;
301         }
302         TC_PRT("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
303 }
304
305 static gboolean key_event_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
306 {
307         char buf[10] = {0};
308         unsigned int len = 0;
309         int test_id;
310
311         if (g_io_channel_read_chars(chan, buf, sizeof(buf), 
312                         &len, NULL) ==  G_IO_STATUS_ERROR) {
313                 printf("IO Channel read error");
314                 return FALSE;
315         }
316         printf("%s\n",buf);
317         tc_usage_print();
318
319         test_id = atoi(buf);
320
321         if (test_id)
322                 g_idle_add(test_input_callback, (void*)test_id);
323
324         return TRUE;
325 }
326
327 int main()
328 {
329         int ret_val;
330         GIOChannel *key_io;
331
332         startup();
333
334         /* Register callback function */
335         TC_PRT("TC : %s", tc_table[0].tc_name);
336         ret_val = bluetooth_register_callback(bt_event_callback, NULL);
337         if (ret_val >= BLUETOOTH_ERROR_NONE) {
338                 TC_PRT("bluetooth_register_callback returned Success");
339                 tc_result(TC_PASS, 0);
340         } else {
341                 TC_PRT("bluetooth_register_callback returned failiure [0x%04x]", ret_val);
342                 tc_result(TC_FAIL, 0);
343                 return 0;
344         }
345
346         ret_val = bluetooth_check_adapter();
347         if (ret_val < BLUETOOTH_ERROR_NONE) {
348                 TC_PRT("bluetooth_check_adapter returned failiure [0x%04x]", ret_val);
349                 tc_result(TC_FAIL, 3);
350         } else {
351                 TC_PRT("BT state [0x%04x]", ret_val);
352                 tc_result(TC_PASS, 3);
353         }
354
355         key_io = g_io_channel_unix_new(fileno(stdin));
356
357         g_io_add_watch(key_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
358                         key_event_cb, NULL);
359         g_io_channel_unref(key_io);
360
361         g_main_loop_run(main_loop);
362
363         cleanup();
364         return 0;
365 }