riscv64: Add RISC-V to supported architectures
[platform/core/connectivity/bluetooth-agent.git] / hf-test / hf-test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <glib.h>
6 #include <bluetooth.h>
7 #include <bluetooth_extension.h>
8
9 #define LOG_RED "\033[0;31m"
10 #define LOG_GREEN "\033[0;32m"
11 #define LOG_BROWN "\033[0;33m"
12 #define LOG_BLUE "\033[0;34m"
13 #define LOG_END "\033[0;m"
14
15 #define BT_PROFILE_SERVICE_UUID_HFP_HF         "111e"
16 #define BT_PROFILE_SERVICE_UUID_HFP_AG         "111f"
17 #define BT_PROFILE_SERVICE_UUID_A2DP_SOURCE    "110a"
18 #define BT_PROFILE_SERVICE_UUID_A2DP_SINK      "110b"
19 #define PHONE_NUMBER_LENGTH                                             15
20
21
22 static const char *__bt_get_error(bt_error_e err)
23 {
24         const char *err_str = NULL;
25
26         switch (err) {
27         case BT_ERROR_NONE:
28                 err_str = "BT_ERROR_NONE";
29                 break;
30         case BT_ERROR_CANCELLED:
31                 err_str = "BT_ERROR_CANCELLED";
32                 break;
33         case BT_ERROR_INVALID_PARAMETER:
34                 err_str = "BT_ERROR_INVALID_PARAMETER";
35                 break;
36         case BT_ERROR_OUT_OF_MEMORY:
37                 err_str = "BT_ERROR_OUT_OF_MEMORY";
38                 break;
39         case BT_ERROR_RESOURCE_BUSY:
40                 err_str = "BT_ERROR_RESOURCE_BUSY";
41                 break;
42         case BT_ERROR_TIMED_OUT:
43                 err_str = "BT_ERROR_TIMED_OUT";
44                 break;
45         case BT_ERROR_NOW_IN_PROGRESS:
46                 err_str = "BT_ERROR_NOW_IN_PROGRESS";
47                 break;
48         case BT_ERROR_NOT_INITIALIZED:
49                 err_str = "BT_ERROR_NOT_INITIALIZED";
50                 break;
51         case BT_ERROR_NOT_ENABLED:
52                 err_str = "BT_ERROR_NOT_ENABLED";
53                 break;
54         case BT_ERROR_ALREADY_DONE:
55                 err_str = "BT_ERROR_ALREADY_DONE";
56                 break;
57         case BT_ERROR_OPERATION_FAILED:
58                 err_str = "BT_ERROR_OPERATION_FAILED";
59                 break;
60         case BT_ERROR_NOT_IN_PROGRESS:
61                 err_str = "BT_ERROR_NOT_IN_PROGRESS";
62                 break;
63         case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
64                 err_str = "BT_ERROR_REMOTE_DEVICE_NOT_BONDED";
65                 break;
66         case BT_ERROR_AUTH_REJECTED:
67                 err_str = "BT_ERROR_AUTH_REJECTED";
68                 break;
69         case BT_ERROR_AUTH_FAILED:
70                 err_str = "BT_ERROR_AUTH_FAILED";
71                 break;
72         case BT_ERROR_REMOTE_DEVICE_NOT_FOUND:
73                 err_str = "BT_ERROR_REMOTE_DEVICE_NOT_FOUND";
74                 break;
75         case BT_ERROR_SERVICE_SEARCH_FAILED:
76                 err_str = "BT_ERROR_SERVICE_SEARCH_FAILED";
77                 break;
78         case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED:
79                 err_str = "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED";
80                 break;
81         case BT_ERROR_PERMISSION_DENIED:
82                 err_str = "BT_ERROR_PERMISSION_DENIED";
83                 break;
84         case BT_ERROR_SERVICE_NOT_FOUND:
85                 err_str = "BT_ERROR_SERVICE_NOT_FOUND";
86                 break;
87         case BT_ERROR_NO_DATA:
88                 err_str = "BT_ERROR_NO_DATA";
89                 break;
90         case BT_ERROR_NOT_SUPPORTED:
91                 err_str = "BT_ERROR_NOT_SUPPORTED";
92                 break;
93         case BT_ERROR_DEVICE_POLICY_RESTRICTION:
94                 err_str = "DEVICE_POLICY_RESTRICTION";
95                 break;
96         default:
97                 err_str = "NOT Defined";
98                 break;
99         }
100
101         return err_str;
102 }
103
104
105 gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data);
106
107 static char remote_phone_number[PHONE_NUMBER_LENGTH] = "+8200000000000";
108 static char remote_phone_bt_mac[18] = "00:00:00:00:00:00";
109 static int remote_phone_pb_size = 0;
110 static bool ringing_status = false;
111
112 void __bt_hf_set_remote_call_event_cb(bt_hf_remote_call_event_e event,
113                                                                           char *phone_number, void *user_data)
114 {
115         switch (event) {
116         case BT_HF_REMOTE_CALL_EVENT_IDLE: {
117                 printf("[remote_call_event_cb] event [IDLE]\n");
118                 if (ringing_status) {
119                         printf("[APP] STOP ALARM\n");
120                         ringing_status = false;
121                 }
122                 break;
123         }
124         case BT_HF_REMOTE_CALL_EVENT_INCOMING:
125                 printf("[remote_call_event_cb] event [INCOMING]\n");
126                 break;
127         case BT_HF_REMOTE_CALL_EVENT_DIALING: {
128                 int ret = 0;
129                 GSList *list;
130
131                 printf("[remote_call_event_cb] event [DIALING]\n");
132                 ret = bt_hf_get_call_status_info_list(&list);
133
134                 if (ret < BT_ERROR_NONE)
135                         printf("failed with [0x%04x]\n", ret);
136                 else {
137                         for (; list; list = g_slist_next(list)) {
138                                 bt_hf_call_status_info_s *call_info = list->data;
139                                 printf("[CALL INFO] number : %s\n", call_info->number);
140                                 printf("[CALL INFO] direction (0: outgoing, 1: incoming) : %d\n", call_info->direction);
141                                 printf("[CALL INFO] status (0: active, 1: held, 2: dialing, 3: alerting) : %d\n", call_info->status);
142                                 strncpy(remote_phone_number, call_info->number, PHONE_NUMBER_LENGTH - 1);
143                         }
144                         bt_hf_free_call_status_info_list(list);
145                 }
146                 break;
147         }
148         case BT_HF_REMOTE_CALL_EVENT_ALERTING:
149                 printf("[remote_call_event_cb] event [ALERTING]\n");
150                 printf("[remote_call_event_cb] number : %s\n", remote_phone_number);
151                 break;
152         case BT_HF_REMOTE_CALL_EVENT_CALL_TERMINATED:
153                 printf("[remote_call_event_cb] event [TERMINATED]\n");
154                 break;
155         case BT_HF_REMOTE_CALL_EVENT_CALL_STARTED: {
156                 printf("[remote_call_event_cb] event [STARTED]\n");
157                 if (ringing_status) {
158                         printf("[APP] STOP ALARM\n");
159                         ringing_status = false;
160                 }
161                 break;
162         }
163         case BT_HF_REMOTE_CALL_EVENT_CALL_ENDED:
164                 printf("[remote_call_event_cb] event [ENDED]\n");
165                 break;
166         case BT_HF_REMOTE_CALL_EVENT_UNHELD:
167                 printf("[remote_call_event_cb] event [UNHELD]\n");
168                 break;
169         case BT_HF_REMOTE_CALL_EVENT_HELD:
170                 printf("[remote_call_event_cb] event [HELD]\n");
171                 break;
172         case BT_HF_REMOTE_CALL_EVENT_RINGING: {
173                 printf("[remote_call_event_cb] event [RINGING]\n");
174                 printf("[remote_call_event_cb] phone_number [%s]\n", phone_number);
175                 if (!ringing_status) {
176                         printf("[APP] START ALARM\n");
177                         ringing_status = true;
178                 }
179                 break;
180         }
181         case BT_HF_REMOTE_CALL_EVENT_WAITING:
182                 printf("[remote_call_event_cb] event [WAITING]\n");
183                 break;
184         case BT_HF_REMOTE_CALL_EVENT_FAILED_TO_DIALING:
185                 printf("[remote_call_event_cb] event [FAILED_TO_DIALING]\n");
186                 break;
187         default:
188                 printf("[remote_call_event_cb] event [UNKNOWN]\n");
189         }
190
191 }
192
193
194 void __bt_pbap_phonebook_pull_cb(int result, const char *remote_address,
195         const char *vcf_file, void *user_data)
196 {
197         printf("[__bt_pbap_phonebook_pull_cb] Result: %d\n", result);
198         printf("[__bt_pbap_phonebook_pull_cb] Remote Device: %s\n", remote_address);
199         printf("[__bt_pbap_phonebook_pull_cb] Phonebook Download File: %s\n", vcf_file);
200         printf("[__bt_pbap_phonebook_pull_cb] Phonebook Download Status: %s\n",
201                 (result == BT_ERROR_NONE) ? "Successful" : "Unsuccessful");
202
203         if (result == BT_ERROR_NONE) {
204                 printf("[__bt_pbap_phonebook_pull_cb] PHONEBOOK DOWNLOAD DONE.. DISCONNECT PBAP CLIENT\n");
205         } else
206                 printf("[__bt_pbap_phonebook_pull_cb] PHONEBOOK DOWNLOAD FAILED.. (ERROR: %s)\n", __bt_get_error(result));
207 }
208
209 void __bt_pbap_phonebook_size_cb(int result, const char *remote_address, int size, void *user_data)
210 {
211         int ret = 0;
212
213         printf("[__bt_pbap_phonebook_size_cb] Result: %d\n", result);
214         printf("[__bt_pbap_phonebook_size_cb] Remote Device: %s\n", remote_address);
215         printf("[__bt_pbap_phonebook_size_cb] Phonebook Size: %d\n", size);
216
217         remote_phone_pb_size = size;
218
219         if (result == BT_ERROR_NONE) {
220                 ret = bt_pbap_client_get_phone_book(remote_address, BT_PBAP_SOURCE_DEVICE, BT_PBAP_FOLDER_PHONE_BOOK,
221                                                                 BT_PBAP_VCARD_FORMAT_VCARD30, BT_PBAP_ORDER_INDEXED, 0, size, BT_PBAP_FIELD_N | BT_PBAP_FIELD_TEL,
222                                                                 __bt_pbap_phonebook_pull_cb, NULL);
223                 if (ret != BT_ERROR_NONE) {
224                         printf("bt_pbap_client_get_phone_book failed (%d)\n", ret);
225                 }
226         }
227 }
228 void __bt_pbap_connection_state_changed_cb(int result, bool connected, const char *remote_address, void *user_data)
229 {
230         int ret = 0;
231
232         printf("[__bt_pbap_connection_state_changed_cb] Result: %d\n", result);
233         printf("[__bt_pbap_connection_state_changed_cb] Remote Device: %s\n", remote_address);
234         printf("[__bt_pbap_connection_state_changed_cb] Connected Status: %d\n", connected);
235
236         // if phone is PBAP connected, get connected mobile's phonebook size
237         if ((result == 0) && connected) {
238                 ret = bt_pbap_client_get_phone_book_size(remote_address, BT_PBAP_SOURCE_DEVICE,
239                                                                         BT_PBAP_FOLDER_PHONE_BOOK, __bt_pbap_phonebook_size_cb, NULL);
240                 if (ret != BT_ERROR_NONE) {
241                         printf("bt_pbap_client_get_phone_book_size failed (%s)\n", __bt_get_error(result));
242                 }
243         }
244 }
245
246 void __bt_audio_connection_state_changed_cb(int result, bool connected,
247                                 const char *remote_address, bt_audio_profile_type_e type, void *user_data)
248 {
249
250         if (type == BT_AUDIO_PROFILE_TYPE_AG) {
251                 printf("[__bt_audio_connection_state_changed_cb] result : %d\n", result);
252                 printf("[__bt_audio_connection_state_changed_cb] connected : %d\n", connected);
253                 printf("[__bt_audio_connection_state_changed_cb] address : %s\n", remote_address);
254                 printf("[__bt_audio_connection_state_changed_cb] type : %d\n", type);
255
256                 if (connected) {
257                         printf("[__bt_audio_connection_state_changed_cb] mobile connected!!!!\n");
258
259                         strncpy(remote_phone_bt_mac, remote_address, strlen(remote_phone_bt_mac));
260                 }
261                 if (!connected) {
262                         printf("[__bt_audio_connection_state_changed_cb] mobile disconnected!!!!\n");
263                         if (ringing_status) {
264                                 //mobile is disconnected during RINING event.. Stop all alarm
265                                 printf("[APP] STOP ALARM\n");
266                                 ringing_status = false;
267                         }
268                 }
269         }
270 }
271
272 static int initialize_bluetooth(void)
273 {
274         int ret;
275
276         ret = bt_initialize();
277         if (ret != BT_ERROR_NONE) {
278                 printf("bt_initialize failed (%s)\n", __bt_get_error(ret));
279                 return -1;
280         }
281
282         ret = bt_audio_initialize();
283         if (ret != BT_ERROR_NONE) {
284                 printf("bt_audio_initialize failed (%s)\n", __bt_get_error(ret));
285                 return -1;
286         }
287
288         ret = bt_hf_initialize();
289         if (ret != BT_ERROR_NONE) {
290                 printf("bt_hf_initialize failed (%s)\n", __bt_get_error(ret));
291         }
292
293         ret = bt_hf_set_remote_call_event_cb(__bt_hf_set_remote_call_event_cb, NULL);
294         if (ret != BT_ERROR_NONE) {
295                 printf("bt_hf_set_remote_call_event_cb failed (%s)\n", __bt_get_error(ret));
296                 return -1;
297         }
298
299         ret = bt_audio_set_connection_state_changed_cb(__bt_audio_connection_state_changed_cb, NULL);
300         if (ret != BT_ERROR_NONE) {
301                 printf("bt_audio_set_connection_state_changed_cb failed (%s)\n", __bt_get_error(ret));
302         }
303
304         // PBAP initialize
305         ret = bt_pbap_client_initialize();
306         if (ret != BT_ERROR_NONE && ret != BT_ERROR_ALREADY_DONE) {
307                 printf("bt_pbap_client_initialize failed (%s)\n", __bt_get_error(ret));
308         }
309
310         ret = bt_pbap_client_set_connection_state_changed_cb(__bt_pbap_connection_state_changed_cb, NULL);
311         if (ret != BT_ERROR_NONE) {
312                 printf("bt_pbap_client_set_connection_state_changed_cb failed (%s)\n", __bt_get_error(ret));
313         }
314
315         return 1;
316 }
317
318 void test_deinitialize(void)
319 {
320         int ret = 0;
321
322         ret = bt_hf_unset_remote_call_event_cb();
323         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
324                 printf("bt_hf_unset_remote_call_event_cb failed (%s)\n", __bt_get_error(ret));
325         }
326
327         ret = bt_pbap_client_unset_connection_state_changed_cb();
328         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
329                 printf("bt_pbap_client_unset_connection_state_changed_cb failed (%s)\n", __bt_get_error(ret));
330         }
331
332         ret = bt_audio_unset_connection_state_changed_cb();
333         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
334                 printf("bt_audio_set_connection_state_changed_cb failed (%s)\n", __bt_get_error(ret));
335         }
336
337         ret = bt_pbap_client_deinitialize();
338         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
339                 printf("bt_pbap_client_deinitialize failed (%s)\n", __bt_get_error(ret));
340         }
341
342         ret = bt_hf_deinitialize();
343         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
344                 printf("bt_hf_deinitialize failed (%s)\n", __bt_get_error(ret));
345         }
346
347         ret = bt_audio_deinitialize();
348         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
349                 printf("bt_audio_deinitialize failed (%s)\n", __bt_get_error(ret));
350         }
351
352         ret = bt_deinitialize();
353         if (ret != BT_ERROR_NONE && ret != BT_ERROR_NOT_INITIALIZED) {
354                 printf("bt_deinitialize failed (%s)\n", __bt_get_error(ret));
355         }
356
357 }
358 int test_accept_incoming_call(void)
359 {
360         int ret = 0;
361         ret = bt_hf_notify_call_event(BT_HF_CALL_EVENT_ANSWER, NULL);
362
363         if (ret != BT_ERROR_NONE) {
364                 printf("bt_hf_notify_call_event(BT_HF_CALL_EVENT_ANSWER) failed (%s)\n", __bt_get_error(ret));
365                 return -1;
366         } else
367                 printf("[SUCCESS] accept incoming call\n");
368
369         return 1;
370 }
371
372 int test_initiate_call(void)
373 {
374         int ret = 0;
375
376         printf("Input full phone number to dial : ");
377         ret = scanf("%14s", remote_phone_number);
378
379         ret = bt_hf_notify_call_event(BT_HF_CALL_EVENT_DIAL, remote_phone_number);
380         if (ret != BT_ERROR_NONE) {
381                 printf("bt_hf_notify_call_event(BT_HF_CALL_EVENT_DIAL) failed (%s)\n", __bt_get_error(ret));
382                 printf("phone number : %s", remote_phone_number);
383                 return -1;
384         } else
385                 printf("[SUCCESS] initiate call.. [%s]\n", remote_phone_number);
386
387         return 1;
388 }
389
390 int test_terminate_call(void)
391 {
392         int ret = 0;
393         ret = bt_hf_notify_call_event(BT_HF_CALL_EVENT_IDLE, NULL);
394
395         if (ret != BT_ERROR_NONE) {
396                 printf("bt_hf_notify_call_event(BT_HF_CALL_EVENT_IDLE) failed (%s)\n", __bt_get_error(ret));
397                 return -1;
398         } else
399                 printf("[SUCCESS] terminate call\n");
400
401         return 1;
402 }
403
404 int test_audio_mute_on(void)
405 {
406         int ret = 0;
407         ret = bt_hf_notify_call_event(BT_HF_CALL_EVENT_AUDIO_MUTE_ON, NULL);
408
409         if (ret != BT_ERROR_NONE) {
410                 printf("bt_hf_notify_call_event(BT_HF_CALL_EVENT_AUDIO_MUTE_ON) failed (%s)\n", __bt_get_error(ret));
411                 return -1;
412         } else
413                 printf("[SUCCESS] audio mute\n");
414
415         return 1;
416 }
417
418 int test_audio_mute_off(void)
419 {
420         int ret = 0;
421         ret = bt_hf_notify_call_event(BT_HF_CALL_EVENT_AUDIO_MUTE_OFF, NULL);
422
423         if (ret != BT_ERROR_NONE) {
424                 printf("bt_hf_notify_call_event(BT_HF_CALL_EVENT_AUDIO_MUTE_OFF) failed (%s)\n", __bt_get_error(ret));
425                 return -1;
426         } else
427                 printf("[SUCCESS] audio unmute\n");
428
429         return 1;
430 }
431
432 int test_pbap_connect(void)
433 {
434         int ret = 0;
435
436         // try to PBAP connect to connected mobile phone device
437         ret = bt_pbap_client_connect(remote_phone_bt_mac);
438         if (ret != BT_ERROR_NONE) {
439                 if (ret == BT_ERROR_ALREADY_DONE) {
440                         printf("PBAP already connected [%s]\n", remote_phone_bt_mac);
441
442                         /// if phone is PBAP connected, get connected mobile's phonebook size
443                         ret = bt_pbap_client_get_phone_book_size(remote_phone_bt_mac, BT_PBAP_SOURCE_DEVICE,
444                                                                                 BT_PBAP_FOLDER_PHONE_BOOK, __bt_pbap_phonebook_size_cb, NULL);
445                         if (ret != BT_ERROR_NONE) {
446                                 printf("bt_pbap_client_get_phone_book_size failed (%s)\n", __bt_get_error(ret));
447                         }
448                 } else {
449                         printf("bt_pbap_client_connect failed (%s)\n", __bt_get_error(ret));
450                         return -1;
451                 }
452         } else
453                 printf("[SUCCESS] pbap connect.. [%s]\n", remote_phone_bt_mac);
454
455         return 1;
456 }
457
458 int test_pbap_disconnect(void)
459 {
460         int ret = 0;
461
462         // try to PBAP connect to connected mobile phone device
463         ret = bt_pbap_client_disconnect(remote_phone_bt_mac);
464         if (ret != BT_ERROR_NONE) {
465                 printf("bt_pbap_client_disconnect failed (%s)\n", __bt_get_error(ret));
466                 return -1;
467         } else
468                 printf("[SUCCESS] pbap disconnect.. [%s]\n", remote_phone_bt_mac);
469
470         return 1;
471 }
472
473 int main(void)
474 {
475         GMainLoop *gmain_loop;
476
477         gmain_loop = g_main_loop_new(NULL, FALSE);
478
479         if (gmain_loop == NULL) {
480                 printf("GMainLoop create failed\n");
481                 return EXIT_FAILURE;
482         }
483
484         GIOChannel *channel = g_io_channel_unix_new(0);
485         g_io_add_watch(channel, (G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL), test_thread, NULL);
486
487         printf("Test Thread created...\n");
488
489         g_main_loop_run(gmain_loop);
490
491         if (gmain_loop)
492                 g_main_loop_unref(gmain_loop);
493
494         return 0;
495 }
496
497 gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
498 {
499         int rv;
500         char a[10];
501
502         printf("Event received from stdin\n");
503
504         rv = read(0, a, 10);
505
506         if (rv <= 0 || a[0] == '0') {
507                 test_deinitialize();
508                 exit(1);
509         }
510
511         if (a[0] == '\n' || a[0] == '\r') {
512 /* Public API */
513                 printf("\n\n Bluetooth HFP Test App\n\n");
514                 printf("Options..\n");
515                 printf(LOG_GREEN "1   - Bluetooth init and set callbacks\n" LOG_END);
516                 printf("2   - accept incoming call\n");
517                 printf("3   - initiate call\n");
518                 printf("4   - terminatate call\n");
519                 printf("5   - audio mute\n");
520                 printf("6   - audio unmute\n");
521                 printf("7       - connect PBAP\n");
522                 printf("8       - disconnect PBAP\n");
523                 printf(LOG_RED "0   - Exit \n" LOG_END);
524
525                 printf("ENTER  - Show options menu.......\n");
526         }
527
528         switch (a[0]) {
529 /* Public API */
530         case '1':
531                 rv = initialize_bluetooth();
532                 break;
533         case '2':
534                 rv = test_accept_incoming_call();
535                 break;
536         case '3':
537                 rv = test_initiate_call();
538                 break;
539         case '4':
540                 rv = test_terminate_call();
541                 break;
542         case '5':
543                 rv = test_audio_mute_on();
544                 break;
545         case '6':
546                 rv = test_audio_mute_off();
547                 break;
548         case '7':
549                 rv = test_pbap_connect();
550                 break;
551         case '8':
552                 rv = test_pbap_disconnect();
553                 break;
554
555         default:
556                 break;
557         }
558
559         if (rv == 1)
560                 printf("Operation succeeded!\n");
561         else
562                 printf("Operation failed!\n");
563
564         return TRUE;
565 }
566