hfp: add script for extracting PTS test sequences from log file; add pts test to HF and AG client

This commit is contained in:
Milanka Ringwald 2015-12-02 15:04:52 +01:00
parent d794a752e8
commit 0cacd247cd
9 changed files with 220 additions and 126 deletions

View File

@ -130,6 +130,7 @@ const char * hfp_ag_feature(int index){
}
int send_str_over_rfcomm(uint16_t cid, char * command){
log_info("PTS_TEST_TX %s", command);
if (!rfcomm_can_send_packet_now(cid)) return 1;
int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command));
if (err){

View File

@ -1523,6 +1523,12 @@ static hfp_generic_status_indicator_t *get_hf_indicator_by_number(int number){
static void hfp_handle_rfcomm_data(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;
char last_char = packet[size-1];
packet[size-1] = 0;
log_info("HFP_RX %s", packet);
packet[size-1] = last_char;
int pos;
for (pos = 0; pos < size ; pos++){
hfp_parse(context, packet[pos], 0);

View File

@ -919,9 +919,12 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel);
if (!context) return;
packet[size] = 0;
char last_char = packet[size-1];
packet[size-1] = 0;
log_info("HFP_RX %s", packet);
packet[size-1] = last_char;
int pos, i, value;
//printf("\nHF received: %s", packet+2);
for (pos = 0; pos < size ; pos++){
hfp_parse(context, packet[pos], 1);
}

View File

@ -0,0 +1,89 @@
#!/usr/bin/env python
# BlueKitchen GmbH (c) 2014
# primitive dump for PacketLogger format
# APPLE PacketLogger
# typedef struct {
# uint32_t len;
# uint32_t ts_sec;
# uint32_t ts_usec;
# uint8_t type; // 0xfc for note
# }
import re
import sys
import time
import datetime
packet_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="]
def read_net_32(f):
a = f.read(1)
b = f.read(1)
c = f.read(1)
d = f.read(1)
return ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d)
def as_hex(data):
str_list = []
for byte in data:
str_list.append("{0:02x} ".format(ord(byte)))
return ''.join(str_list)
if len(sys.argv) < 2:
print 'Dump PacketLogger file'
print 'Copyright 2014, BlueKitchen GmbH'
print ''
print 'Usage: ', sys.argv[0], 'hci_dump.pklg test_name'
exit(0)
infile = sys.argv[1]
test_name = sys.argv[2]
separator = ""
spaces = " "
print "const char * "+test_name+"[] = {"
with open (infile, 'rb') as fin:
try:
while True:
len = read_net_32(fin)
ts_sec = read_net_32(fin)
ts_usec = read_net_32(fin)
type = ord(fin.read(1))
packet_len = len - 9;
packet = fin.read(packet_len)
time = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000)
if type == 0xfc:
packet = packet.replace("\n","\\n");
packet = packet.replace("\r","\\r");
packet = packet.replace("\"","\\\"");
parts = re.match('HFP_RX(.*)',packet)
if not parts:
parts = re.match('PTS_TEST_TX(.*)',packet)
cmd = 0
if parts:
cmd = parts.groups()[0].strip()
cmd = cmd.replace("\\n","");
cmd = cmd.replace("\\r","");
if cmd:
#print "CMD ", packet
cmd_parts = re.match('(.*)OK', cmd)
if (cmd_parts):
if cmd_parts.groups()[0] <> "":
print separator+spaces+"\""+cmd_parts.groups()[0]+"\"",
print separator+spaces+"\"OK\"",
else:
print separator+spaces+"\""+cmd+"\"",
separator = ",\n"
except TypeError:
print "\n};\n"
exit(0)
print "\n};\n"

View File

@ -84,7 +84,7 @@ static hfp_ag_indicator_t ag_indicators[] = {
{7, "callheld", 0, 2, 0, 1, 1, 0}
};
static int supported_features_with_codec_negotiation = 1007; // 0011 1110 1111
static int supported_features_with_codec_negotiation = 4079; // 0011 1110 1111
static int supported_features_without_codec_negotiation = 495; // 0001 1110 1111
static int call_hold_services_nr = 5;
@ -118,9 +118,12 @@ int expected_rfcomm_command(const char * expected_cmd){
}
void simulate_test_sequence(char ** test_steps, int nr_test_steps){
void simulate_test_sequence(hfp_test_item_t * test_item){
char ** test_steps = test_item->test;
printf("\nSimulate test sequence: \"%s\"\n", test_item->name);
int i = 0;
for (i=0; i < nr_test_steps; i++){
for (i=0; i < test_item->len; i++){
char * cmd = test_steps[i];
printf("\n---> NEXT STEP %s\n", cmd);
if (strncmp(cmd, "AT", 2) == 0){
@ -213,59 +216,31 @@ TEST_GROUP(HFPClient){
audio_connection_established = 0;
}
void setup_hfp_service_level_connection(char ** test_steps, int nr_test_steps){
void setup_hfp_service_level_connection(hfp_test_item_t * test_item){
service_level_connection_established = 0;
hfp_ag_establish_service_level_connection(device_addr);
simulate_test_sequence((char **) test_steps, nr_test_steps);
simulate_test_sequence(test_item);
}
void setup_hfp_codecs_connection(char ** test_steps, int nr_test_steps){
void setup_hfp_codecs_connection(hfp_test_item_t * test_item){
codecs_connection_established = 0;
simulate_test_sequence((char **) test_steps, nr_test_steps);
simulate_test_sequence(test_item);
}
};
// TEST(HFPClient, HFAnswerIncomingCallWithInBandRingToneHFTermiantesCall){
// setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
// CHECK_EQUAL(service_level_connection_established, 1);
// hfp_ag_set_use_in_band_ring_tone(1);
// hfp_ag_incoming_call();
// simulate_test_sequence(default_ic_setup(), default_ic_setup_size());
// CHECK_EQUAL(audio_connection_established, 1);
// simulate_test_sequence(alert_ic_setup(), alert_ic_setup_size());
// CHECK_EQUAL(stop_ringing, 1);
// simulate_test_sequence(terminate_ic_hf_setup(), terminate_ic_hf_setup_size());
// CHECK_EQUAL(call_termiated,1);
// }
// TEST(HFPClient, HFAnswerIncomingCallWithInBandRingToneAGTerminatesCall){
// setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
// CHECK_EQUAL(service_level_connection_established, 1);
// hfp_ag_set_use_in_band_ring_tone(1);
// hfp_ag_incoming_call();
// simulate_test_sequence(default_ic_setup(), default_ic_setup_size());
// CHECK_EQUAL(audio_connection_established, 1);
// simulate_test_sequence(alert_ic_setup(), alert_ic_setup_size());
// CHECK_EQUAL(stop_ringing, 1);
// // AG terminates call
// hfp_ag_terminate_call();
// simulate_test_sequence(terminate_ic_ag_setup(), terminate_ic_ag_setup_size());
// CHECK_EQUAL(call_termiated,1);
// }
TEST(HFPClient, PTSSLCTests){
for (int i = 0; i < hfp_pts_slc_tests_size(); i++){
setup_hfp_service_level_connection(&hfp_pts_slc_tests()[i]);
teardown();
}
}
TEST(HFPClient, HFAudioConnectionEstablishedWithCodecNegotiation){
setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
setup_hfp_service_level_connection(default_hfp_slc_test());
CHECK_EQUAL(service_level_connection_established, 1);
setup_hfp_codecs_connection(default_cc_setup(), default_cc_setup_size());
setup_hfp_codecs_connection(default_hfp_cc_test());
CHECK_EQUAL(codecs_connection_established, 1);
hfp_ag_establish_audio_connection(device_addr);
@ -282,10 +257,10 @@ TEST(HFPClient, HFAudioConnectionEstablishedWithoutCodecNegotiation){
hf_indicators, hf_indicators_nr,
call_hold_services, call_hold_services_nr);
setup_hfp_service_level_connection(hfp_slc_tests()[1].test, hfp_slc_tests()[1].len);
setup_hfp_service_level_connection(&hfp_slc_tests()[1]);
CHECK_EQUAL(service_level_connection_established, 1);
setup_hfp_codecs_connection(default_cc_setup(), default_cc_setup_size());
setup_hfp_codecs_connection(default_hfp_cc_test());
CHECK_EQUAL(codecs_connection_established, 1);
hfp_ag_establish_audio_connection(device_addr);
@ -296,21 +271,21 @@ TEST(HFPClient, HFAudioConnectionEstablishedWithoutCodecNegotiation){
}
TEST(HFPClient, HFCodecsConnectionEstablished){
for (int i = 0; i < cc_tests_size(); i++){
setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
for (int i = 0; i < hfp_cc_tests_size(); i++){
setup_hfp_service_level_connection(default_hfp_slc_test());
CHECK_EQUAL(service_level_connection_established, 1);
setup_hfp_codecs_connection(hfp_cc_tests()[i].test, hfp_cc_tests()[i].len);
setup_hfp_codecs_connection(&hfp_cc_tests()[i]);
CHECK_EQUAL(codecs_connection_established, 1);
teardown();
}
}
TEST(HFPClient, HFServiceLevelConnectionCommands){
setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
setup_hfp_service_level_connection(default_hfp_slc_test());
CHECK_EQUAL(service_level_connection_established, 1);
for (int i = 0; i < slc_cmds_tests_size(); i++){
simulate_test_sequence(hfp_slc_cmds_tests()[i].test, hfp_slc_cmds_tests()[i].len);
for (int i = 0; i < hfp_slc_cmds_tests_size(); i++){
simulate_test_sequence(&hfp_slc_cmds_tests()[i]);
}
}
@ -320,13 +295,14 @@ TEST(HFPClient, HFServiceLevelConnectionEstablishedWithoutCodecNegotiation){
ag_indicators, ag_indicators_nr,
hf_indicators, hf_indicators_nr,
call_hold_services, call_hold_services_nr);
setup_hfp_service_level_connection(hfp_slc_tests()[1].test, hfp_slc_tests()[1].len);
setup_hfp_service_level_connection(&hfp_slc_tests()[1]);
CHECK_EQUAL(service_level_connection_established, 1);
}
TEST(HFPClient, HFServiceLevelConnectionEstablishedWithCodecNegotiation){
setup_hfp_service_level_connection(hfp_slc_tests()[0].test, hfp_slc_tests()[0].len);
setup_hfp_service_level_connection(default_hfp_slc_test());
CHECK_EQUAL(service_level_connection_established, 1);
teardown();
}
int main (int argc, const char * argv[]){

View File

@ -113,9 +113,12 @@ int expected_rfcomm_command(const char * cmd){
return cmd_found && ok_found;
}
void simulate_test_sequence(char ** test_steps, int nr_test_steps){
void simulate_test_sequence(hfp_test_item_t * test_item){
char ** test_steps = test_item->test;
printf("\nSimulate test sequence: \"%s\"\n", test_item->name);
int i = 0;
for (i=0; i < nr_test_steps; i++){
for (i=0; i < test_item->len; i++){
char * cmd = test_steps[i];
printf("\n---> NEXT STEP %s\n", cmd);
if (strncmp(cmd, "AT", 2) == 0){
@ -128,12 +131,12 @@ void simulate_test_sequence(char ** test_steps, int nr_test_steps){
new_codecs[1] = parsed_codecs[1];
hfp_hf_set_codecs((uint8_t*)new_codecs, 2);
} else {
printf("Verify\n");
int expected_cmd = expected_rfcomm_command(cmd);
if (expected_cmd){
printf("\nError: Expected:'%s', but got:'%s'", cmd, (char *)get_rfcomm_payload());
return;
}
printf("Command verified: %s\n", cmd);
inject_rfcomm_command_to_ag((uint8_t*)"NOP",3);
}
} else {
@ -215,27 +218,35 @@ TEST_GROUP(HFPClient){
audio_connection_established = 0;
}
void setup_hfp_service_level_connection(char ** test_steps, int nr_test_steps){
void setup_hfp_service_level_connection(hfp_test_item_t * test_item){
service_level_connection_established = 0;
hfp_hf_establish_service_level_connection(device_addr);
simulate_test_sequence((char **) test_steps, nr_test_steps);
simulate_test_sequence(test_item);
}
void setup_hfp_codecs_connection(char ** test_steps, int nr_test_steps){
void setup_hfp_codecs_connection(hfp_test_item_t * test_item){
codecs_connection_established = 0;
simulate_test_sequence((char **) test_steps, nr_test_steps);
simulate_test_sequence(test_item);
}
};
TEST(HFPClient, PTSSLCTests){
for (int i = 0; i < hfp_pts_slc_tests_size(); i++){
setup_hfp_service_level_connection(&hfp_pts_slc_tests()[i]);
CHECK_EQUAL(service_level_connection_established, 1);
teardown();
}
}
TEST(HFPClient, HFAudioConnectionEstablishedWithoutCodecNegotiation){
hfp_hf_init(rfcomm_channel_nr, supported_features_without_codec_negotiation, indicators, sizeof(indicators)/sizeof(uint16_t), 1);
hfp_hf_set_codecs(default_codecs, 1);
setup_hfp_service_level_connection(hfp_slc_tests()[1].test, hfp_slc_tests()[1].len);
setup_hfp_service_level_connection(&hfp_slc_tests()[1]);
CHECK_EQUAL(service_level_connection_established, 1);
setup_hfp_codecs_connection(default_cc_setup(), default_cc_setup_size());
setup_hfp_codecs_connection(default_hfp_cc_test());
CHECK_EQUAL(codecs_connection_established, 1);
hfp_hf_establish_audio_connection(device_addr);
@ -244,26 +255,26 @@ TEST(HFPClient, HFAudioConnectionEstablishedWithoutCodecNegotiation){
}
TEST(HFPClient, HFCodecsConnectionEstablished){
for (int i = 0; i < cc_tests_size(); i++){
setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
for (int i = 0; i < hfp_cc_tests_size(); i++){
setup_hfp_service_level_connection(default_hfp_slc_test());
CHECK_EQUAL(service_level_connection_established, 1);
setup_hfp_codecs_connection(hfp_cc_tests()[i].test, hfp_cc_tests()[i].len);
setup_hfp_codecs_connection(&hfp_cc_tests()[i]);
teardown();
}
}
TEST(HFPClient, HFServiceLevelConnectionCommands){
setup_hfp_service_level_connection(default_slc_setup(), default_slc_setup_size());
setup_hfp_service_level_connection(default_hfp_slc_test());
CHECK_EQUAL(service_level_connection_established, 1);
for (int i = 0; i < slc_cmds_tests_size(); i++){
simulate_test_sequence(hfp_slc_cmds_tests()[i].test, hfp_slc_cmds_tests()[i].len);
for (int i = 0; i < hfp_slc_cmds_tests_size(); i++){
simulate_test_sequence(&hfp_slc_cmds_tests()[i]);
}
}
TEST(HFPClient, 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 < hfp_slc_tests_size(); i++){
setup_hfp_service_level_connection(&hfp_slc_tests()[i]);
CHECK_EQUAL(service_level_connection_established, 1);
teardown();
}

View File

@ -164,7 +164,7 @@ static void hci_event_sco_complete(){
}
int hci_send_cmd(const hci_cmd_t *cmd, ...){
printf("hci_send_cmd opcode 0x%02x\n", cmd->opcode);
//printf("hci_send_cmd opcode 0x%02x\n", cmd->opcode);
if (cmd->opcode == 0x428){
hci_event_sco_complete();
}
@ -294,9 +294,10 @@ void inject_rfcomm_command_to_hf(uint8_t * data, int len){
prepare_rfcomm_buffer(data, len);
if (data[0] == '+' || (data[0] == 'O' && data[1] == 'K')){
printf("Send cmd to HF state machine: %s\n", data);
} else {
printf("Trigger HF state machine - %s", data);
}
}
//} else {
// printf("Trigger HF state machine - %s", data);
// }
(*registered_rfcomm_packet_handler)(active_connection, RFCOMM_DATA_PACKET, rfcomm_cid, (uint8_t *) &rfcomm_payload[0], rfcomm_payload_len);
}
@ -306,9 +307,10 @@ void inject_rfcomm_command_to_ag(uint8_t * data, int len){
prepare_rfcomm_buffer(data, len);
if (memcmp((char*)data, "AT", 2) == 0){
printf("Send cmd to AG state machine: %s\n", data);
} else {
printf("Trigger AG state machine - %s", data);
}
// } else {
// printf("Trigger AG state machine - %s", data);
// }
(*registered_rfcomm_packet_handler)(active_connection, RFCOMM_DATA_PACKET, rfcomm_cid, (uint8_t *) &rfcomm_payload[0], rfcomm_payload_len);
}

View File

@ -49,14 +49,14 @@
#include "test_sequences.h"
#define TEST_SEQUENCE(name) { (char**)name, sizeof(name) / sizeof(char *)}
#define TEST_SEQUENCE(test_sequence) { (char *)#test_sequence, (char**)test_sequence, sizeof(test_sequence) / sizeof(char *)}
/* Service Level Connection (slc) test sequences */
// with codec negotiation feature
const char * slc_test1[] = {
"AT+BRSF=438",
"+BRSF:1007",
"AT+BRSF=127",
"+BRSF:4079",
"OK",
"AT+BAC=1,2",
"OK",
@ -91,6 +91,7 @@ const char * slc_test2[] = {
"OK"
};
hfp_test_item_t slc_tests[] = {
TEST_SEQUENCE(slc_test1),
TEST_SEQUENCE(slc_test2)
@ -190,44 +191,60 @@ hfp_test_item_t ic_tests[] = {
TEST_SEQUENCE(ic_test1)
};
// PTS test sequences
const char * TC_AG_SLC_BV_01_C[] = {
"AT+BRSF=127" ,
"+BRSF:4079" ,
"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" ,
"AT+VGS=9" ,
"OK" ,
"AT+VGM=9" ,
"OK" ,
"AT+CLIP=1" ,
"OK" ,
"AT+CCWA=1" ,
"OK" ,
"AT+CMEE=1" ,
"OK"
};
hfp_test_item_t pts_slc_tests[] = {
TEST_SEQUENCE(TC_AG_SLC_BV_01_C)
};
//////////////
static int test_item_size = sizeof(hfp_test_item_t);
// SLC
int hfp_slc_tests_size(){ return sizeof(slc_tests)/test_item_size;}
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*);}
hfp_test_item_t * default_hfp_slc_test(){return &slc_tests[0];}
// SLC commands
int hfp_slc_cmds_tests_size(){ return sizeof(slc_cmds_tests)/test_item_size;}
hfp_test_item_t * hfp_slc_cmds_tests(){ return slc_cmds_tests;}
int slc_cmds_tests_size(){ return sizeof(slc_cmds_tests)/test_item_size;}
char ** default_slc_cmds_setup() { return (char **)slc_cmds_test1;}
int default_slc_cmds_setup_size(){ return sizeof(slc_cmds_test1)/sizeof(char*);}
hfp_test_item_t * default_slc_cmds_test() { return &slc_tests[0];}
// CC
int hfp_cc_tests_size(){ return sizeof(cc_tests) /test_item_size;}
hfp_test_item_t * hfp_cc_tests(){ return cc_tests;}
int cc_tests_size(){ return sizeof(cc_tests) /test_item_size;}
hfp_test_item_t * default_hfp_cc_test(){ return &cc_tests[0];}
char ** default_cc_setup() { return (char **)cc_test1;}
int default_cc_setup_size(){ return sizeof(cc_test1)/sizeof(char*);}
// PTS
int hfp_pts_slc_tests_size(){ return sizeof(pts_slc_tests)/test_item_size;}
hfp_test_item_t * hfp_pts_slc_tests(){ return pts_slc_tests;}
// IC
char ** default_ic_setup() { return (char **)ic_test1;}
int default_ic_setup_size(){ return sizeof(ic_test1)/sizeof(char*);}
char ** alert_ic_setup() { return (char **)ic_alert_test1;}
int alert_ic_setup_size(){ return sizeof(ic_alert_test1)/sizeof(char*);}
char ** terminate_ic_ag_setup() { return (char **)ic_ag_terminates_call;}
int terminate_ic_ag_setup_size(){ return sizeof(ic_ag_terminates_call)/sizeof(char*);}
char ** terminate_ic_hf_setup() { return (char **)ic_hf_terminates_call;}
int terminate_ic_hf_setup_size(){ return sizeof(ic_hf_terminates_call)/sizeof(char*);}

View File

@ -47,39 +47,28 @@
#include <string.h>
typedef struct hfp_test_item{
char * name;
char ** test;
int len;
} hfp_test_item_t;
/* Service Level Connection (slc) test sequences */
int hfp_slc_tests_size();
hfp_test_item_t * hfp_slc_tests();
int slc_tests_size();
char ** default_slc_setup();
int default_slc_setup_size();
hfp_test_item_t * default_hfp_slc_test();
/* Service Level Connection (slc) common commands */
int hfp_slc_cmds_tests_size();
hfp_test_item_t * hfp_slc_cmds_tests();
int slc_cmds_tests_size();
char ** default_slc_cmds_setup();
int default_slc_cmds_setup_size();
hfp_test_item_t * deafult_hfp_slc_cmds_test();
/* Codecs Connection (cc) test sequences */
int hfp_cc_tests_size();
hfp_test_item_t * hfp_cc_tests();
int cc_tests_size();
char ** default_cc_setup();
int default_cc_setup_size();
hfp_test_item_t * default_hfp_cc_test();
/* Incoming call (ic) test sequences */
char ** default_ic_setup();
int default_ic_setup_size();
char ** alert_ic_setup();
int alert_ic_setup_size();
char ** terminate_ic_ag_setup();
int terminate_ic_ag_setup_size();
char ** terminate_ic_hf_setup();
int terminate_ic_hf_setup_size();
/* PTS test sequences */
int hfp_pts_slc_tests_size();
hfp_test_item_t * hfp_pts_slc_tests();