1 /*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 // *****************************************************************************
39 //
40 // HFG HF state machine tests
41 //
42 // *****************************************************************************
43
44 #include "btstack_config.h"
45
46 #include <stdint.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50
51 #include "CppUTest/TestHarness.h"
52 #include "CppUTest/CommandLineTestRunner.h"
53
54 #include "hci_cmd.h"
55 #include "btstack_run_loop.h"
56 #include "classic/sdp_util.h"
57
58 #include "hci.h"
59 #include "l2cap.h"
60 #include "classic/rfcomm.h"
61 #include "classic/sdp_server.h"
62 #include "btstack_debug.h"
63 #include "classic/hfp_hf.h"
64
65 #include "mock.h"
66 #include "test_sequences.h"
67 #include "btstack.h"
68
69 const uint8_t rfcomm_channel_nr = 1;
70
71 static bd_addr_t device_addr = {0xD8,0xBb,0x2C,0xDf,0xF1,0x08};
72
73 static uint8_t codecs[2] = {1,2};
74 static uint16_t indicators[1] = {0x01};
75
76 static uint8_t service_level_connection_established = 0;
77 static uint8_t audio_connection_established = 0;
78 static uint8_t start_ringing = 0;
79 static uint8_t stop_ringing = 0;
80 static uint8_t call_termiated = 0;
81
82 static int supported_features_with_codec_negotiation = 438;
83
84 static uint16_t acl_handle = -1;
85
get_next_hfp_hf_command(void)86 static char * get_next_hfp_hf_command(void){
87 return get_next_hfp_command(0,2);
88 }
89
has_more_hfp_hf_commands(void)90 static int has_more_hfp_hf_commands(void){
91 return has_more_hfp_commands(0,2);
92 }
93
user_command(char cmd)94 static void user_command(char cmd){
95 switch (cmd){
96 case '#':
97 case '-':
98 case '+':
99 case '*':
100 printf("DTMF Code: %c\n", cmd);
101 hfp_hf_send_dtmf_code(acl_handle, cmd);
102 break;
103 case 'a':
104 printf("Establish Service level connection to device with Bluetooth address %s...\n", bd_addr_to_str(device_addr));
105 hfp_hf_establish_service_level_connection(device_addr);
106 break;
107 case 'A':
108 printf("Release Service level connection.\n");
109 hfp_hf_release_service_level_connection(acl_handle);
110 break;
111 case 'b':
112 printf("Establish Audio connection to device with Bluetooth address %s...\n", bd_addr_to_str(device_addr));
113 hfp_hf_establish_audio_connection(acl_handle);
114 break;
115 case 'B':
116 printf("Release Audio service level connection.\n");
117 hfp_hf_release_audio_connection(acl_handle);
118 break;
119 case 'C':
120 printf("Enable registration status update for all AG indicators.\n");
121 hfp_hf_enable_status_update_for_all_ag_indicators(acl_handle);
122 case 'c':
123 printf("Disable registration status update for all AG indicators.\n");
124 hfp_hf_disable_status_update_for_all_ag_indicators(acl_handle);
125 break;
126 case 'D':
127 printf("Set HFP AG registration status update for individual indicators (0111111).\n");
128 hfp_hf_set_status_update_for_individual_ag_indicators(acl_handle, 63);
129 break;
130 case 'd':
131 printf("Query network operator.\n");
132 hfp_hf_query_operator_selection(acl_handle);
133 break;
134 case 'E':
135 printf("Enable reporting of the extended AG error result code.\n");
136 hfp_hf_enable_report_extended_audio_gateway_error_result_code(acl_handle);
137 break;
138 case 'e':
139 printf("Disable reporting of the extended AG error result code.\n");
140 hfp_hf_disable_report_extended_audio_gateway_error_result_code(acl_handle);
141 break;
142 case 'f':
143 printf("Answer incoming call.\n");
144 hfp_hf_answer_incoming_call(acl_handle);
145 break;
146 case 'F':
147 printf("Hangup call.\n");
148 hfp_hf_terminate_call(acl_handle);
149 break;
150 case 'G':
151 printf("Reject incoming call.\n");
152 hfp_hf_reject_incoming_call(acl_handle);
153 break;
154 case 'g':
155 printf("Query operator.\n");
156 hfp_hf_query_operator_selection(acl_handle);
157 break;
158 case 't':
159 printf("Terminate HCI connection.\n");
160 gap_disconnect(acl_handle);
161 break;
162 case 'i':
163 printf("Dial 1234567\n");
164 hfp_hf_dial_number(acl_handle, (char *)"1234567");
165 break;
166 case 'I':
167 printf("Dial 7654321\n");
168 hfp_hf_dial_number(acl_handle, (char *)"7654321");
169 break;
170 case 'j':
171 printf("Dial #1\n");
172 hfp_hf_dial_memory(acl_handle, 1);
173 break;
174 case 'J':
175 printf("Dial #99\n");
176 hfp_hf_dial_memory(acl_handle, 99);
177 break;
178 case 'k':
179 printf("Deactivate call waiting notification\n");
180 hfp_hf_deactivate_call_waiting_notification(acl_handle);
181 break;
182 case 'K':
183 printf("Activate call waiting notification\n");
184 hfp_hf_activate_call_waiting_notification(acl_handle);
185 break;
186 case 'l':
187 printf("Deactivate calling line notification\n");
188 hfp_hf_deactivate_calling_line_notification(acl_handle);
189 break;
190 case 'L':
191 printf("Activate calling line notification\n");
192 hfp_hf_activate_calling_line_notification(acl_handle);
193 break;
194 case 'm':
195 printf("Deactivate echo canceling and noise reduction\n");
196 hfp_hf_deactivate_echo_canceling_and_noise_reduction(acl_handle);
197 break;
198 case 'n':
199 printf("Deactivate voice recognition\n");
200 hfp_hf_deactivate_voice_recognition(acl_handle);
201 break;
202 case 'N':
203 printf("Activate voice recognition\n");
204 hfp_hf_activate_voice_recognition(acl_handle);
205 break;
206 case 'o':
207 printf("Set speaker gain to 0 (minimum)\n");
208 hfp_hf_set_speaker_gain(acl_handle, 0);
209 break;
210 case 'O':
211 printf("Set speaker gain to 9 (default)\n");
212 hfp_hf_set_speaker_gain(acl_handle, 9);
213 break;
214 case 'p':
215 printf("Set speaker gain to 12 (higher)\n");
216 hfp_hf_set_speaker_gain(acl_handle, 12);
217 break;
218 case 'P':
219 printf("Set speaker gain to 15 (maximum)\n");
220 hfp_hf_set_speaker_gain(acl_handle, 15);
221 break;
222 case 'q':
223 printf("Set microphone gain to 0\n");
224 hfp_hf_set_microphone_gain(acl_handle, 0);
225 break;
226 case 'Q':
227 printf("Set microphone gain to 9\n");
228 hfp_hf_set_microphone_gain(acl_handle, 9);
229 break;
230 case 's':
231 printf("Set microphone gain to 12\n");
232 hfp_hf_set_microphone_gain(acl_handle, 12);
233 break;
234 case 'S':
235 printf("Set microphone gain to 15\n");
236 hfp_hf_set_microphone_gain(acl_handle, 15);
237 break;
238 case 'u':
239 printf("Send 'user busy' (Three-Way Call 0)\n");
240 hfp_hf_user_busy(acl_handle);
241 break;
242 case 'U':
243 printf("End active call and accept waiting/held call (Three-Way Call 1)\n");
244 hfp_hf_end_active_and_accept_other(acl_handle);
245 break;
246 case 'v':
247 printf("Swap active call and hold/waiting call (Three-Way Call 2)\n");
248 hfp_hf_swap_calls(acl_handle);
249 break;
250 case 'V':
251 printf("Join hold call (Three-Way Call 3)\n");
252 hfp_hf_join_held_call(acl_handle);
253 break;
254 case 'w':
255 printf("Connect calls (Three-Way Call 4)\n");
256 hfp_hf_connect_calls(acl_handle);
257 break;
258 case 'W':
259 printf("Redial\n");
260 hfp_hf_redial_last_number(acl_handle);
261 break;
262 case 'x':
263 printf("Request phone number for voice tag\n");
264 hfp_hf_request_phone_number_for_voice_tag(acl_handle);
265 break;
266 case 'X':
267 printf("Query current call status\n");
268 hfp_hf_query_current_call_status(acl_handle);
269 break;
270 case 'y':
271 printf("Release call with index 2\n");
272 hfp_hf_release_call_with_index(acl_handle, 2);
273 break;
274 case 'Y':
275 printf("Private consulation with call 2\n");
276 hfp_hf_private_consultation_with_call(acl_handle, 2);
277 break;
278 case '[':
279 printf("Query Response and Hold status (RHH ?)\n");
280 hfp_hf_rrh_query_status(acl_handle);
281 break;
282 case ']':
283 printf("Place call in a response and held state (RHH 0)\n");
284 hfp_hf_rrh_hold_call(acl_handle);
285 break;
286 case '{':
287 printf("Accept held call (RHH 1)\n");
288 hfp_hf_rrh_accept_held_call(acl_handle);
289 break;
290 case '}':
291 printf("Reject held call (RHH 2)\n");
292 hfp_hf_rrh_reject_held_call(acl_handle);
293 break;
294 case '?':
295 printf("Query Subscriber Number\n");
296 hfp_hf_query_subscriber_number(acl_handle);
297 break;
298 case '!':
299 printf("Update HF indicator with assigned number 1 (HFI)\n");
300 hfp_hf_set_hf_indicator(acl_handle, 1, 1);
301 break;
302 default:
303 printf("HF: undefined user command\n");
304 break;
305 }
306 }
307
simulate_test_sequence(hfp_test_item_t * test_item)308 static void simulate_test_sequence(hfp_test_item_t * test_item){
309 char ** test_steps = test_item->test;
310 printf("\nSimulate test sequence: \"%s\" [%d steps]\n", test_item->name, test_item->len);
311
312 int i = 0;
313 int previous_step = -1;
314 while ( i < test_item->len){
315 previous_step++;
316 CHECK_EQUAL(i >= previous_step, 1);
317
318 char * expected_cmd = test_steps[i];
319 int expected_cmd_len = strlen(expected_cmd);
320 printf("\nStep %d, %s \n", i, expected_cmd);
321
322 if (strncmp(expected_cmd, "USER:", 5) == 0){
323 user_command(expected_cmd[5]);
324 while (has_more_hfp_hf_commands()){
325 // empty rfcomm payload buffer
326 get_next_hfp_hf_command();
327 }
328 i++;
329
330 } else if (strncmp(expected_cmd, "AT+BAC=", 7) == 0){
331 int parsed_codecs[2];
332 uint8_t new_codecs[2];
333 sscanf(&expected_cmd[7],"%d,%d", &parsed_codecs[0], &parsed_codecs[1]);
334 new_codecs[0] = parsed_codecs[0];
335 new_codecs[1] = parsed_codecs[1];
336 hfp_hf_init_codecs(2, (uint8_t*)new_codecs);
337 while (has_more_hfp_hf_commands()){
338 // empty rfcomm payload buffer
339 get_next_hfp_hf_command();
340 }
341 i++;
342 } else if (strncmp(expected_cmd, "AT+BRSF=", 8) == 0 ){
343 int supported_features = 0;
344 sscanf(&expected_cmd[8],"%d", &supported_features);
345 printf("Call hfp_hf_init with SF %d\n", supported_features);
346 hfp_hf_release_service_level_connection(acl_handle);
347
348 hfp_hf_init_supported_features(supported_features);
349
350 user_command('a');
351 while (has_more_hfp_hf_commands()){
352 // empty rfcomm payload buffer
353 get_next_hfp_hf_command();
354 }
355 i++;
356 } else if (strncmp(expected_cmd, "AT+BCC", 6) == 0){
357 user_command('b');
358 while (has_more_hfp_hf_commands()){
359 // empty rfcomm payload buffer
360 get_next_hfp_hf_command();
361 }
362 i++;
363 } else if (strncmp(expected_cmd, "AT", 2) == 0){
364 printf("\n---> NEXT STEP expect from HF: %s\n", expected_cmd);
365 while (has_more_hfp_hf_commands()){
366 char * ag_cmd = get_next_hfp_hf_command();
367 printf("HF response verify %s == %s[%d]\n", expected_cmd, ag_cmd, expected_cmd_len);
368
369 int equal_cmds = strncmp(ag_cmd, expected_cmd, expected_cmd_len) == 0;
370 if (!equal_cmds){
371 printf("\nError: Expected:'%s', but got:'%s'\n", expected_cmd, ag_cmd);
372 CHECK_EQUAL(equal_cmds,1);
373 return;
374 }
375 printf("Verified: '%s'\n", expected_cmd);
376 i++;
377 if (i < test_item->len){
378 expected_cmd = test_steps[i];
379 expected_cmd_len = strlen(expected_cmd);
380 }
381 }
382 } else {
383 //printf("\n---> NEXT STEP receive from AG: '%s'\n", expected_cmd);
384 inject_hfp_command_to_hf((uint8_t*)expected_cmd, strlen(expected_cmd));
385 i++;
386 }
387 }
388 }
389
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * event,uint16_t event_size)390 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){
391 if (event[0] != HCI_EVENT_HFP_META) return;
392
393 switch (event[2]) {
394 case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
395 printf("\n** SLC established **\n\n");
396 acl_handle = hfp_subevent_service_level_connection_established_get_acl_handle(event);
397 service_level_connection_established = 1;
398 audio_connection_established = 0;
399 break;
400 case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
401 printf("\n** SLC released **\n\n");
402 service_level_connection_established = 0;
403 break;
404 case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED:
405 printf("\n** AC established **\n\n");
406 audio_connection_established = 1;
407 break;
408 case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED:
409 printf("\n** AC released **\n\n");
410 audio_connection_established = 0;
411 break;
412 case HFP_SUBEVENT_START_RINGING:
413 printf("\n** Start ringing **\n\n");
414 start_ringing = 1;
415 break;
416 case HFP_SUBEVENT_STOP_RINGING:
417 printf("\n** Stop ringing **\n\n");
418 stop_ringing = 1;
419 start_ringing = 0;
420 break;
421 case HFP_SUBEVENT_CALL_TERMINATED:
422 call_termiated = 1;
423 break;
424 case HFP_SUBEVENT_COMPLETE:
425 printf("HFP AG HFP_SUBEVENT_COMPLETE.\n");
426 break;
427 case HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED:
428 printf("AG_INDICATOR_STATUS_CHANGED, AG indicator (index: %d) to: %d of range [%d, %d], name '%s'\n",
429 hfp_subevent_ag_indicator_status_changed_get_indicator_index(event),
430 hfp_subevent_ag_indicator_status_changed_get_indicator_status(event),
431 hfp_subevent_ag_indicator_status_changed_get_indicator_min_range(event),
432 hfp_subevent_ag_indicator_status_changed_get_indicator_max_range(event),
433 (const char*) hfp_subevent_ag_indicator_status_changed_get_indicator_name(event));
434 break;
435 case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
436 printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n",
437 hfp_subevent_network_operator_changed_get_network_operator_mode(event),
438 hfp_subevent_network_operator_changed_get_network_operator_format(event),
439 (char *) hfp_subevent_network_operator_changed_get_network_operator_name(event));
440 break;
441 case HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR:
442 printf("EXTENDED_AUDIO_GATEWAY_ERROR_REPORT, status : %d\n",
443 hfp_subevent_extended_audio_gateway_error_get_error(event));
444 break;
445 case HFP_SUBEVENT_RING:
446 printf("** Ring **\n");
447 break;
448 case HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG:
449 printf("Phone number for voice tag: %s\n",
450 (const char *) hfp_subevent_number_for_voice_tag_get_number(event));
451 break;
452 case HFP_SUBEVENT_SPEAKER_VOLUME:
453 printf("Speaker volume: gain %u\n",
454 hfp_subevent_speaker_volume_get_gain(event));
455 break;
456 case HFP_SUBEVENT_MICROPHONE_VOLUME:
457 printf("Microphone volume: gain %u\n",
458 hfp_subevent_microphone_volume_get_gain(event));
459 break;
460 case HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION:
461 printf("Caller ID, number %s\n", hfp_subevent_calling_line_identification_notification_get_number(event));
462 break;
463 default:
464 printf("event not handled %u\n", event[2]);
465 break;
466 }
467 }
468
469
TEST_GROUP(HFPClient)470 TEST_GROUP(HFPClient){
471
472 void setup(void){
473 service_level_connection_established = 0;
474 audio_connection_established = 0;
475 start_ringing = 0;
476 stop_ringing = 0;
477 call_termiated = 0;
478
479 hfp_hf_init(rfcomm_channel_nr);
480 hfp_hf_init_supported_features(supported_features_with_codec_negotiation);
481 hfp_hf_init_hf_indicators(sizeof(indicators)/sizeof(uint16_t), indicators);
482
483 hfp_hf_init_codecs(sizeof(codecs), codecs);
484 }
485
486 void teardown(void){
487 hfp_hf_release_audio_connection(acl_handle);
488 hfp_hf_release_service_level_connection(acl_handle);
489
490 service_level_connection_established = 0;
491 audio_connection_established = 0;
492 }
493 };
494
495
TEST(HFPClient,PTSRHHTests)496 TEST(HFPClient, PTSRHHTests){
497 for (int i = 0; i < hfp_pts_hf_rhh_tests_size(); i++){
498 setup();
499 simulate_test_sequence(&hfp_pts_hf_rhh_tests()[i]);
500 teardown();
501 }
502 }
503
TEST(HFPClient,PTSECCTests)504 TEST(HFPClient, PTSECCTests){
505 for (int i = 0; i < hfp_pts_hf_ecc_tests_size(); i++){
506 setup();
507 simulate_test_sequence(&hfp_pts_hf_ecc_tests()[i]);
508 teardown();
509 }
510 }
511
TEST(HFPClient,PTSECSTests)512 TEST(HFPClient, PTSECSTests){
513 for (int i = 0; i < hfp_pts_hf_ecs_tests_size(); i++){
514 setup();
515 simulate_test_sequence(&hfp_pts_hf_ecs_tests()[i]);
516 teardown();
517 }
518 }
519
TEST(HFPClient,PTSTWCTests)520 TEST(HFPClient, PTSTWCTests){
521 for (int i = 0; i < hfp_pts_hf_twc_tests_size(); i++){
522 setup();
523 simulate_test_sequence(&hfp_pts_hf_twc_tests()[i]);
524 teardown();
525 }
526 }
527
TEST(HFPClient,PTSATATests)528 TEST(HFPClient, PTSATATests){
529 for (int i = 0; i < hfp_pts_hf_ata_tests_size(); i++){
530 setup();
531 simulate_test_sequence(&hfp_pts_hf_ata_tests()[i]);
532 teardown();
533 }
534 }
535
TEST(HFPClient,PTSSLCTests)536 TEST(HFPClient, PTSSLCTests){
537 for (int i = 0; i < hfp_pts_hf_slc_tests_size(); i++){
538 setup();
539 simulate_test_sequence(&hfp_pts_hf_slc_tests()[i]);
540 teardown();
541 }
542 }
543
main(int argc,const char * argv[])544 int main (int argc, const char * argv[]){
545 hfp_hf_register_packet_handler(packet_handler);
546 return CommandLineTestRunner::RunAllTests(argc, argv);
547 }
548