11d3bd1e5SMatthias Ringwald /* 21d3bd1e5SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 31d3bd1e5SMatthias Ringwald * 41d3bd1e5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 51d3bd1e5SMatthias Ringwald * modification, are permitted provided that the following conditions 61d3bd1e5SMatthias Ringwald * are met: 71d3bd1e5SMatthias Ringwald * 81d3bd1e5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 91d3bd1e5SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 101d3bd1e5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 111d3bd1e5SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 121d3bd1e5SMatthias Ringwald * documentation and/or other materials provided with the distribution. 131d3bd1e5SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 141d3bd1e5SMatthias Ringwald * contributors may be used to endorse or promote products derived 151d3bd1e5SMatthias Ringwald * from this software without specific prior written permission. 161d3bd1e5SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 171d3bd1e5SMatthias Ringwald * personal benefit and not for any commercial purpose or for 181d3bd1e5SMatthias Ringwald * monetary gain. 191d3bd1e5SMatthias Ringwald * 201d3bd1e5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 211d3bd1e5SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 221d3bd1e5SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 231d3bd1e5SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 241d3bd1e5SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 251d3bd1e5SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 261d3bd1e5SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 271d3bd1e5SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 281d3bd1e5SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 291d3bd1e5SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 301d3bd1e5SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311d3bd1e5SMatthias Ringwald * SUCH DAMAGE. 321d3bd1e5SMatthias Ringwald * 331d3bd1e5SMatthias Ringwald * Please inquire about commercial licensing options at 341d3bd1e5SMatthias Ringwald * [email protected] 351d3bd1e5SMatthias Ringwald * 361d3bd1e5SMatthias Ringwald */ 371d3bd1e5SMatthias Ringwald 381d3bd1e5SMatthias Ringwald 391d3bd1e5SMatthias Ringwald #include <stdint.h> 401d3bd1e5SMatthias Ringwald #include <stdio.h> 411d3bd1e5SMatthias Ringwald #include <stdlib.h> 421d3bd1e5SMatthias Ringwald #include <string.h> 431d3bd1e5SMatthias Ringwald 441d3bd1e5SMatthias Ringwald #include "CppUTest/TestHarness.h" 451d3bd1e5SMatthias Ringwald #include "CppUTest/CommandLineTestRunner.h" 461d3bd1e5SMatthias Ringwald 47d2621a77SMatthias Ringwald #include "btstack_event.h" 481d3bd1e5SMatthias Ringwald #include "classic/hfp.h" 49d2621a77SMatthias Ringwald #include "classic/hfp_hf.h" 501d3bd1e5SMatthias Ringwald #include "classic/hfp_ag.h" 511d3bd1e5SMatthias Ringwald 521d3bd1e5SMatthias Ringwald void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree); 531d3bd1e5SMatthias Ringwald 541d3bd1e5SMatthias Ringwald static hfp_connection_t context; 551d3bd1e5SMatthias Ringwald static int hfp_ag_indicators_nr = 7; 561d3bd1e5SMatthias Ringwald static hfp_ag_indicator_t hfp_ag_indicators[] = { 571d3bd1e5SMatthias Ringwald // index, name, min range, max range, status, mandatory, enabled, status changed 581d3bd1e5SMatthias Ringwald {1, "service", 0, 1, 1, 0, 0, 0}, 591d3bd1e5SMatthias Ringwald {2, "call", 0, 1, 0, 1, 1, 0}, 601d3bd1e5SMatthias Ringwald {3, "callsetup", 0, 3, 0, 1, 1, 0}, 611d3bd1e5SMatthias Ringwald {4, "battchg", 0, 5, 3, 0, 0, 0}, 621d3bd1e5SMatthias Ringwald {5, "signal", 0, 5, 5, 0, 0, 0}, 631d3bd1e5SMatthias Ringwald {6, "roam", 0, 1, 0, 0, 0, 0}, 641d3bd1e5SMatthias Ringwald {7, "callheld", 0, 2, 0, 1, 1, 0} 651d3bd1e5SMatthias Ringwald }; 661d3bd1e5SMatthias Ringwald static uint8_t call_status_index = 2; 671d3bd1e5SMatthias Ringwald static uint8_t callsetup_status_index = 3; 681d3bd1e5SMatthias Ringwald static uint8_t callheld_status_index = 7; 691d3bd1e5SMatthias Ringwald 702cd3b4c4SMatthias Ringwald // #define LOG_LINE_BUFFER 712cd3b4c4SMatthias Ringwald static void hfp_at_parser_test_dump_line_buffer(void){ 722cd3b4c4SMatthias Ringwald #ifdef LOG_LINE_BUFFER 732cd3b4c4SMatthias Ringwald uint16_t line_len = strlen(reinterpret_cast<const char *>(context.line_buffer)); 742cd3b4c4SMatthias Ringwald printf("\nLine buffer: %s\n", context.line_buffer); 752cd3b4c4SMatthias Ringwald printf_hexdump(context.line_buffer, line_len); 762cd3b4c4SMatthias Ringwald #endif 772cd3b4c4SMatthias Ringwald } 781d3bd1e5SMatthias Ringwald 791d3bd1e5SMatthias Ringwald static void parse_ag(const char * packet){ 801d3bd1e5SMatthias Ringwald for (uint16_t pos = 0; pos < strlen(packet); pos++){ 811d3bd1e5SMatthias Ringwald hfp_parse(&context, packet[pos], 0); 821d3bd1e5SMatthias Ringwald } 831d3bd1e5SMatthias Ringwald } 841d3bd1e5SMatthias Ringwald 851d3bd1e5SMatthias Ringwald static void parse_hf(const char * packet){ 861d3bd1e5SMatthias Ringwald for (uint16_t pos = 0; pos < strlen(packet); pos++){ 871d3bd1e5SMatthias Ringwald hfp_parse(&context, packet[pos], 1); 881d3bd1e5SMatthias Ringwald } 891d3bd1e5SMatthias Ringwald } 901d3bd1e5SMatthias Ringwald 911d3bd1e5SMatthias Ringwald TEST_GROUP(HFPParser){ 921d3bd1e5SMatthias Ringwald char packet[200]; 931d3bd1e5SMatthias Ringwald int pos; 941d3bd1e5SMatthias Ringwald int offset; 951d3bd1e5SMatthias Ringwald 961d3bd1e5SMatthias Ringwald void setup(void){ 97d2621a77SMatthias Ringwald hfp_init(); 98016a59dfSMatthias Ringwald memset(&context, 0, sizeof(hfp_connection_t)); 991d3bd1e5SMatthias Ringwald context.parser_state = HFP_PARSER_CMD_HEADER; 1001d3bd1e5SMatthias Ringwald context.parser_item_index = 0; 1011d3bd1e5SMatthias Ringwald context.line_size = 0; 1021d3bd1e5SMatthias Ringwald context.ag_indicators_nr = 0; 1031d3bd1e5SMatthias Ringwald context.remote_codecs_nr = 0; 104016a59dfSMatthias Ringwald context.bnip_number[0] = 0; 105016a59dfSMatthias Ringwald context.bnip_type = 0; 1061d3bd1e5SMatthias Ringwald memset(packet,0, sizeof(packet)); 1071d3bd1e5SMatthias Ringwald } 108d2621a77SMatthias Ringwald 109d2621a77SMatthias Ringwald void teardown(void){ 110d2621a77SMatthias Ringwald hfp_deinit(); 111d2621a77SMatthias Ringwald } 1121d3bd1e5SMatthias Ringwald }; 1131d3bd1e5SMatthias Ringwald 1141d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_OK){ 11520d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s\r\n", HFP_OK); 1161d3bd1e5SMatthias Ringwald parse_hf(packet); 1171d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 1181d3bd1e5SMatthias Ringwald } 1191d3bd1e5SMatthias Ringwald 1201d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_SUPPORTED_FEATURES){ 12120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:1007\r\n\r\nOK\r\n", HFP_SUPPORTED_FEATURES); 1221d3bd1e5SMatthias Ringwald parse_hf(packet); 1231d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 1241d3bd1e5SMatthias Ringwald CHECK_EQUAL(1007, context.remote_supported_features); 1251d3bd1e5SMatthias Ringwald } 1261d3bd1e5SMatthias Ringwald 1271d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_CMD_INDICATORS_QUERY){ 12820d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s?\r\n", HFP_INDICATOR); 1291d3bd1e5SMatthias Ringwald parse_ag(packet); 1301d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS, context.command); 1311d3bd1e5SMatthias Ringwald } 1321d3bd1e5SMatthias Ringwald 1331d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_CMD_INDICATORS_RETRIEVE){ 13420d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=?\r\n", HFP_INDICATOR); 1351d3bd1e5SMatthias Ringwald parse_ag(packet); 1361d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RETRIEVE_AG_INDICATORS, context.command); 1371d3bd1e5SMatthias Ringwald } 1381d3bd1e5SMatthias Ringwald 1391d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_INDICATORS){ 1401d3bd1e5SMatthias Ringwald offset = 0; 1411d3bd1e5SMatthias Ringwald offset += snprintf(packet, sizeof(packet), "%s:", HFP_INDICATOR); 1421d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 1431d3bd1e5SMatthias Ringwald if (pos != 0) { 1441d3bd1e5SMatthias Ringwald packet[offset++] = ','; 1451d3bd1e5SMatthias Ringwald } 1461d3bd1e5SMatthias Ringwald offset += snprintf(packet+offset, sizeof(packet)-offset, "(\"%s\", (%d, %d)),", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range); 1471d3bd1e5SMatthias Ringwald } 1481d3bd1e5SMatthias Ringwald offset += snprintf(packet+offset, sizeof(packet)-offset, "\r\n\r\nOK\r\n"); 1491d3bd1e5SMatthias Ringwald context.state = HFP_W4_RETRIEVE_INDICATORS; 1501d3bd1e5SMatthias Ringwald 1511d3bd1e5SMatthias Ringwald parse_hf(packet); 1521d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 1531d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators_nr, context.ag_indicators_nr); 1541d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 1551d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].index, context.ag_indicators[pos].index); 1561d3bd1e5SMatthias Ringwald STRCMP_EQUAL(hfp_ag_indicators[pos].name, context.ag_indicators[pos].name); 1571d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].min_range, context.ag_indicators[pos].min_range); 1581d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].max_range, context.ag_indicators[pos].max_range); 1591d3bd1e5SMatthias Ringwald } 1601d3bd1e5SMatthias Ringwald } 1611d3bd1e5SMatthias Ringwald 1621d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_INDICATORS_RANGE){ 1631d3bd1e5SMatthias Ringwald offset = 0; 1641d3bd1e5SMatthias Ringwald offset += snprintf(packet, sizeof(packet), "%s:", HFP_INDICATOR); 1651d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 1661d3bd1e5SMatthias Ringwald if (pos != 0) { 1671d3bd1e5SMatthias Ringwald packet[offset++] = ','; 1681d3bd1e5SMatthias Ringwald } 1691d3bd1e5SMatthias Ringwald offset += snprintf(packet+offset, sizeof(packet)-offset, "(\"%s\", (%d-%d)),", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range); 1701d3bd1e5SMatthias Ringwald } 1711d3bd1e5SMatthias Ringwald offset += snprintf(packet+offset, sizeof(packet)-offset, "\r\n\r\nOK\r\n"); 1721d3bd1e5SMatthias Ringwald context.state = HFP_W4_RETRIEVE_INDICATORS; 1731d3bd1e5SMatthias Ringwald 1741d3bd1e5SMatthias Ringwald parse_hf(packet); 1751d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 1761d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators_nr, context.ag_indicators_nr); 1771d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 1781d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].index, context.ag_indicators[pos].index); 1791d3bd1e5SMatthias Ringwald STRCMP_EQUAL(hfp_ag_indicators[pos].name, context.ag_indicators[pos].name); 1801d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].min_range, context.ag_indicators[pos].min_range); 1811d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].max_range, context.ag_indicators[pos].max_range); 1821d3bd1e5SMatthias Ringwald } 1831d3bd1e5SMatthias Ringwald } 1841d3bd1e5SMatthias Ringwald 1851d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_INDICATOR_STATUS){ 1861d3bd1e5SMatthias Ringwald // send status 1871d3bd1e5SMatthias Ringwald offset = 0; 1881d3bd1e5SMatthias Ringwald offset += snprintf(packet, sizeof(packet), "%s:", HFP_INDICATOR); 1891d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr - 1; pos++){ 1901d3bd1e5SMatthias Ringwald offset += snprintf(packet+offset, sizeof(packet)-offset, "%d,", hfp_ag_indicators[pos].status); 1911d3bd1e5SMatthias Ringwald } 1921d3bd1e5SMatthias Ringwald offset += snprintf(packet+offset, sizeof(packet)-offset, "%d\r\n\r\nOK\r\n", hfp_ag_indicators[pos].status); 1931d3bd1e5SMatthias Ringwald 1941d3bd1e5SMatthias Ringwald //context.command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 1951d3bd1e5SMatthias Ringwald context.state = HFP_W4_RETRIEVE_INDICATORS_STATUS; 1961d3bd1e5SMatthias Ringwald 1971d3bd1e5SMatthias Ringwald parse_hf(packet); 1981d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 1991d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 2001d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].status, context.ag_indicators[pos].status); 2011d3bd1e5SMatthias Ringwald } 2021d3bd1e5SMatthias Ringwald } 2031d3bd1e5SMatthias Ringwald 2041d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES_TEST){ 20520d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=?\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES); 2061d3bd1e5SMatthias Ringwald parse_ag(packet); 2071d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, context.command); 2081d3bd1e5SMatthias Ringwald } 2091d3bd1e5SMatthias Ringwald 2101d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES_SET){ 2111d3bd1e5SMatthias Ringwald int action = 1; 2121d3bd1e5SMatthias Ringwald int call_index = 2; 21320d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=%u%u\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, action, call_index); 2141d3bd1e5SMatthias Ringwald parse_ag(packet); 2151d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_CALL_HOLD, context.command); 2161d3bd1e5SMatthias Ringwald CHECK_EQUAL(action, context.ag_call_hold_action); 2171d3bd1e5SMatthias Ringwald CHECK_EQUAL(call_index, context.call_index); 2181d3bd1e5SMatthias Ringwald } 2191d3bd1e5SMatthias Ringwald 2201d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES){ 22120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:(1,1x,2,2x,3)\r\n\r\nOK\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES); 2221d3bd1e5SMatthias Ringwald parse_hf(packet); 2231d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 2241d3bd1e5SMatthias Ringwald CHECK_EQUAL(5, context.remote_call_services_index); 2251d3bd1e5SMatthias Ringwald 2261d3bd1e5SMatthias Ringwald STRCMP_EQUAL("1", (char*)context.remote_call_services[0].name); 2271d3bd1e5SMatthias Ringwald STRCMP_EQUAL("1x", (char*)context.remote_call_services[1].name); 2281d3bd1e5SMatthias Ringwald STRCMP_EQUAL("2", (char*)context.remote_call_services[2].name); 2291d3bd1e5SMatthias Ringwald STRCMP_EQUAL("2x", (char*)context.remote_call_services[3].name); 2301d3bd1e5SMatthias Ringwald STRCMP_EQUAL("3", (char*)context.remote_call_services[4].name); 2311d3bd1e5SMatthias Ringwald } 2321d3bd1e5SMatthias Ringwald 2331d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_GENERIC_STATUS_INDICATOR_TEST){ 23420d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=?\r\n", HFP_GENERIC_STATUS_INDICATOR); 2351d3bd1e5SMatthias Ringwald parse_ag(packet); 2361d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS, context.command); 2371d3bd1e5SMatthias Ringwald } 2381d3bd1e5SMatthias Ringwald 2391d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_GENERIC_STATUS_INDICATOR_SET){ 2402cd3b4c4SMatthias Ringwald int param1 = 1; 2412cd3b4c4SMatthias Ringwald int param2 = 2; 2422cd3b4c4SMatthias Ringwald int param3 = 3; 2432cd3b4c4SMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s= %u,%u,%u\r\n", HFP_GENERIC_STATUS_INDICATOR, param1, param2, param3); 2441d3bd1e5SMatthias Ringwald parse_ag(packet); 2451d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_LIST_GENERIC_STATUS_INDICATORS, context.command); 2461d3bd1e5SMatthias Ringwald } 2471d3bd1e5SMatthias Ringwald 2481d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_GENERIC_STATUS_INDICATOR_READ){ 24920d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s?\r\n", HFP_GENERIC_STATUS_INDICATOR); 2501d3bd1e5SMatthias Ringwald parse_ag(packet); 2511d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE, context.command); 2521d3bd1e5SMatthias Ringwald } 2531d3bd1e5SMatthias Ringwald 2541d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR_STATE){ 25520d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:0,1\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR); 2561d3bd1e5SMatthias Ringwald // context.command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 2571d3bd1e5SMatthias Ringwald context.state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 2581d3bd1e5SMatthias Ringwald 2591d3bd1e5SMatthias Ringwald parse_hf(packet); 2601d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 2611d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.generic_status_indicators[0].state); 2621d3bd1e5SMatthias Ringwald } 2631d3bd1e5SMatthias Ringwald 2641d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_AG_INDICATOR_STATUS_UPDATE){ 2651d3bd1e5SMatthias Ringwald context.ag_indicators_nr = hfp_ag_indicators_nr; 2661d3bd1e5SMatthias Ringwald memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 2671d3bd1e5SMatthias Ringwald 2681d3bd1e5SMatthias Ringwald uint8_t index = 4; 2691d3bd1e5SMatthias Ringwald uint8_t status = 5; 2701d3bd1e5SMatthias Ringwald 27120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status); 2721d3bd1e5SMatthias Ringwald 2731d3bd1e5SMatthias Ringwald parse_hf(packet); 2741d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 2751d3bd1e5SMatthias Ringwald CHECK_EQUAL(status, context.ag_indicators[index - 1].status); 2761d3bd1e5SMatthias Ringwald } 2771d3bd1e5SMatthias Ringwald 2781d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_AG_QUERY_OPERATOR_SELECTION){ 27920d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:1,0,\"sunrise\"\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION); 2801d3bd1e5SMatthias Ringwald 2811d3bd1e5SMatthias Ringwald context.command = HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; 2821d3bd1e5SMatthias Ringwald 2831d3bd1e5SMatthias Ringwald parse_hf(packet); 2841d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 2851d3bd1e5SMatthias Ringwald CHECK_EQUAL(0, context.operator_name_changed); 2861d3bd1e5SMatthias Ringwald STRCMP_EQUAL( "sunrise", context.network_operator.name); 2871d3bd1e5SMatthias Ringwald } 2881d3bd1e5SMatthias Ringwald 2891d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_ERROR){ 29020d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s\r\n", HFP_ERROR); 2911d3bd1e5SMatthias Ringwald 2921d3bd1e5SMatthias Ringwald parse_hf(packet); 2931d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ERROR, context.command); 2941d3bd1e5SMatthias Ringwald } 2951d3bd1e5SMatthias Ringwald 2961d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_EXTENDED_AUDIO_GATEWAY_ERROR){ 29720d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:%d\r\n", HFP_EXTENDED_AUDIO_GATEWAY_ERROR, HFP_CME_ERROR_NO_NETWORK_SERVICE); 2981d3bd1e5SMatthias Ringwald 2991d3bd1e5SMatthias Ringwald parse_hf(packet); 3001d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR, context.command); 3011d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CME_ERROR_NO_NETWORK_SERVICE, context.extended_audio_gateway_error_value); 3021d3bd1e5SMatthias Ringwald } 3031d3bd1e5SMatthias Ringwald 3041d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_HF_AG_INDICATOR_CALLS_STATUS_UPDATE){ 3051d3bd1e5SMatthias Ringwald context.ag_indicators_nr = hfp_ag_indicators_nr; 3061d3bd1e5SMatthias Ringwald memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 3071d3bd1e5SMatthias Ringwald uint8_t status = 1; 3081d3bd1e5SMatthias Ringwald 3091d3bd1e5SMatthias Ringwald // call status 3101d3bd1e5SMatthias Ringwald uint8_t index = call_status_index; 31120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status); 3121d3bd1e5SMatthias Ringwald parse_hf(packet); 3131d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 3141d3bd1e5SMatthias Ringwald CHECK_EQUAL(status, context.ag_indicators[index - 1].status); 3151d3bd1e5SMatthias Ringwald 3161d3bd1e5SMatthias Ringwald // callsetup status 3171d3bd1e5SMatthias Ringwald index = callsetup_status_index; 31820d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status); 3191d3bd1e5SMatthias Ringwald parse_hf(packet); 3201d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 3211d3bd1e5SMatthias Ringwald CHECK_EQUAL(status, context.ag_indicators[index - 1].status); 3221d3bd1e5SMatthias Ringwald 3231d3bd1e5SMatthias Ringwald // callheld status 3241d3bd1e5SMatthias Ringwald index = callheld_status_index; 32520d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status); 3261d3bd1e5SMatthias Ringwald parse_hf(packet); 3271d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_OK, context.command); 3281d3bd1e5SMatthias Ringwald CHECK_EQUAL(status, context.ag_indicators[index - 1].status); 3291d3bd1e5SMatthias Ringwald } 3301d3bd1e5SMatthias Ringwald 3311d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_LIST_CURRENT_CALLS_1){ 3321d3bd1e5SMatthias Ringwald strcpy(packet, "\r\n+CLCC: 1,2,3,4,5,,129\r\n"); 3331d3bd1e5SMatthias Ringwald parse_hf(packet); 3341d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_LIST_CURRENT_CALLS, context.command); 3351d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.clcc_idx); 3361d3bd1e5SMatthias Ringwald CHECK_EQUAL(2, context.clcc_dir); 3371d3bd1e5SMatthias Ringwald CHECK_EQUAL(3, context.clcc_status); 3381d3bd1e5SMatthias Ringwald CHECK_EQUAL(4, context.clcc_mode); 3391d3bd1e5SMatthias Ringwald CHECK_EQUAL(5, context.clcc_mpty); 3401d3bd1e5SMatthias Ringwald STRCMP_EQUAL("", context.bnip_number); 3411d3bd1e5SMatthias Ringwald CHECK_EQUAL(129, context.bnip_type); 3421d3bd1e5SMatthias Ringwald } 3431d3bd1e5SMatthias Ringwald 3441d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_LIST_CURRENT_CALLS_2){ 3451d3bd1e5SMatthias Ringwald strcpy(packet, "\r\n+CLCC: 1,2,3,4,5,"",129\r\n"); 3461d3bd1e5SMatthias Ringwald parse_hf(packet); 3471d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_LIST_CURRENT_CALLS, context.command); 3481d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.clcc_idx); 3491d3bd1e5SMatthias Ringwald CHECK_EQUAL(2, context.clcc_dir); 3501d3bd1e5SMatthias Ringwald CHECK_EQUAL(3, context.clcc_status); 3511d3bd1e5SMatthias Ringwald CHECK_EQUAL(4, context.clcc_mode); 3521d3bd1e5SMatthias Ringwald CHECK_EQUAL(5, context.clcc_mpty); 3531d3bd1e5SMatthias Ringwald STRCMP_EQUAL("", context.bnip_number); 3541d3bd1e5SMatthias Ringwald CHECK_EQUAL(129, context.bnip_type); 3551d3bd1e5SMatthias Ringwald } 3561d3bd1e5SMatthias Ringwald 3571d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_SUPPORTED_FEATURES){ 35820d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=159\r\n", HFP_SUPPORTED_FEATURES); 3591d3bd1e5SMatthias Ringwald //context.keep_separator = 0; 3601d3bd1e5SMatthias Ringwald parse_ag(packet); 3611d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_SUPPORTED_FEATURES, context.command); 3621d3bd1e5SMatthias Ringwald CHECK_EQUAL(159, context.remote_supported_features); 3631d3bd1e5SMatthias Ringwald } 3641d3bd1e5SMatthias Ringwald 3651d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_AVAILABLE_CODECS){ 36620d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=0,1,2\r\n", HFP_AVAILABLE_CODECS); 3671d3bd1e5SMatthias Ringwald parse_ag(packet); 3681d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_AVAILABLE_CODECS, context.command); 3691d3bd1e5SMatthias Ringwald CHECK_EQUAL(3, context.remote_codecs_nr); 3701d3bd1e5SMatthias Ringwald for (pos = 0; pos < 3; pos++){ 3711d3bd1e5SMatthias Ringwald CHECK_EQUAL(pos, context.remote_codecs[pos]); 3721d3bd1e5SMatthias Ringwald } 3731d3bd1e5SMatthias Ringwald } 3741d3bd1e5SMatthias Ringwald 3751d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_GENERIC_STATUS_INDICATOR){ 37620d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=0,1,2,3,4\r\n", HFP_GENERIC_STATUS_INDICATOR); 3771d3bd1e5SMatthias Ringwald parse_ag(packet); 3781d3bd1e5SMatthias Ringwald CHECK_EQUAL(context.command, HFP_CMD_LIST_GENERIC_STATUS_INDICATORS); 3791d3bd1e5SMatthias Ringwald CHECK_EQUAL(5, context.generic_status_indicators_nr); 3801d3bd1e5SMatthias Ringwald 3811d3bd1e5SMatthias Ringwald for (pos = 0; pos < context.generic_status_indicators_nr; pos++){ 3821d3bd1e5SMatthias Ringwald CHECK_EQUAL(pos, context.generic_status_indicators[pos].uuid); 3831d3bd1e5SMatthias Ringwald } 3841d3bd1e5SMatthias Ringwald } 3851d3bd1e5SMatthias Ringwald 3861d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_ENABLE_INDICATOR_STATUS_UPDATE){ 38720d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=3,0,0,1\r\n", HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS); 3881d3bd1e5SMatthias Ringwald parse_ag(packet); 3891d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE, context.command); 3901d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.enable_status_update_for_ag_indicators); 3911d3bd1e5SMatthias Ringwald } 3921d3bd1e5SMatthias Ringwald 3931d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE){ 3941d3bd1e5SMatthias Ringwald hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators); 3951d3bd1e5SMatthias Ringwald context.ag_indicators_nr = hfp_ag_indicators_nr; 3961d3bd1e5SMatthias Ringwald memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 3971d3bd1e5SMatthias Ringwald 3981d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 3991d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].index, hfp_ag_get_ag_indicators(&context)[pos].index ); 4001d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].enabled, hfp_ag_get_ag_indicators(&context)[pos].enabled); 4011d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].index, context.ag_indicators[pos].index); 4021d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].enabled, context.ag_indicators[pos].enabled); 4031d3bd1e5SMatthias Ringwald } 40420d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=0,0,0,0,0,0,0\r\n", 4051d3bd1e5SMatthias Ringwald HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS); 4061d3bd1e5SMatthias Ringwald parse_ag(packet); 4071d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command); 4081d3bd1e5SMatthias Ringwald 4091d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 4101d3bd1e5SMatthias Ringwald if (hfp_ag_get_ag_indicators(&context)[pos].mandatory){ 4111d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, hfp_ag_get_ag_indicators(&context)[pos].enabled); 4121d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.ag_indicators[pos].enabled); 4131d3bd1e5SMatthias Ringwald } else { 4141d3bd1e5SMatthias Ringwald CHECK_EQUAL(0, hfp_ag_get_ag_indicators(&context)[pos].enabled); 4151d3bd1e5SMatthias Ringwald CHECK_EQUAL(0, context.ag_indicators[pos].enabled); 4161d3bd1e5SMatthias Ringwald } 4171d3bd1e5SMatthias Ringwald } 4181d3bd1e5SMatthias Ringwald } 4191d3bd1e5SMatthias Ringwald 4201d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES3){ 4211d3bd1e5SMatthias Ringwald hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators); 4221d3bd1e5SMatthias Ringwald context.ag_indicators_nr = hfp_ag_indicators_nr; 4231d3bd1e5SMatthias Ringwald memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 4241d3bd1e5SMatthias Ringwald 42520d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=,1,,,,,1\r\n", 4261d3bd1e5SMatthias Ringwald HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS); 4271d3bd1e5SMatthias Ringwald parse_ag(packet); 4281d3bd1e5SMatthias Ringwald 4291d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command); 4301d3bd1e5SMatthias Ringwald 4311d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 4321d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].index, hfp_ag_get_ag_indicators(&context)[pos].index ); 4331d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].enabled, hfp_ag_get_ag_indicators(&context)[pos].enabled); 4341d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].index, context.ag_indicators[pos].index ); 4351d3bd1e5SMatthias Ringwald CHECK_EQUAL(hfp_ag_indicators[pos].enabled, context.ag_indicators[pos].enabled); 4361d3bd1e5SMatthias Ringwald } 4371d3bd1e5SMatthias Ringwald } 4381d3bd1e5SMatthias Ringwald 4391d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES2){ 4401d3bd1e5SMatthias Ringwald hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators); 4411d3bd1e5SMatthias Ringwald context.ag_indicators_nr = hfp_ag_indicators_nr; 4421d3bd1e5SMatthias Ringwald memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 4431d3bd1e5SMatthias Ringwald 44420d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=1,,,1,1,1,\r\n", 4451d3bd1e5SMatthias Ringwald HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS); 4461d3bd1e5SMatthias Ringwald parse_ag(packet); 4471d3bd1e5SMatthias Ringwald 4481d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command); 4491d3bd1e5SMatthias Ringwald 4501d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 4511d3bd1e5SMatthias Ringwald CHECK_EQUAL(1,hfp_ag_get_ag_indicators(&context)[pos].enabled); 4521d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.ag_indicators[pos].enabled); 4531d3bd1e5SMatthias Ringwald } 4541d3bd1e5SMatthias Ringwald } 4551d3bd1e5SMatthias Ringwald 4561d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE_OPT_VALUES1){ 4571d3bd1e5SMatthias Ringwald hfp_ag_init_ag_indicators(hfp_ag_indicators_nr, (hfp_ag_indicator_t *)&hfp_ag_indicators); 4581d3bd1e5SMatthias Ringwald context.ag_indicators_nr = hfp_ag_indicators_nr; 4591d3bd1e5SMatthias Ringwald memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 4601d3bd1e5SMatthias Ringwald 46120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=1,,,1,1,1,\r\n", 4621d3bd1e5SMatthias Ringwald HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS); 4631d3bd1e5SMatthias Ringwald parse_ag(packet); 4641d3bd1e5SMatthias Ringwald 4651d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command); 4661d3bd1e5SMatthias Ringwald 4671d3bd1e5SMatthias Ringwald for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ 4681d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, hfp_ag_get_ag_indicators(&context)[pos].enabled); 4691d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.ag_indicators[pos].enabled); 4701d3bd1e5SMatthias Ringwald } 4711d3bd1e5SMatthias Ringwald } 4721d3bd1e5SMatthias Ringwald 4731d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_HF_QUERY_OPERATOR_SELECTION){ 4741d3bd1e5SMatthias Ringwald context.network_operator.format = 0xff; 47520d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=3,0\r\n", HFP_QUERY_OPERATOR_SELECTION); 4761d3bd1e5SMatthias Ringwald 4771d3bd1e5SMatthias Ringwald parse_ag(packet); 4781d3bd1e5SMatthias Ringwald CHECK_EQUAL(0, context.operator_name_changed); 4791d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT, context.command); 4801d3bd1e5SMatthias Ringwald 48120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s?\r\n", HFP_QUERY_OPERATOR_SELECTION); 4821d3bd1e5SMatthias Ringwald 4831d3bd1e5SMatthias Ringwald parse_ag(packet); 4841d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_QUERY_OPERATOR_SELECTION_NAME, context.command); 4851d3bd1e5SMatthias Ringwald CHECK_EQUAL(0, context.operator_name_changed); 4861d3bd1e5SMatthias Ringwald } 4871d3bd1e5SMatthias Ringwald 4881d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_EXTENDED_AUDIO_GATEWAY_ERROR){ 48920d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=1\r\n", HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR); 4901d3bd1e5SMatthias Ringwald 4911d3bd1e5SMatthias Ringwald parse_ag(packet); 4921d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, context.command ); 4931d3bd1e5SMatthias Ringwald CHECK_EQUAL(1, context.enable_extended_audio_gateway_error_report); 4941d3bd1e5SMatthias Ringwald } 4951d3bd1e5SMatthias Ringwald 4961d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_TRIGGER_CODEC_CONNECTION_SETUP){ 49720d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s\r\n", HFP_TRIGGER_CODEC_CONNECTION_SETUP); 4981d3bd1e5SMatthias Ringwald parse_ag(packet); 4991d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP, context.command); 5001d3bd1e5SMatthias Ringwald } 5011d3bd1e5SMatthias Ringwald 5021d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_CONFIRM_COMMON_CODEC){ 5031d3bd1e5SMatthias Ringwald int codec = 2; 50420d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=%d\r\n", HFP_CONFIRM_COMMON_CODEC, codec); 5051d3bd1e5SMatthias Ringwald 5061d3bd1e5SMatthias Ringwald parse_ag(packet); 5071d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_HF_CONFIRMED_CODEC, context.command ); 5081d3bd1e5SMatthias Ringwald CHECK_EQUAL(codec, context.codec_confirmed); 5091d3bd1e5SMatthias Ringwald } 5101d3bd1e5SMatthias Ringwald 5111d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_AG_DIAL){ 5121d3bd1e5SMatthias Ringwald strcpy(packet, "\r\nATD00123456789;\r\n"); 5131d3bd1e5SMatthias Ringwald 5141d3bd1e5SMatthias Ringwald parse_ag(packet); 5151d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_CALL_PHONE_NUMBER, context.command); 5161d3bd1e5SMatthias Ringwald STRCMP_EQUAL("00123456789", (const char *) &context.line_buffer[3]); 5171d3bd1e5SMatthias Ringwald } 5181d3bd1e5SMatthias Ringwald 5191d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_ANSWER_CALL){ 52020d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s\r\n", HFP_ANSWER_CALL); 5211d3bd1e5SMatthias Ringwald parse_ag(packet); 5221d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_CALL_ANSWERED, context.command); 5231d3bd1e5SMatthias Ringwald } 5241d3bd1e5SMatthias Ringwald 5251d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_CMD_RESPONSE_AND_HOLD_QUERY){ 52620d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s?\r\n", HFP_RESPONSE_AND_HOLD); 5271d3bd1e5SMatthias Ringwald parse_ag(packet); 5281d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RESPONSE_AND_HOLD_QUERY, context.command); 5291d3bd1e5SMatthias Ringwald } 5301d3bd1e5SMatthias Ringwald 5311d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_CMD_RESPONSE_AND_HOLD_COMMAND){ 5321d3bd1e5SMatthias Ringwald int param = 1; 53320d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=%u\r\n", HFP_RESPONSE_AND_HOLD, param); 5341d3bd1e5SMatthias Ringwald parse_ag(packet); 5351d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RESPONSE_AND_HOLD_COMMAND, context.command); 5361d3bd1e5SMatthias Ringwald CHECK_EQUAL(param, context.ag_response_and_hold_action); 5371d3bd1e5SMatthias Ringwald } 5381d3bd1e5SMatthias Ringwald 5391d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_CMD_RESPONSE_AND_HOLD_STATUS){ 5401d3bd1e5SMatthias Ringwald int status = 1; 54120d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s:%u\r\n", HFP_RESPONSE_AND_HOLD, status); 5421d3bd1e5SMatthias Ringwald parse_hf(packet); 5431d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_RESPONSE_AND_HOLD_STATUS, context.command); 5441d3bd1e5SMatthias Ringwald } 5451d3bd1e5SMatthias Ringwald 5461d3bd1e5SMatthias Ringwald TEST(HFPParser, HFP_CMD_ENABLE_CLIP){ 5471d3bd1e5SMatthias Ringwald int param = 1; 54820d8d1cfSMatthias Ringwald snprintf(packet, sizeof(packet), "\r\nAT%s=%u\r\n", HFP_ENABLE_CLIP, param); 5491d3bd1e5SMatthias Ringwald parse_ag(packet); 5501d3bd1e5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_ENABLE_CLIP, context.command); 5511d3bd1e5SMatthias Ringwald CHECK_EQUAL(param, context.clip_enabled); 5521d3bd1e5SMatthias Ringwald } 5531d3bd1e5SMatthias Ringwald 554016a59dfSMatthias Ringwald TEST(HFPParser, HFP_CMD_AG_SENT_CLIP_INFORMATION_a){ 555016a59dfSMatthias Ringwald // default/minimal 556016a59dfSMatthias Ringwald parse_hf("\r\n+CLIP: \"+123456789\",145\r\n"); 557016a59dfSMatthias Ringwald CHECK_EQUAL(HFP_CMD_AG_SENT_CLIP_INFORMATION, context.command); 558016a59dfSMatthias Ringwald STRCMP_EQUAL("+123456789", context.bnip_number); 559016a59dfSMatthias Ringwald CHECK_EQUAL(145, context.bnip_type); 560016a59dfSMatthias Ringwald CHECK_EQUAL(false, context.clip_have_alpha); 561016a59dfSMatthias Ringwald } 562016a59dfSMatthias Ringwald 563016a59dfSMatthias Ringwald TEST(HFPParser, HFP_CMD_AG_SENT_CLIP_INFORMATION_b){ 564016a59dfSMatthias Ringwald // iOS 565016a59dfSMatthias Ringwald parse_hf("\r\n+CLIP: \"+123456789\",145,,,\"BlueKitchen GmbH\"\r\n"); 566016a59dfSMatthias Ringwald CHECK_EQUAL(HFP_CMD_AG_SENT_CLIP_INFORMATION, context.command); 567016a59dfSMatthias Ringwald STRCMP_EQUAL("+123456789", context.bnip_number); 568016a59dfSMatthias Ringwald CHECK_EQUAL(145, context.bnip_type); 569016a59dfSMatthias Ringwald CHECK_EQUAL(true, context.clip_have_alpha); 570016a59dfSMatthias Ringwald STRCMP_EQUAL("BlueKitchen GmbH", (const char *)context.line_buffer); 571016a59dfSMatthias Ringwald } 572016a59dfSMatthias Ringwald 573016a59dfSMatthias Ringwald TEST(HFPParser, HFP_CMD_AG_SENT_CLIP_INFORMATION_c){ 574016a59dfSMatthias Ringwald // older iOS with additional ',' 575016a59dfSMatthias Ringwald parse_hf("\r\n+CLIP: \"+123456789\",145,,,,\"BlueKitchen GmbH\"\r\n"); 576016a59dfSMatthias Ringwald CHECK_EQUAL(HFP_CMD_AG_SENT_CLIP_INFORMATION, context.command); 577016a59dfSMatthias Ringwald STRCMP_EQUAL("+123456789", context.bnip_number); 578016a59dfSMatthias Ringwald CHECK_EQUAL(145, context.bnip_type); 579016a59dfSMatthias Ringwald CHECK_EQUAL(true, context.clip_have_alpha); 580016a59dfSMatthias Ringwald STRCMP_EQUAL("BlueKitchen GmbH", (const char *)context.line_buffer); 581016a59dfSMatthias Ringwald } 582016a59dfSMatthias Ringwald 583016a59dfSMatthias Ringwald TEST(HFPParser, HFP_CMD_AG_SENT_CLIP_INFORMATION_d){ 584016a59dfSMatthias Ringwald // BlackBerry, additional quotes 585016a59dfSMatthias Ringwald parse_hf("\r\n+CLIP: \"+123456789\",145,\"\",,\"BlueKitchen GmbH\"\r\n"); 586016a59dfSMatthias Ringwald CHECK_EQUAL(HFP_CMD_AG_SENT_CLIP_INFORMATION, context.command); 587016a59dfSMatthias Ringwald STRCMP_EQUAL("+123456789", context.bnip_number); 588016a59dfSMatthias Ringwald CHECK_EQUAL(145, context.bnip_type); 589016a59dfSMatthias Ringwald CHECK_EQUAL(true, context.clip_have_alpha); 590016a59dfSMatthias Ringwald STRCMP_EQUAL("BlueKitchen GmbH", (const char *)context.line_buffer); 591016a59dfSMatthias Ringwald } 592016a59dfSMatthias Ringwald 593da8e14c5SMatthias Ringwald TEST(HFPParser, HFP_CMD_AG_SENT_CALL_WAITING_INFORMATION){ 594da8e14c5SMatthias Ringwald parse_hf("\r\n+CCWA: \"+123456789\",145,\"\",1,\"BlueKitchen GmbH\"\r\n"); 595da8e14c5SMatthias Ringwald CHECK_EQUAL(HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, context.command); 596da8e14c5SMatthias Ringwald STRCMP_EQUAL("+123456789", context.bnip_number); 597da8e14c5SMatthias Ringwald CHECK_EQUAL(145, context.bnip_type); 598da8e14c5SMatthias Ringwald CHECK_EQUAL(true, context.clip_have_alpha); 599da8e14c5SMatthias Ringwald STRCMP_EQUAL("BlueKitchen GmbH", (const char *)context.line_buffer); 600da8e14c5SMatthias Ringwald } 601da8e14c5SMatthias Ringwald 602d2621a77SMatthias Ringwald TEST(HFPParser, custom_command_hf){ 603d2621a77SMatthias Ringwald hfp_custom_at_command_t custom_hf_command = { 604d2621a77SMatthias Ringwald .command = "+FOO:", 605d2621a77SMatthias Ringwald .command_id = 1 606d2621a77SMatthias Ringwald }; 607d2621a77SMatthias Ringwald const char * custom_hf_command_string = "\r\n+FOO:1,2,3\r\n"; 608d2621a77SMatthias Ringwald hfp_register_custom_hf_command(&custom_hf_command); 609d2621a77SMatthias Ringwald parse_hf(custom_hf_command_string); 610d2621a77SMatthias Ringwald CHECK_EQUAL(1, context.custom_at_command_id); 6118deec660SMatthias Ringwald STRCMP_EQUAL("+FOO:1,2,3", (const char *)context.line_buffer); 612d2621a77SMatthias Ringwald hfp_at_parser_test_dump_line_buffer(); 613d2621a77SMatthias Ringwald } 614d2621a77SMatthias Ringwald 615d2621a77SMatthias Ringwald TEST(HFPParser, custom_command_ag_with_colon){ 616d2621a77SMatthias Ringwald hfp_custom_at_command_t custom_ag_command = { 617d2621a77SMatthias Ringwald .command = "AT+FOO:", 618d2621a77SMatthias Ringwald .command_id = 2 619d2621a77SMatthias Ringwald }; 620d2621a77SMatthias Ringwald const char * custom_hf_command_string = "\r\nAT+FOO:1,2,3\r\n"; 621d2621a77SMatthias Ringwald hfp_register_custom_ag_command(&custom_ag_command); 622d2621a77SMatthias Ringwald parse_ag(custom_hf_command_string); 623d2621a77SMatthias Ringwald CHECK_EQUAL(2, context.custom_at_command_id); 6248deec660SMatthias Ringwald STRCMP_EQUAL("AT+FOO:1,2,3", (const char *)context.line_buffer); 625d2621a77SMatthias Ringwald hfp_at_parser_test_dump_line_buffer(); 626d2621a77SMatthias Ringwald } 627d2621a77SMatthias Ringwald 628d2621a77SMatthias Ringwald TEST(HFPParser, custom_command_ag_with_question){ 629d2621a77SMatthias Ringwald hfp_custom_at_command_t custom_ag_command = { 630d2621a77SMatthias Ringwald .command = "AT+FOO?", 631d2621a77SMatthias Ringwald .command_id = 3 632d2621a77SMatthias Ringwald }; 633d2621a77SMatthias Ringwald const char * custom_hf_command_string = "\r\nAT+FOO?\r\n"; 634d2621a77SMatthias Ringwald hfp_register_custom_ag_command(&custom_ag_command); 635d2621a77SMatthias Ringwald parse_ag(custom_hf_command_string); 636d2621a77SMatthias Ringwald CHECK_EQUAL(3, context.custom_at_command_id); 6378deec660SMatthias Ringwald STRCMP_EQUAL("AT+FOO?", (const char *)context.line_buffer); 6382cd3b4c4SMatthias Ringwald hfp_at_parser_test_dump_line_buffer(); 6392cd3b4c4SMatthias Ringwald } 6402cd3b4c4SMatthias Ringwald 6412cd3b4c4SMatthias Ringwald TEST(HFPParser, custom_command_hf_with_assignment){ 6422cd3b4c4SMatthias Ringwald hfp_custom_at_command_t custom_ag_command = { 6432cd3b4c4SMatthias Ringwald .command = "AT+TEST=", 6442cd3b4c4SMatthias Ringwald .command_id = 3 6452cd3b4c4SMatthias Ringwald }; 6462cd3b4c4SMatthias Ringwald const char * custom_hf_command_string = "\r\nAT+TEST=ABCDE\r\n"; 6472cd3b4c4SMatthias Ringwald hfp_register_custom_ag_command(&custom_ag_command); 6482cd3b4c4SMatthias Ringwald parse_ag(custom_hf_command_string); 6492cd3b4c4SMatthias Ringwald CHECK_EQUAL(3, context.custom_at_command_id); 6508deec660SMatthias Ringwald STRCMP_EQUAL("AT+TEST=ABCDE", (const char *)context.line_buffer); 651d2621a77SMatthias Ringwald hfp_at_parser_test_dump_line_buffer(); 652d2621a77SMatthias Ringwald } 653d2621a77SMatthias Ringwald 654bee8b0c9SMatthias Ringwald TEST(HFPParser, HFP_GABRBAGE_AND_ANSWER_CALL){ 655bee8b0c9SMatthias Ringwald parse_ag("\r\nABCDEF\r\n"); 656bee8b0c9SMatthias Ringwald snprintf(packet, sizeof(packet), "\r\n%s\r\n", HFP_ANSWER_CALL); 657bee8b0c9SMatthias Ringwald parse_ag(packet); 658bee8b0c9SMatthias Ringwald CHECK_EQUAL(HFP_CMD_CALL_ANSWERED, context.command); 659bee8b0c9SMatthias Ringwald } 660bee8b0c9SMatthias Ringwald 661bee8b0c9SMatthias Ringwald TEST(HFPParser, long_command){ 662bee8b0c9SMatthias Ringwald char command[300]; 663bee8b0c9SMatthias Ringwald uint16_t offset = 0; 664bee8b0c9SMatthias Ringwald const char * header = "+CIEV"; 665bee8b0c9SMatthias Ringwald uint16_t header_len = strlen(header); 666bee8b0c9SMatthias Ringwald memcpy(&command[offset], header, header_len); 667bee8b0c9SMatthias Ringwald offset += header_len; 668bee8b0c9SMatthias Ringwald command[offset++] = 0x02; 669bee8b0c9SMatthias Ringwald command[offset++] = 0x32; 670bee8b0c9SMatthias Ringwald uint16_t num_2c = 250; 671bee8b0c9SMatthias Ringwald memset(&command[offset], 0x2c, num_2c); 672bee8b0c9SMatthias Ringwald offset += num_2c; 673bee8b0c9SMatthias Ringwald command[offset++] = 0x31; 674bee8b0c9SMatthias Ringwald command[offset++] = '\r'; 675bee8b0c9SMatthias Ringwald command[offset++] = '\n'; 676bee8b0c9SMatthias Ringwald command[offset++] = 0x00; 677bee8b0c9SMatthias Ringwald parse_hf(command); 678bee8b0c9SMatthias Ringwald } 679c94576d5SMatthias Ringwald 680*e1c49007SMatthias Ringwald TEST(HFPParser, apple_accessory_information){ 681*e1c49007SMatthias Ringwald parse_ag("\n\rAT+XAPL=ABCD-1234-0100,10\r\n"); 682*e1c49007SMatthias Ringwald CHECK_EQUAL(HFP_CMD_APPLE_ACCESSORY_INFORMATION, context.command); 683*e1c49007SMatthias Ringwald CHECK_EQUAL(0xABCD, context.apple_accessory_vendor_id); 684*e1c49007SMatthias Ringwald CHECK_EQUAL(0x1234, context.apple_accessory_product_id); 685*e1c49007SMatthias Ringwald STRCMP_EQUAL("0100",context.apple_accessory_version); 686*e1c49007SMatthias Ringwald CHECK_EQUAL(10, context.apple_accessory_features); 687*e1c49007SMatthias Ringwald } 688*e1c49007SMatthias Ringwald 689*e1c49007SMatthias Ringwald TEST(HFPParser, apple_accessory_state_battery){ 690*e1c49007SMatthias Ringwald context.apple_accessory_battery_level = -1; 691*e1c49007SMatthias Ringwald context.apple_accessory_docked = -1; 692*e1c49007SMatthias Ringwald parse_ag("\n\rAT+IPHONEACCEV=1,1,3\r\n"); 693*e1c49007SMatthias Ringwald CHECK_EQUAL(HFP_CMD_APPLE_ACCESSORY_STATE, context.command); 694*e1c49007SMatthias Ringwald CHECK_EQUAL(3, context.apple_accessory_battery_level); 695*e1c49007SMatthias Ringwald CHECK_EQUAL(-1, context.apple_accessory_docked); 696*e1c49007SMatthias Ringwald } 697*e1c49007SMatthias Ringwald 698*e1c49007SMatthias Ringwald TEST(HFPParser, apple_accessory_state_docked){ 699*e1c49007SMatthias Ringwald context.apple_accessory_battery_level = -1; 700*e1c49007SMatthias Ringwald context.apple_accessory_docked = -1; 701*e1c49007SMatthias Ringwald parse_ag("\n\rAT+IPHONEACCEV=1,2,1\r\n"); 702*e1c49007SMatthias Ringwald CHECK_EQUAL(HFP_CMD_APPLE_ACCESSORY_STATE, context.command); 703*e1c49007SMatthias Ringwald CHECK_EQUAL(-1, context.apple_accessory_battery_level); 704*e1c49007SMatthias Ringwald CHECK_EQUAL(1, context.apple_accessory_docked); 705*e1c49007SMatthias Ringwald } 706*e1c49007SMatthias Ringwald 707*e1c49007SMatthias Ringwald TEST(HFPParser, apple_accessory_state_both){ 708*e1c49007SMatthias Ringwald context.apple_accessory_battery_level = -1; 709*e1c49007SMatthias Ringwald context.apple_accessory_docked = -1; 710*e1c49007SMatthias Ringwald parse_ag("\n\rAT+IPHONEACCEV=1,1,3,2,1\r\n"); 711*e1c49007SMatthias Ringwald CHECK_EQUAL(HFP_CMD_APPLE_ACCESSORY_STATE, context.command); 712*e1c49007SMatthias Ringwald CHECK_EQUAL(3, context.apple_accessory_battery_level); 713*e1c49007SMatthias Ringwald CHECK_EQUAL(1, context.apple_accessory_docked); 714*e1c49007SMatthias Ringwald } 715*e1c49007SMatthias Ringwald 716c94576d5SMatthias Ringwald TEST(HFPParser,dummy){ 717c94576d5SMatthias Ringwald unsigned char data[] = { 718c94576d5SMatthias Ringwald 0x99, 0x08, 0x0a 719c94576d5SMatthias Ringwald }; 720c94576d5SMatthias Ringwald unsigned int data_len = sizeof(data); 721c94576d5SMatthias Ringwald int is_handsfree = data[0] & 1; 722c94576d5SMatthias Ringwald hfp_connection_t hfp_connection; 723c94576d5SMatthias Ringwald memset(&hfp_connection, 0, sizeof(hfp_connection_t)); 724c94576d5SMatthias Ringwald uint32_t i; 725c94576d5SMatthias Ringwald for (i = 1; i < data_len; i++){ 726c94576d5SMatthias Ringwald hfp_parse(&hfp_connection, data[i], is_handsfree); 727c94576d5SMatthias Ringwald } 728c94576d5SMatthias Ringwald 729c94576d5SMatthias Ringwald } 730c94576d5SMatthias Ringwald 7311d3bd1e5SMatthias Ringwald int main (int argc, const char * argv[]){ 7321d3bd1e5SMatthias Ringwald return CommandLineTestRunner::RunAllTests(argc, argv); 7331d3bd1e5SMatthias Ringwald } 734