From 66e0c1180ba0291fef54b726649d23fe6210a15d Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 18 Sep 2015 15:15:48 +0200 Subject: [PATCH 1/3] hfp: fix test --- test/hfp/hfp_ag_parser_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hfp/hfp_ag_parser_test.c b/test/hfp/hfp_ag_parser_test.c index 959e74a21..609f10503 100644 --- a/test/hfp/hfp_ag_parser_test.c +++ b/test/hfp/hfp_ag_parser_test.c @@ -241,8 +241,8 @@ TEST(HFPParser, HFP_AG_CONFIRM_COMMON_CODEC){ hfp_parse(&context, packet[pos]); } - CHECK_EQUAL(context.command, HFP_CMD_CONFIRM_COMMON_CODEC); - CHECK_EQUAL(context.remote_codec_received, codec); + CHECK_EQUAL(context.command, HFP_CMD_HF_CONFIRMED_CODEC); + CHECK_EQUAL(context.codec_confirmed, codec); } int main (int argc, const char * argv[]){ From dc5611fddefa948cedb447d9bfd1d551e6e657f0 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Wed, 23 Sep 2015 16:58:34 +0200 Subject: [PATCH 2/3] hfp: add ag client state machine test for service level connection --- src/hfp.c | 1 - src/hfp_ag.c | 273 +++++++++++++++++----------------- src/hfp_ag.h | 2 +- src/hfp_hf.c | 1 + test/hfp/.gitignore | 3 +- test/hfp/Makefile | 17 ++- test/hfp/hfp_ag_client_test.c | 190 +++++++++++++++++++++++ test/hfp/hfp_hf_client_test.c | 175 +++++----------------- test/hfp/mock.c | 103 ++++++++++++- test/hfp/mock.h | 53 +++++++ test/hfp/test_sequences.c | 150 +++++++++++++++++++ test/hfp/test_sequences.h | 69 +++++++++ 12 files changed, 747 insertions(+), 290 deletions(-) create mode 100644 test/hfp/hfp_ag_client_test.c create mode 100644 test/hfp/mock.h create mode 100644 test/hfp/test_sequences.c create mode 100644 test/hfp/test_sequences.h diff --git a/src/hfp.c b/src/hfp.c index 203cc16d6..83f2f4c4f 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -813,7 +813,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ switch (context->parser_state){ case HFP_PARSER_CMD_HEADER: // header - // printf(" parse header 1 \n"); if (byte == '='){ context->keep_separator = 1; hfp_parser_store_byte(context, byte); diff --git a/src/hfp_ag.c b/src/hfp_ag.c index f3cbec96d..5cdf1b71d 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -370,136 +370,6 @@ static uint8_t hfp_ag_suggest_codec(hfp_connection_t *context){ } static void hfp_ag_run_for_context_service_level_connection(hfp_connection_t * context){ - -} - -static void hfp_ag_run_for_context_service_level_connection_queries(hfp_connection_t * context){ - if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return; - if (context->enable_status_update_for_ag_indicators){ - int i; - for (i = 0; i < context->ag_indicators_nr; i++){ - if (context->ag_indicators[i].enabled == 0) continue; - if (context->ag_indicators[i].status_changed == 0) continue; - hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]); - context->ag_indicators[i].status_changed = 0; - return; - } - } - - if (context->enable_extended_audio_gateway_error_report){ - if (context->extended_audio_gateway_error){ - hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error); - context->extended_audio_gateway_error = 0; - return; - } - } -} - -static void hfp_ag_run_for_context_codecs_connection(hfp_connection_t * context){ - switch (context->state){ - case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: - if (context->notify_ag_on_new_codecs){ - context->notify_ag_on_new_codecs = 0; - hfp_ag_ok(context->rfcomm_cid); - if (!context->negotiated_codec) return; - if (hfp_ag_suggest_codec(context) == context->negotiated_codec) return; - context->suggested_codec = hfp_ag_suggest_codec(context); - context->trigger_codec_connection_setup = 1; - context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; - return; - } - case HFP_SLE_W2_EXCHANGE_COMMON_CODEC: - if (context->notify_ag_on_new_codecs){ - context->notify_ag_on_new_codecs = 0; - hfp_ag_ok(context->rfcomm_cid); - if (!context->negotiated_codec) return; - if (hfp_ag_suggest_codec(context) == context->negotiated_codec) return; - context->suggested_codec = hfp_ag_suggest_codec(context); - context->trigger_codec_connection_setup = 1; - context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; - return; - } - - if (context->trigger_codec_connection_setup){ - context->trigger_codec_connection_setup = 0; - hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec); - context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; - } - break; - case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: - if (context->codec_confirmed){ - // TODO check if they are equal? - if (context->codec_confirmed == context->suggested_codec){ - context->negotiated_codec = context->codec_confirmed; - hfp_ag_ok(context->rfcomm_cid); - context->state = HFP_CODECS_CONNECTION_ESTABLISHED; - return; - } else { - hfp_ag_error(context->rfcomm_cid); - context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; - } - context->codec_confirmed = 0; - context->suggested_codec = 0; - break; - } - default: - break; - } - - switch(context->command){ - // START codec setup - case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: - switch (context->state){ - case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: - // hfp_ag_ok(context->rfcomm_cid); - context->trigger_codec_connection_setup = 1; - context->suggested_codec = hfp_ag_suggest_codec(context); - hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->negotiated_codec); - context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; - break; - default: - hfp_ag_error(context->rfcomm_cid); - break; - } - break; - case HFP_CMD_AVAILABLE_CODECS: - switch(context->state){ - case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: - case HFP_SLE_W2_EXCHANGE_COMMON_CODEC: - case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: - context->notify_ag_on_new_codecs = 1; - break; - default: - break; - } - break; - default: - break; - } -} - - -void hfp_run_for_context(hfp_connection_t *context){ - // printf(" hfp_run_for_context \n"); - if (!context) return; - if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; - // printf("AG hfp_run_for_context 1 state %d, command %d\n", context->state, context->command); - if (context->send_ok){ - hfp_ag_ok(context->rfcomm_cid); - context->send_ok = 0; - return; - } - - if (context->send_error){ - hfp_ag_error(context->rfcomm_cid); - context->send_error = 0; - return; - } - - hfp_ag_run_for_context_service_level_connection(context); - hfp_ag_run_for_context_service_level_connection_queries(context); - hfp_ag_run_for_context_codecs_connection(context); - switch(context->command){ case HFP_CMD_SUPPORTED_FEATURES: switch(context->state){ @@ -634,8 +504,139 @@ void hfp_run_for_context(hfp_connection_t *context){ } break; default: + printf("default: hfp_ag_run_for_context_service_level_connection \n"); break; } +} + +static void hfp_ag_run_for_context_service_level_connection_queries(hfp_connection_t * context){ + if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return; + if (context->enable_status_update_for_ag_indicators){ + int i; + for (i = 0; i < context->ag_indicators_nr; i++){ + if (context->ag_indicators[i].enabled == 0) continue; + if (context->ag_indicators[i].status_changed == 0) continue; + hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]); + context->ag_indicators[i].status_changed = 0; + return; + } + } + + if (context->enable_extended_audio_gateway_error_report){ + if (context->extended_audio_gateway_error){ + hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error); + context->extended_audio_gateway_error = 0; + return; + } + } +} + +static void hfp_ag_run_for_context_codecs_connection(hfp_connection_t * context){ + if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return; + switch (context->state){ + case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: + if (context->notify_ag_on_new_codecs){ + context->notify_ag_on_new_codecs = 0; + hfp_ag_ok(context->rfcomm_cid); + if (!context->negotiated_codec) return; + if (hfp_ag_suggest_codec(context) == context->negotiated_codec) return; + context->suggested_codec = hfp_ag_suggest_codec(context); + context->trigger_codec_connection_setup = 1; + context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; + return; + } + case HFP_SLE_W2_EXCHANGE_COMMON_CODEC: + if (context->notify_ag_on_new_codecs){ + context->notify_ag_on_new_codecs = 0; + hfp_ag_ok(context->rfcomm_cid); + if (!context->negotiated_codec) return; + if (hfp_ag_suggest_codec(context) == context->negotiated_codec) return; + context->suggested_codec = hfp_ag_suggest_codec(context); + context->trigger_codec_connection_setup = 1; + context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; + return; + } + + if (context->trigger_codec_connection_setup){ + context->trigger_codec_connection_setup = 0; + hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec); + context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; + } + break; + case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: + if (context->codec_confirmed){ + // TODO check if they are equal? + if (context->codec_confirmed == context->suggested_codec){ + context->negotiated_codec = context->codec_confirmed; + hfp_ag_ok(context->rfcomm_cid); + context->state = HFP_CODECS_CONNECTION_ESTABLISHED; + return; + } else { + hfp_ag_error(context->rfcomm_cid); + context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; + } + context->codec_confirmed = 0; + context->suggested_codec = 0; + break; + } + default: + break; + } + + switch(context->command){ + // START codec setup + case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: + switch (context->state){ + case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: + // hfp_ag_ok(context->rfcomm_cid); + context->trigger_codec_connection_setup = 1; + context->suggested_codec = hfp_ag_suggest_codec(context); + hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->negotiated_codec); + context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; + break; + default: + hfp_ag_error(context->rfcomm_cid); + break; + } + break; + case HFP_CMD_AVAILABLE_CODECS: + switch(context->state){ + case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: + case HFP_SLE_W2_EXCHANGE_COMMON_CODEC: + case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: + context->notify_ag_on_new_codecs = 1; + break; + default: + break; + } + break; + default: + break; + } +} + + +void hfp_run_for_context(hfp_connection_t *context){ + if (!context) return; + if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; + // printf("AG hfp_run_for_context 1 state %d, command %d\n", context->state, context->command); + if (context->send_ok){ + hfp_ag_ok(context->rfcomm_cid); + context->send_ok = 0; + return; + } + + if (context->send_error){ + hfp_ag_error(context->rfcomm_cid); + context->send_error = 0; + return; + } + + hfp_ag_run_for_context_service_level_connection(context); + hfp_ag_run_for_context_service_level_connection_queries(context); + hfp_ag_run_for_context_codecs_connection(context); + + // done context->command = HFP_CMD_NONE; } @@ -643,12 +644,12 @@ void hfp_run_for_context(hfp_connection_t *context){ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel); if (!context) return; + if (context->state == HFP_EXCHANGE_SUPPORTED_FEATURES){ context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES; } packet[size] = 0; - printf("HF response: %s\n", packet); int pos; for (pos = 0; pos < size ; pos++){ hfp_parse(context, packet[pos]); @@ -671,15 +672,16 @@ static void hfp_run(){ static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet_type){ case RFCOMM_DATA_PACKET: - printf("\nRFCOMM_DATA_PACKET: %s\n", packet); + printf("\nAG received: %s\n", packet); hfp_handle_rfcomm_event(packet_type, channel, packet, size); break; case HCI_EVENT_PACKET: hfp_handle_hci_event(hfp_callback, packet_type, packet, size); - break; + return; default: break; - } + } + hfp_run(); } @@ -687,7 +689,7 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_t * codecs, int codecs_nr, hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr, hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr, - char *call_hold_services[], int call_hold_services_nr){ + const char *call_hold_services[], int call_hold_services_nr){ if (codecs_nr > HFP_MAX_NUM_CODECS){ log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS); return; @@ -720,6 +722,7 @@ void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr){ } void hfp_ag_release_service_level_connection(bd_addr_t bd_addr){ + printf(" hfp_ag_release_service_level_connection \n"); hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); hfp_release_service_level_connection(connection); hfp_run_for_context(connection); diff --git a/src/hfp_ag.h b/src/hfp_ag.h index 42ae6e9b7..d45faad69 100644 --- a/src/hfp_ag.h +++ b/src/hfp_ag.h @@ -68,7 +68,7 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_t * codecs, int codecs_nr, hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr, hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr, - char *call_hold_services[], int call_hold_services_nr); + const char *call_hold_services[], int call_hold_services_nr); /** * @brief Register callback for the HFP Audio Gateway (AG) client. diff --git a/src/hfp_hf.c b/src/hfp_hf.c index e75a24d5d..c6aec3bfe 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -649,6 +649,7 @@ static void hfp_run(){ static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ switch (packet_type){ case RFCOMM_DATA_PACKET: + printf("\nHF received: %s\n", packet); hfp_handle_rfcomm_event(packet_type, channel, packet, size); break; case HCI_EVENT_PACKET: diff --git a/test/hfp/.gitignore b/test/hfp/.gitignore index 6f6647269..05b844ead 100644 --- a/test/hfp/.gitignore +++ b/test/hfp/.gitignore @@ -1,3 +1,4 @@ hfp_hf_client_test hfp_ag_parser_test -hfp_hf_parser_test \ No newline at end of file +hfp_hf_parser_test +hfp_ag_parser_test \ No newline at end of file diff --git a/test/hfp/Makefile b/test/hfp/Makefile index f297254b8..3671d509f 100644 --- a/test/hfp/Makefile +++ b/test/hfp/Makefile @@ -25,7 +25,6 @@ COMMON = \ sdp_query_util.c \ sdp_query_rfcomm.c \ sdp.c \ - mock.c \ MOCK = \ @@ -38,7 +37,8 @@ MOCK = \ sdp_util.c \ utils.c \ mock.c \ - + test_sequences.c \ + COMMON_OBJ = $(COMMON:.c=.o) MOCK_OBJ = $(MOCK:.c=.o) @@ -53,14 +53,12 @@ VPATH += ${BTSTACK_ROOT}/platforms/posix/src CFLAGS = -g -Wall -I. -I../ -I${BTSTACK_ROOT}/src -I${BTSTACK_ROOT}/include -I${BTSTACK_ROOT}/ble LDFLAGS += -lCppUTest -lCppUTestExt - -EXAMPLES = hfp_hf_client_test -# hfp_ag_parser_test hfp_hf_parser_test +EXAMPLES = hfp_ag_parser_test hfp_hf_parser_test hfp_hf_client_test hfp_ag_client_test all: ${BTSTACK_ROOT}/include/btstack/version.h ${EXAMPLES} clean: - rm -rf *.o $(EXAMPLES) *.dSYM + rm -rf *.o $(PARSER_EXAMPLES) $(CLIENT_EXAMPLES) *.dSYM hfp_ag_parser_test: ${COMMON_OBJ} hfp_ag.o hfp.o hfp_ag_parser_test.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ @@ -71,7 +69,12 @@ hfp_hf_parser_test: ${COMMON_OBJ} hfp_hf.o hfp.o hfp_hf_parser_test.c hfp_hf_client_test: ${MOCK_OBJ} hfp_hf.o hfp.o hfp_hf_client_test.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ +hfp_ag_client_test: ${MOCK_OBJ} hfp_ag.o hfp.o hfp_ag_client_test.c + ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ + test: all - ./hfp_ag_parser_test ./hfp_hf_parser_test + ./hfp_ag_parser_test ./hfp_hf_client_test + ./hfp_ag_client_test + diff --git a/test/hfp/hfp_ag_client_test.c b/test/hfp/hfp_ag_client_test.c new file mode 100644 index 000000000..9dc6c8aa3 --- /dev/null +++ b/test/hfp/hfp_ag_client_test.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +// ***************************************************************************** +// +// HFG AG state machine tests +// +// ***************************************************************************** + +#include "btstack-config.h" + +#include +#include +#include +#include + +#include "CppUTest/TestHarness.h" +#include "CppUTest/CommandLineTestRunner.h" + +#include +#include +#include + +#include "hci.h" +#include "l2cap.h" +#include "rfcomm.h" +#include "sdp.h" +#include "sdp_parser.h" +#include "debug.h" +#include "hfp_ag.h" + +#include "mock.h" +#include "test_sequences.h" + +const uint8_t rfcomm_channel_nr = 1; + +static bd_addr_t device_addr = {0xD8,0xBb,0x2C,0xDf,0xF1,0x08}; + +static uint8_t codecs[1] = {HFP_CODEC_CVSD}; + +static int ag_indicators_nr = 7; +static hfp_ag_indicator_t ag_indicators[] = { + // index, name, min range, max range, status, mandatory, enabled, status changed + {1, "service", 0, 1, 1, 0, 0, 0}, + {2, "call", 0, 1, 0, 1, 1, 0}, + {3, "callsetup", 0, 3, 0, 1, 1, 0}, + {4, "battchg", 0, 5, 3, 0, 0, 0}, + {5, "signal", 0, 5, 5, 0, 0, 0}, + {6, "roam", 0, 1, 0, 0, 0, 0}, + {7, "callheld", 0, 2, 0, 1, 1, 0} +}; + +static int call_hold_services_nr = 5; +static const char* call_hold_services[] = {"1", "1x", "2", "2x", "3"}; + +static int hf_indicators_nr = 2; +static hfp_generic_status_indicator_t hf_indicators[] = { + {1, 1}, + {2, 1}, +}; + + +static uint8_t service_level_connection_established = 0; +static uint8_t codecs_connection_established = 0; +static uint8_t audio_connection_established = 0; +static uint8_t service_level_connection_released = 0; + +void hfp_ag_run_test_sequence(char ** test_steps, int nr_test_steps){ + int i = 0; + for (i=0; i < nr_test_steps; i++){ + char * cmd = test_steps[i]; + if (memcmp(cmd, "OK", 2) == 0) continue; + if (memcmp(cmd, "AT", 2) == 0){ + printf("---> next step %s\n", cmd); + inject_rfcomm_command((uint8_t*)cmd, strlen(cmd)); + } else { + int expected_cmd = expected_rfcomm_command(cmd); + if (!expected_cmd){ + printf("\nError: Expected:'%s', but got:'%s'", cmd, (char *)get_rfcomm_payload()); + return; + } + } + } +} + +void packet_handler(uint8_t * event, uint16_t event_size){ + if (event[0] != HCI_EVENT_HFP_META) return; + if (event[3] && event[2] != HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR){ + printf("ERROR, status: %u\n", event[3]); + return; + } + + switch (event[2]) { + case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED: + service_level_connection_established = 1; + codecs_connection_established = 0; + audio_connection_established = 0; + break; + case HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE: + codecs_connection_established = 1; + audio_connection_established = 0; + break; + case HFP_SUBEVENT_AUDIO_CONNECTION_COMPLETE: + audio_connection_established = 1; + break; + case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED: + service_level_connection_released = 1; + break; + default: + printf("event not handled %u\n", event[2]); + break; + } +} + + +TEST_GROUP(AudiogatewayClient){ + void setup(void){ + service_level_connection_established = 0; + codecs_connection_established = 0; + audio_connection_established = 0; + service_level_connection_released = 0; + } + + void teardown(void){ + if (service_level_connection_established){ + hfp_ag_release_service_level_connection(device_addr); + CHECK_EQUAL(service_level_connection_released, 1); + } + } + + void setup_hfp_service_level_connection(char ** test_steps, int nr_test_steps){ + service_level_connection_established = 0; + hfp_ag_establish_service_level_connection(device_addr); + hfp_ag_run_test_sequence((char **) test_steps, nr_test_steps); + CHECK_EQUAL(service_level_connection_established, 1); + } +}; + + +TEST(AudiogatewayClient, HFServiceLevelConnectionEstablished){ + for (int i = 0; i < slc_tests_size(); i++){ + setup_hfp_service_level_connection(hfp_slc_tests()[i].test, hfp_slc_tests()[i].len); + } +} + + +int main (int argc, const char * argv[]){ + hfp_ag_init(rfcomm_channel_nr, 1007, codecs, sizeof(codecs), + ag_indicators, ag_indicators_nr, + hf_indicators, hf_indicators_nr, + call_hold_services, call_hold_services_nr); + + hfp_ag_register_packet_handler(packet_handler); + + return CommandLineTestRunner::RunAllTests(argc, argv); +} diff --git a/test/hfp/hfp_hf_client_test.c b/test/hfp/hfp_hf_client_test.c index 904190eec..36ca0966f 100644 --- a/test/hfp/hfp_hf_client_test.c +++ b/test/hfp/hfp_hf_client_test.c @@ -37,7 +37,7 @@ // ***************************************************************************** // -// Minimal test for HSP Headset (!! UNDER DEVELOPMENT !!) +// HFG HF state machine tests // // ***************************************************************************** @@ -63,13 +63,8 @@ #include "debug.h" #include "hfp_hf.h" -#define TEST_SEQUENCE(name) { (char**)name, sizeof(name) / sizeof(char *)} - -typedef struct hfp_test_item{ - char ** test; - int len; -} hfp_test_item_t; - +#include "mock.h" +#include "test_sequences.h" const uint8_t rfcomm_channel_nr = 1; @@ -83,10 +78,31 @@ static uint8_t codecs_connection_established = 0; static uint8_t audio_connection_established = 0; static uint8_t service_level_connection_released = 0; -// prototypes -uint8_t * get_rfcomm_payload(); -uint16_t get_rfcomm_payload_len(); -void inject_rfcomm_command(uint8_t * payload, int len); +void hfp_hf_run_test_sequence(char ** test_steps, int nr_test_steps){ + int i = 0; + for (i=0; i < nr_test_steps; i++){ + char * cmd = test_steps[i]; + // printf("---> next step %s\n", cmd); + if (memcmp(cmd, "AT", 2) == 0){ + int parsed_codecs[2]; + uint8_t new_codecs[2]; + if (memcmp(cmd, "AT+BAC=", 7) == 0){ + sscanf(&cmd[7],"%d,%d", &parsed_codecs[0], &parsed_codecs[1]); + new_codecs[0] = parsed_codecs[0]; + new_codecs[1] = parsed_codecs[1]; + hfp_hf_set_codecs((uint8_t*)new_codecs, 2); + } else { + int expected_cmd = expected_rfcomm_command(cmd); + if (expected_cmd){ + printf("\nError: Expected:'%s', but got:'%s'", cmd, (char *)get_rfcomm_payload()); + return; + } + } + } else { + inject_rfcomm_command((uint8_t*)cmd, strlen(cmd)); + } + } +} void packet_handler(uint8_t * event, uint16_t event_size){ if (event[0] != HCI_EVENT_HFP_META) return; @@ -130,109 +146,15 @@ void packet_handler(uint8_t * event, uint16_t event_size){ } } -static int expected_rfcomm_command(const char * cmd){ - if (memcmp(cmd, "AT", 2) == 0){ - return memcmp((char *)cmd, (char *)get_rfcomm_payload(), get_rfcomm_payload_len()-2); - } - if (cmd[0] == '+'){ - return memcmp((char *)cmd, (char *)get_rfcomm_payload()+2, get_rfcomm_payload_len()-2); - } - if (memcmp(cmd, "OK", 2) == 0) return 0; - if (memcmp(cmd, "ERROR", 5) == 0) return 0; - return 1; -} - -static void verify_expected_rfcomm_command(const char * cmd){ - if (expected_rfcomm_command(cmd)){ - printf("\nError: Expected:'%s', but got:'%s'", cmd, (char *)get_rfcomm_payload()); - } - CHECK_EQUAL(expected_rfcomm_command(cmd),0); -} - -/* Service Level Connection (slc) test sequences */ - -const char * hf_slc_test1[] = { - "AT+BRSF=438", - "+BRSF:1007", - HFP_OK, - "AT+BAC=1,2", - HFP_OK, - "AT+CIND=?", - "+CIND:\"service\",(0,1),\"call\",(0,1),\"callsetup\",(0,3),\"battchg\",(0,5),\"signal\",(0,5),\"roam\",(0,1),\"callheld\",(0,2)", - HFP_OK, - "AT+CIND?", - "+CIND:1,0,0,3,5,0,0", - HFP_OK, - "AT+CMER=3,0,0,1", - HFP_OK, - "AT+CHLD=?", - "+CHLD:(1,1x,2,2x,3)", - HFP_OK -}; - -hfp_test_item_t hfp_slc_tests[] = { - TEST_SEQUENCE(hf_slc_test1) -}; - -/* Service Level Connection (slc) common commands */ -const char * hf_slc_cmds_test1[] = { - "AT+BAC=1,3", - HFP_OK -}; - -/* Codecs Connection (cc) test sequences */ - -const char * hf_cc_test1[] = { - "AT+BCC", - HFP_OK, - "+BCS:1", - "AT+BCS=1", - HFP_OK -}; - -const char * hf_cc_test2[] = { - "AT+BCC", - HFP_OK, - "+BCS:1", - "AT+BAC=2,3", - HFP_OK, - "+BCS:2", - "AT+BCS=2", - HFP_OK -}; - -hfp_test_item_t hfp_cc_tests[] = { - TEST_SEQUENCE(hf_cc_test1), - TEST_SEQUENCE(hf_cc_test2) -}; TEST_GROUP(HandsfreeClient){ - int test_item_size; - int cc_tests_size; - int slc_tests_size; - char ** default_slc_setup; - int default_slc_setup_size; - - char ** default_cc_setup; - int default_cc_setup_size; - void setup(void){ service_level_connection_established = 0; codecs_connection_established = 0; audio_connection_established = 0; service_level_connection_released = 0; - - test_item_size = sizeof(hfp_test_item_t); - slc_tests_size = sizeof(hfp_slc_tests)/test_item_size; - cc_tests_size = sizeof(hfp_cc_tests) /test_item_size; - - default_slc_setup = (char **)hf_slc_test1; - default_slc_setup_size = sizeof(hf_slc_test1)/sizeof(char*); - - default_cc_setup = (char **)hf_cc_test1; - default_cc_setup_size = sizeof(hf_cc_test1)/sizeof(char*); } void teardown(void){ @@ -242,32 +164,10 @@ TEST_GROUP(HandsfreeClient){ } } - void test(char ** test_steps, int nr_test_steps){ - int i = 0; - for (i=0; i < nr_test_steps; i++){ - char * cmd = test_steps[i]; - // printf("---> next step %s\n", cmd); - if (memcmp(cmd, "AT", 2) == 0){ - int parsed_codecs[2]; - uint8_t new_codecs[2]; - if (memcmp(cmd, "AT+BAC=", 7) == 0){ - sscanf(&cmd[7],"%d,%d", &parsed_codecs[0], &parsed_codecs[1]); - new_codecs[0] = parsed_codecs[0]; - new_codecs[1] = parsed_codecs[1]; - hfp_hf_set_codecs((uint8_t*)new_codecs, 2); - } else { - verify_expected_rfcomm_command(cmd); - } - } else { - inject_rfcomm_command((uint8_t*)cmd, strlen(cmd)); - } - } - } - void setup_hfp_service_level_connection(char ** test_steps, int nr_test_steps){ service_level_connection_established = 0; hfp_hf_establish_service_level_connection(device_addr); - test((char **) test_steps, nr_test_steps); + hfp_hf_run_test_sequence((char **) test_steps, nr_test_steps); CHECK_EQUAL(service_level_connection_established, 1); hfp_hf_set_codecs(codecs, 1); inject_rfcomm_command((uint8_t*)HFP_OK, strlen(HFP_OK)); @@ -276,7 +176,7 @@ TEST_GROUP(HandsfreeClient){ void setup_hfp_codecs_connection_state_machine(char ** test_steps, int nr_test_steps){ codecs_connection_established = 0; hfp_hf_negotiate_codecs(device_addr); - test((char **) test_steps, nr_test_steps); + hfp_hf_run_test_sequence((char **) test_steps, nr_test_steps); CHECK_EQUAL(codecs_connection_established, 1); } @@ -284,22 +184,21 @@ TEST_GROUP(HandsfreeClient){ TEST(HandsfreeClient, HFCodecsConnectionEstablished){ - setup_hfp_service_level_connection(default_slc_setup, default_slc_setup_size); - for (int i = 0; i < cc_tests_size; i++){ - setup_hfp_codecs_connection_state_machine(hfp_cc_tests[i].test, hfp_cc_tests[i].len); + setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size()); + for (int i = 0; i < cc_tests_size(); i++){ + setup_hfp_codecs_connection_state_machine(hfp_cc_tests()[i].test, hfp_cc_tests()[i].len); } } TEST(HandsfreeClient, HFCodecChange){ - setup_hfp_service_level_connection(default_slc_setup, default_slc_setup_size); - test((char**)hf_slc_cmds_test1, sizeof(hf_slc_cmds_test1)/sizeof(char*)); - verify_expected_rfcomm_command(HFP_OK); + setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size()); + hfp_hf_run_test_sequence(default_cc_setup(), default_cc_setup_size()); CHECK_EQUAL(service_level_connection_established, 1); } TEST(HandsfreeClient, HFServiceLevelConnectionEstablished){ - for (int i = 0; i < slc_tests_size; i++){ - setup_hfp_service_level_connection(hfp_slc_tests[i].test, hfp_slc_tests[i].len); + for (int i = 0; i < slc_tests_size(); i++){ + setup_hfp_service_level_connection(hfp_slc_tests()[i].test, hfp_slc_tests()[i].len); } } diff --git a/test/hfp/mock.c b/test/hfp/mock.c index 2036190f5..af0525433 100644 --- a/test/hfp/mock.c +++ b/test/hfp/mock.c @@ -1,3 +1,46 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +// ***************************************************************************** +// +// HFP BTstack Mocks +// +// ***************************************************************************** + #include #include #include @@ -8,6 +51,9 @@ #include "hci_dump.h" #include "sdp_query_rfcomm.h" #include "rfcomm.h" +#include "hfp_hf.h" + +#include "mock.h" static void *registered_sdp_app_context; static uint8_t sdp_rfcomm_channel_nr = 1; @@ -39,17 +85,16 @@ static void prepare_rfcomm_buffer(uint8_t * data, int len){ pos += len; if (memcmp((char*)data, "AT", 2) != 0){ rfcomm_payload[pos++] = '\r'; - rfcomm_payload[pos] = '\n'; - } + rfcomm_payload[pos++] = '\n'; + rfcomm_payload[pos++] = 'O'; + rfcomm_payload[pos++] = 'K'; + } + rfcomm_payload[pos++] = '\r'; + rfcomm_payload[pos] = '\n'; rfcomm_payload_len = pos; } -void inject_rfcomm_command(uint8_t * data, int len){ - prepare_rfcomm_buffer(data, len); - (*registered_rfcomm_packet_handler)(active_connection, RFCOMM_DATA_PACKET, rfcomm_cid, (uint8_t *) &rfcomm_payload[0], rfcomm_payload_len); -} - int rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){ if (memcmp((char*)data, "AT", 2) == 0){ printf("HF send: %s", data); @@ -143,3 +188,47 @@ void rfcomm_accept_connection_internal(uint16_t rfcomm_cid){ printf("rfcomm_accept_connection_internal \n"); } +// HFP Mock API + +int expected_rfcomm_command(const char * cmd){ + char * ag_cmd = (char *)get_rfcomm_payload(); + int offset = 0; + int cmd_size = strlen(cmd); + + if (memcmp(ag_cmd, "OK", 2) == 0){ + int ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0; + while (!ok_found && get_rfcomm_payload_len() - 2 >= offset){ + offset++; + ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0; + } + return ok_found; + } + + int cmd_found = memcmp(ag_cmd, cmd, cmd_size) == 0; + while (!cmd_found && get_rfcomm_payload_len() - cmd_size >= offset){ + offset++; + cmd_found = strncmp(ag_cmd+offset, cmd, cmd_size) == 0; + } + + if (!cmd_found) return 0; + offset += strlen(cmd); + + int ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0; + while (!ok_found && get_rfcomm_payload_len() - 2 >= offset){ + offset++; + ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0; + } + + return cmd_found && ok_found; +} + + +void inject_rfcomm_command(uint8_t * data, int len){ + prepare_rfcomm_buffer(data, len); + (*registered_rfcomm_packet_handler)(active_connection, RFCOMM_DATA_PACKET, rfcomm_cid, (uint8_t *) &rfcomm_payload[0], rfcomm_payload_len); +} + + + + + diff --git a/test/hfp/mock.h b/test/hfp/mock.h new file mode 100644 index 000000000..b193ad6df --- /dev/null +++ b/test/hfp/mock.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +// ***************************************************************************** +// +// HFP BTstack Mocks +// +// ***************************************************************************** + +#include +#include +#include +#include + +// HFP Mock API +uint8_t * get_rfcomm_payload(); +uint16_t get_rfcomm_payload_len(); +void inject_rfcomm_command(uint8_t * data, int len); +int expected_rfcomm_command(const char * cmd); diff --git a/test/hfp/test_sequences.c b/test/hfp/test_sequences.c new file mode 100644 index 000000000..c73c676aa --- /dev/null +++ b/test/hfp/test_sequences.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +// ***************************************************************************** +// +// HFP Test Sequences +// +// ***************************************************************************** + +#include +#include +#include +#include + +#include "test_sequences.h" + + +#define TEST_SEQUENCE(name) { (char**)name, sizeof(name) / sizeof(char *)} + +/* Service Level Connection (slc) test sequences */ + +const char * slc_test1[] = { + "AT+BRSF=438", + "+BRSF:1007", + "OK", + "AT+BAC=1,2", + "OK", + "AT+CIND=?", + "+CIND:(\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0,3)),(\"battchg\",(0,5)),(\"signal\",(0,5)),(\"roam\",(0,1)),(\"callheld\",(0,2))", + "OK", + "AT+CIND?", + "+CIND:1,0,0,3,5,0,0", + "OK", + "AT+CMER=3,0,0,1", + "OK", + "AT+CHLD=?", + "+CHLD:(1,1x,2,2x,3)", + "OK" +}; + +hfp_test_item_t slc_tests[] = { + TEST_SEQUENCE(slc_test1) +}; + +/* Service Level Connection (slc) common commands */ +const char * slc_cmds_test1[] = { + "AT+BAC=1,3", + "OK" +}; + +hfp_test_item_t slc_cmds_tests[] = { + TEST_SEQUENCE(slc_cmds_test1) +}; +/* Codecs Connection (cc) test sequences */ + +const char * cc_test1[] = { + "AT+BCC", + "OK", + "+BCS:1", + "AT+BCS=1", + "OK" +}; + +const char * cc_test2[] = { + "AT+BCC", + "OK", + "+BCS:1", + "AT+BAC=2,3", + "OK", + "+BCS:2", + "AT+BCS=2", + "OK" +}; + +hfp_test_item_t cc_tests[] = { + TEST_SEQUENCE(cc_test1), + TEST_SEQUENCE(cc_test2) +}; + + + +////////////// + +int test_item_size = sizeof(hfp_test_item_t); + +// SLC +hfp_test_item_t * hfp_slc_tests(){ + return slc_tests; +} + +int slc_tests_size(){ + return sizeof(slc_tests)/test_item_size; +} + +char ** default_slc_setup(){ + return (char **)slc_test1; +} + +int default_slc_setup_size(){ + return sizeof(slc_test1)/sizeof(char*); +} + +// CC +hfp_test_item_t * hfp_cc_tests(){ + return cc_tests; +} +int cc_tests_size(){ + return sizeof(cc_tests) /test_item_size; +} +char ** default_cc_setup(){ + return (char **)cc_test1; +} +int default_cc_setup_size(){ + return sizeof(cc_test1)/sizeof(char*); +} + \ No newline at end of file diff --git a/test/hfp/test_sequences.h b/test/hfp/test_sequences.h new file mode 100644 index 000000000..f5d7eb6f5 --- /dev/null +++ b/test/hfp/test_sequences.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +// ***************************************************************************** +// +// HFP Test Sequences +// +// ***************************************************************************** + +#include +#include +#include +#include + +typedef struct hfp_test_item{ + char ** test; + int len; +} hfp_test_item_t; + + +/* Service Level Connection (slc) test sequences */ +hfp_test_item_t * hfp_slc_tests(); +int slc_tests_size(); +char ** default_slc_setup(); +int default_slc_setup_size(); + +/* Service Level Connection (slc) common commands */ +hfp_test_item_t * hfp_slc_cmds_tests(); + +/* Codecs Connection (cc) test sequences */ +hfp_test_item_t * hfp_cc_tests(); +int cc_tests_size(); +char ** default_cc_setup(); +int default_cc_setup_size(); + From 114c2ff23a9acd5ddbea8ee436e4cba5c6e05f36 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Wed, 23 Sep 2015 16:59:52 +0200 Subject: [PATCH 3/3] ignore ag client test object --- test/hfp/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hfp/.gitignore b/test/hfp/.gitignore index 05b844ead..2b8d1607f 100644 --- a/test/hfp/.gitignore +++ b/test/hfp/.gitignore @@ -1,4 +1,4 @@ hfp_hf_client_test -hfp_ag_parser_test +hfp_ag_client_test hfp_hf_parser_test hfp_ag_parser_test \ No newline at end of file