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 AG 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 55 #include "btstack_debug.h" 56 #include "btstack_event.h" 57 #include "btstack_run_loop.h" 58 #include "classic/hfp_ag.h" 59 #include "classic/rfcomm.h" 60 #include "classic/sdp_server.h" 61 #include "classic/sdp_util.h" 62 #include "hci.h" 63 #include "hci_cmd.h" 64 #include "l2cap.h" 65 66 #include "mock.h" 67 #include "test_sequences.h" 68 69 static bd_addr_t pts_addr = {0x00,0x15,0x83,0x5F,0x9D,0x46}; 70 71 const uint8_t rfcomm_channel_nr = 1; 72 73 static bd_addr_t device_addr = {0xD8,0xBb,0x2C,0xDf,0xF1,0x08}; 74 75 static uint8_t codecs[2] = {1, 3}; 76 77 static int ag_indicators_nr = 7; 78 static hfp_ag_indicator_t ag_indicators[] = { 79 // index, name, min range, max range, status, mandatory, enabled, status changed 80 {1, "service", 0, 1, 1, 0, 0, 0}, 81 {2, "call", 0, 1, 0, 1, 1, 0}, 82 {3, "callsetup", 0, 3, 0, 1, 1, 0}, 83 {4, "battchg", 0, 5, 3, 0, 0, 0}, 84 {5, "signal", 0, 5, 5, 0, 0, 0}, 85 {6, "roam", 0, 1, 0, 0, 0, 0}, 86 {7, "callheld", 0, 2, 0, 1, 1, 0} 87 }; 88 89 hfp_ag_indicator_t ag_indicators_temp[] = { 90 // index, name, min range, max range, status, mandatory, enabled, status changed 91 {1, "service", 0, 1, 1, 0, 0, 0}, 92 {2, "call", 0, 1, 0, 1, 1, 0}, 93 {3, "callsetup", 0, 3, 0, 1, 1, 0}, 94 {4, "battchg", 0, 5, 3, 0, 0, 0}, 95 {5, "signal", 0, 5, 5, 0, 0, 0}, 96 {6, "roam", 0, 1, 0, 0, 0, 0}, 97 {7, "callheld", 0, 2, 0, 1, 1, 0} 98 }; 99 100 static int supported_features_with_codec_negotiation = 4079; // 0011 1110 1111 101 102 static int call_hold_services_nr = 5; 103 static const char* call_hold_services[] = {"1", "1x", "2", "2x", "3"}; 104 105 static int hf_indicators_nr = 2; 106 static hfp_generic_status_indicator_t hf_indicators[] = { 107 {1, 1}, 108 {2, 1}, 109 }; 110 111 static hci_con_handle_t acl_handle = -1; 112 static int memory_1_enabled = 1; 113 114 static int has_more_hfp_ag_commands(void){ 115 return has_more_hfp_commands(2,2); 116 } 117 118 static char * get_next_hfp_ag_command(void){ 119 return get_next_hfp_command(2,2); 120 } 121 122 static void user_command(char cmd){ 123 switch (cmd){ 124 case 'a': 125 memcpy(device_addr, pts_addr, 6); 126 printf("Establish HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr)); 127 hfp_ag_establish_service_level_connection(device_addr); 128 break; 129 case 'A': 130 printf("Release HFP service level connection.\n"); 131 hfp_ag_release_service_level_connection(acl_handle); 132 break; 133 case 'Z': 134 printf("Release HFP service level connection to %s...\n", bd_addr_to_str(device_addr)); 135 hfp_ag_release_service_level_connection(acl_handle); 136 break; 137 case 'b': 138 printf("Establish Audio connection %s...\n", bd_addr_to_str(device_addr)); 139 hfp_ag_establish_audio_connection(acl_handle); 140 break; 141 case 'B': 142 printf("Release Audio connection.\n"); 143 hfp_ag_release_audio_connection(acl_handle); 144 break; 145 case 'c': 146 printf("Simulate incoming call from 1234567\n"); 147 hfp_ag_set_clip(129, "1234567"); 148 hfp_ag_incoming_call(); 149 break; 150 case 'm': 151 printf("Simulate incoming call from 7654321\n"); 152 hfp_ag_set_clip(129, "7654321"); 153 hfp_ag_incoming_call(); 154 break; 155 case 'C': 156 printf("Simulate terminate call\n"); 157 hfp_ag_call_dropped(); 158 break; 159 case 'd': 160 printf("Report AG failure\n"); 161 hfp_ag_report_extended_audio_gateway_error_result_code(acl_handle, HFP_CME_ERROR_AG_FAILURE); 162 break; 163 case 'e': 164 printf("Answer call on AG\n"); 165 hfp_ag_answer_incoming_call(); 166 break; 167 case 'E': 168 printf("Reject call on AG\n"); 169 hfp_ag_terminate_call(); 170 break; 171 case 'f': 172 printf("Disable cellular network\n"); 173 hfp_ag_set_registration_status(0); 174 break; 175 case 'F': 176 printf("Enable cellular network\n"); 177 hfp_ag_set_registration_status(1); 178 break; 179 case 'g': 180 printf("Set signal strength to 0\n"); 181 hfp_ag_set_signal_strength(0); 182 break; 183 case 'G': 184 printf("Set signal strength to 5\n"); 185 hfp_ag_set_signal_strength(5); 186 break; 187 case 'h': 188 printf("Disable roaming\n"); 189 hfp_ag_set_roaming_status(0); 190 break; 191 case 'H': 192 printf("Enable roaming\n"); 193 hfp_ag_set_roaming_status(1); 194 break; 195 case 'i': 196 printf("Set battery level to 3\n"); 197 hfp_ag_set_battery_level(3); 198 break; 199 case 'I': 200 printf("Set battery level to 5\n"); 201 hfp_ag_set_battery_level(5); 202 break; 203 case 'j': 204 printf("Answering call on remote side\n"); 205 hfp_ag_outgoing_call_established(); 206 break; 207 case 'r': 208 printf("Disable in-band ring tone\n"); 209 hfp_ag_set_use_in_band_ring_tone(0); 210 break; 211 case 'k': 212 printf("Memory 1 cleared\n"); 213 memory_1_enabled = 0; 214 break; 215 case 'K': 216 printf("Memory 1 set\n"); 217 memory_1_enabled = 1; 218 break; 219 case 'l': 220 printf("Last dialed number cleared\n"); 221 hfp_ag_clear_last_dialed_number(); 222 break; 223 case 'L': 224 printf("Outgoing call connected, ringing\n"); 225 hfp_ag_outgoing_call_ringing(); 226 break; 227 case 'n': 228 printf("Disable Voice Recognition\n"); 229 hfp_ag_deactivate_voice_recognition(acl_handle); 230 break; 231 case 'N': 232 printf("Enable Voice Recognition\n"); 233 hfp_ag_activate_voice_recognition(acl_handle); 234 break; 235 case 'o': 236 printf("Set speaker gain to 0 (minimum)\n"); 237 hfp_ag_set_speaker_gain(acl_handle, 0); 238 break; 239 case 'O': 240 printf("Set speaker gain to 9 (default)\n"); 241 hfp_ag_set_speaker_gain(acl_handle, 9); 242 break; 243 case 'p': 244 printf("Set speaker gain to 12 (higher)\n"); 245 hfp_ag_set_speaker_gain(acl_handle, 12); 246 break; 247 case 'P': 248 printf("Set speaker gain to 15 (maximum)\n"); 249 hfp_ag_set_speaker_gain(acl_handle, 15); 250 break; 251 case 'q': 252 printf("Set microphone gain to 0\n"); 253 hfp_ag_set_microphone_gain(acl_handle, 0); 254 break; 255 case 'Q': 256 printf("Set microphone gain to 9\n"); 257 hfp_ag_set_microphone_gain(acl_handle, 9); 258 break; 259 case 's': 260 printf("Set microphone gain to 12\n"); 261 hfp_ag_set_microphone_gain(acl_handle, 12); 262 break; 263 case 'S': 264 printf("Set microphone gain to 15\n"); 265 hfp_ag_set_microphone_gain(acl_handle, 15); 266 break; 267 case 'R': 268 printf("Enable in-band ring tone\n"); 269 hfp_ag_set_use_in_band_ring_tone(1); 270 break; 271 case 't': 272 printf("Terminate HCI connection.\n"); 273 gap_disconnect(acl_handle); 274 break; 275 case 'u': 276 printf("Join held call\n"); 277 hfp_ag_join_held_call(); 278 break; 279 // case 'v': 280 // printf("Starting inquiry scan..\n"); 281 // gap_inquiry_start(15); 282 // break; 283 case 'w': 284 printf("AG: Put incoming call on hold (Response and Hold)\n"); 285 hfp_ag_hold_incoming_call(); 286 break; 287 case 'x': 288 printf("AG: Accept held incoming call (Response and Hold)\n"); 289 hfp_ag_accept_held_incoming_call(); 290 break; 291 case 'X': 292 printf("AG: Reject held incoming call (Response and Hold)\n"); 293 hfp_ag_reject_held_incoming_call(); 294 break; 295 default: 296 printf("unknow cmd %c\n", cmd); 297 break; 298 } 299 } 300 301 static void simulate_test_sequence(hfp_test_item_t * test_item){ 302 char ** test_steps = test_item->test; 303 printf("\nSimulate test sequence: \"%s\"\n", test_item->name); 304 305 int i = 0; 306 int previous_step = -1; 307 while ( i < test_item->len){ 308 previous_step++; 309 CHECK_EQUAL(i >= previous_step, 1); 310 311 char * expected_cmd = test_steps[i]; 312 int expected_cmd_len = strlen(expected_cmd); 313 printf("\nStep %d, %s \n", i, expected_cmd); 314 315 if (strncmp(expected_cmd, "USER:", 5) == 0){ 316 printf("\n---> USER: "); 317 user_command(expected_cmd[5]); 318 i++; 319 } else if (strncmp(expected_cmd, "AT", 2) == 0){ 320 // printf("\n---> NEXT STEP receive from HF: '%s'\n", expected_cmd); 321 inject_hfp_command_to_ag((uint8_t*)expected_cmd, expected_cmd_len); 322 i++; 323 324 } else { 325 while (has_more_hfp_ag_commands()){ 326 printf("\n---> NEXT STEP expect from AG: %s\n", expected_cmd); 327 char * ag_cmd = get_next_hfp_ag_command(); 328 329 int equal_cmds = strncmp(ag_cmd, expected_cmd, expected_cmd_len) == 0; 330 // printf("CHECK: %s == %s -> %u", ag_cmd, expected_cmd, equal_cmds); 331 if (!equal_cmds){ 332 printf("\nError: Expected:'%s', but got:'%s'\n", expected_cmd, ag_cmd); 333 CHECK_EQUAL(equal_cmds,1); 334 return; 335 } 336 printf("Verified: '%s'\n", expected_cmd); 337 338 i++; 339 if (i < test_item->len){ 340 expected_cmd = test_steps[i]; 341 expected_cmd_len = strlen(expected_cmd); 342 } 343 } 344 // printf("\n---> NEXT STEP trigger once more AG\n"); 345 inject_hfp_command_to_ag((uint8_t*)"NOP",3); 346 } 347 } 348 } 349 350 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){ 351 352 if (event[0] != HCI_EVENT_HFP_META) return; 353 const char * dial_string; 354 const char * dtmf_string; 355 356 switch (event[2]) { 357 case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 358 acl_handle = hfp_subevent_service_level_connection_established_get_acl_handle(event); 359 printf("Service level connection established.\n"); 360 break; 361 case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED: 362 printf("Service level connection released.\n"); 363 break; 364 case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED: 365 printf("\n** Audio connection established **\n"); 366 break; 367 case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED: 368 printf("\n** Audio connection released **\n"); 369 break; 370 case HFP_SUBEVENT_START_RINGING: 371 printf("\n** Start Ringing **\n"); 372 break; 373 case HFP_SUBEVENT_STOP_RINGING: 374 printf("\n** Stop Ringing **\n"); 375 break; 376 case HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER: 377 dial_string = (const char *) hfp_subevent_place_call_with_number_get_number(event); 378 printf("\n** Outgoing call '%s' **\n", dial_string); 379 // validate number 380 if ( strcmp("1234567", dial_string) == 0 381 || strcmp("7654321", dial_string) == 0 382 || (memory_1_enabled && strcmp(">1", dial_string) == 0)){ 383 printf("Dialstring valid: accept call\n"); 384 hfp_ag_outgoing_call_accepted(); 385 } else { 386 printf("Dialstring invalid: reject call\n"); 387 hfp_ag_outgoing_call_rejected(); 388 } 389 break; 390 case HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG: 391 printf("\n** Attach number to voice tag. Sending '1234567\n"); 392 hfp_ag_send_phone_number_for_voice_tag(acl_handle, "1234567"); 393 break; 394 case HFP_SUBEVENT_TRANSMIT_DTMF_CODES: 395 dtmf_string = (const char *) hfp_subevent_transmit_dtmf_codes_get_dtmf(event); 396 printf("\n** Send DTMF Codes: '%s'\n",dtmf_string); 397 hfp_ag_send_dtmf_code_done(acl_handle); 398 break; 399 default: 400 break; 401 } 402 403 } 404 405 406 TEST_GROUP(HFPClient){ 407 void setup(void){ 408 hfp_ag_init(rfcomm_channel_nr); 409 hfp_ag_init_supported_features(supported_features_with_codec_negotiation); 410 hfp_ag_init_codecs(sizeof(codecs), codecs); 411 hfp_ag_init_ag_indicators(ag_indicators_nr, ag_indicators); 412 hfp_ag_init_hf_indicators(hf_indicators_nr, hf_indicators); 413 hfp_ag_init_call_hold_services(call_hold_services_nr, call_hold_services); 414 } 415 416 void teardown(void){ 417 hfp_ag_release_audio_connection(acl_handle); 418 hfp_ag_release_service_level_connection(acl_handle); 419 } 420 }; 421 422 423 TEST(HFPClient, PTSRHHTests){ 424 for (int i = 0; i < hfp_pts_ag_rhh_tests_size(); i++){ 425 setup(); 426 simulate_test_sequence(&hfp_pts_ag_rhh_tests()[i]); 427 teardown(); 428 } 429 } 430 431 TEST(HFPClient, PTSECCTests){ 432 for (int i = 0; i < hfp_pts_ag_ecc_tests_size(); i++){ 433 setup(); 434 simulate_test_sequence(&hfp_pts_ag_ecc_tests()[i]); 435 teardown(); 436 } 437 } 438 439 TEST(HFPClient, PTSECSTests){ 440 for (int i = 0; i < hfp_pts_ag_ecs_tests_size(); i++){ 441 setup(); 442 simulate_test_sequence(&hfp_pts_ag_ecs_tests()[i]); 443 teardown(); 444 } 445 } 446 447 TEST(HFPClient, PTSTWCTests){ 448 for (int i = 0; i < hfp_pts_ag_twc_tests_size(); i++){ 449 setup(); 450 simulate_test_sequence(&hfp_pts_ag_twc_tests()[i]); 451 teardown(); 452 } 453 } 454 455 TEST(HFPClient, PTSATATests){ 456 for (int i = 0; i < hfp_pts_ag_ata_tests_size(); i++){ 457 setup(); 458 simulate_test_sequence(&hfp_pts_ag_ata_tests()[i]); 459 teardown(); 460 } 461 } 462 463 TEST(HFPClient, PTSSLCTests){ 464 for (int i = 0; i < hfp_pts_ag_slc_tests_size(); i++){ 465 setup(); 466 simulate_test_sequence(&hfp_pts_ag_slc_tests()[i]); 467 teardown(); 468 } 469 } 470 471 472 int main (int argc, const char * argv[]){ 473 hfp_ag_register_packet_handler(packet_handler); 474 475 return CommandLineTestRunner::RunAllTests(argc, argv); 476 } 477