pts/sm_test: support passkey entry

This commit is contained in:
Matthias Ringwald 2018-03-27 16:09:33 +02:00
parent ad912a6c9e
commit a5171bb237
3 changed files with 115 additions and 13 deletions

View File

@ -282,6 +282,7 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
printf("PASSKEY_INPUT_NUMBER\n");
ui_passkey = 0;
ui_digits_for_passkey = 6;
// sm_keypress_notification(connection_handle, SM_KEYPRESS_PASSKEY_ENTRY_STARTED);
break;
case SM_EVENT_PASSKEY_DISPLAY_NUMBER:
// display number
@ -313,8 +314,34 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
fflush(stdout);
}
static void stdin_process(char c){
#define KEYPRESS_DELAY 100
static btstack_timer_source_t passkey_timer;
static int num_keypresses_to_send;
static void passkey_entry_complete(btstack_timer_source_t * ts){
if (num_keypresses_to_send > 0){
num_keypresses_to_send--;
// sm_keypress_notification(connection_handle, SM_KEYPRESS_PASSKEY_DIGIT_ENTERED);
btstack_run_loop_set_timer(ts, KEYPRESS_DELAY);
btstack_run_loop_add_timer(ts);
return;
}
if (num_keypresses_to_send == 0){
num_keypresses_to_send--;
// sm_keypress_notification(connection_handle, SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED);
btstack_run_loop_set_timer(ts, KEYPRESS_DELAY);
btstack_run_loop_add_timer(ts);
return;
}
printf("\nSending Passkey '%06u'\n", ui_passkey);
if (sm_failure == SM_REASON_PASSKEY_ENTRY_FAILED){
// simulate passkey failure
ui_passkey--;
}
sm_passkey_input(connection_handle, ui_passkey);
}
static void stdin_process(char c){
// passkey input
if (ui_digits_for_passkey){
if (c < '0' || c > '9') return;
@ -323,8 +350,11 @@ static void stdin_process(char c){
ui_passkey = ui_passkey * 10 + c - '0';
ui_digits_for_passkey--;
if (ui_digits_for_passkey == 0){
printf("Sending Passkey '%06x'\n", ui_passkey);
sm_passkey_input(connection_handle, ui_passkey);
num_keypresses_to_send = 6;
// set one-shot timer
passkey_timer.process = &passkey_entry_complete;
btstack_run_loop_set_timer(&passkey_timer, KEYPRESS_DELAY);
btstack_run_loop_add_timer(&passkey_timer);
}
return;
}
@ -423,7 +453,7 @@ int btstack_main(int argc, const char * argv[]){
sm_set_authentication_requirements(sm_auth_req);
sm_register_oob_data_callback(get_oob_data_callback);
if (sm_failure < SM_REASON_NUMERIC_COMPARISON_FAILED){
if (sm_failure < SM_REASON_NUMERIC_COMPARISON_FAILED && sm_failure != SM_REASON_PASSKEY_ENTRY_FAILED){
sm_test_set_pairing_failure(sm_failure);
}

View File

@ -60,5 +60,49 @@ SM/MAS/SCJW/BI-01-C/04,0,0,8,8,0,0,9
# tester responds with pairing failure during phase 2
SM/MAS/SCJW/BI-01-C/05,0,0,8,8,0,0,12
# tester responds with pairing failure during phase 2
# TODO: tester responds with pairing failure during phase 2
SM/SLA/SCJW/BI-02-C,0,3,8,8,0,0,4
# -- Passkey Entry (SCPK) --
# TODO: keypress notifications prevent pairing exchange
SM/MAS/SCPK/BV-01-C,0,2,24,28,0,0,0
SM/SLA/SCPK/BV-02-C/01,2,4,24,12,0,0,0
SM/SLA/SCPK/BV-02-C/02,2,4,24,28,0,0,0
# additional bits set in authreq
SM/SLA/SCPK/BV-03-C/01,0,2,8,76,0,0,0
SM/SLA/SCPK/BV-03-C/02,0,2,8,140,0,0,0
SM/SLA/SCPK/BV-03-C/03,0,2,8,204,0,0,0
# same as SM/SLA/SCPK/BV-03-C, just with IUT in Initiator role
SM/MAS/SCPK/BV-03-C/01,0,2,8,76,0,0,0
SM/MAS/SCPK/BV-03-C/02,0,2,8,140,0,0,0
SM/MAS/SCPK/BV-03-C/03,0,2,8,204,0,0,0
# tester responds with pairing failure in responder role
SM/MAS/SCPK/BI-01-C/01,0,0,8,8,0,0,3
SM/MAS/SCPK/BI-01-C/02,0,0,8,8,0,0,8
SM/MAS/SCPK/BI-01-C/03,0,0,8,8,0,0,5
SM/MAS/SCPK/BI-01-C/04,0,0,8,8,0,0,9
# TODO: we enter incorrect Passkey, and get DHKey Check error instead of passkey entry failed
SM/MAS/SCPK/BI-01-C/05,0,2,8,12,0,0,1
SM/SLA/SCPK/BI-04-C/01,0,0,8,8,0,0,3
SM/SLA/SCPK/BI-04-C/02,0,0,8,8,0,0,8
SM/SLA/SCPK/BI-04-C/03,0,0,8,8,0,0,5
SM/SLA/SCPK/BI-04-C/04,0,0,8,8,0,0,9
# TODO: tester responds with pairing failure during phase 2
SM/MAS/SCPK/BI-02-C,0,3,8,8,0,0,4
# TODO: tester responds with pairing failure during phase 2
SM/SLA/SCPK/BI-03-C,0,3,8,8,0,0,4
# TODO: we enter incorrect Passkey, and get DHKey Check error instead of passkey entry failed
SM/SLA/SCPK/BI-04-C/05,0,2,8,12,0,0,1

1 name,iut_io_capabilities,tester_io_capabilities,iut_auth_req,tester_auth_req,iut_oob_data,tester_oob_data,tester_failure
60 SM/SLA/SCPK/BV-03-C/02,0,2,8,140,0,0,0
61 SM/SLA/SCPK/BV-03-C/03,0,2,8,204,0,0,0
62 # same as SM/SLA/SCPK/BV-03-C, just with IUT in Initiator role
63 SM/MAS/SCPK/BV-03-C/01,0,2,8,76,0,0,0
64 SM/MAS/SCPK/BV-03-C/02,0,2,8,140,0,0,0
65 SM/MAS/SCPK/BV-03-C/03,0,2,8,204,0,0,0
66 # tester responds with pairing failure in responder role
67 SM/MAS/SCPK/BI-01-C/01,0,0,8,8,0,0,3
68 SM/MAS/SCPK/BI-01-C/02,0,0,8,8,0,0,8
69 SM/MAS/SCPK/BI-01-C/03,0,0,8,8,0,0,5
70 SM/MAS/SCPK/BI-01-C/04,0,0,8,8,0,0,9
71 # TODO: we enter incorrect Passkey, and get DHKey Check error instead of passkey entry failed
72 SM/MAS/SCPK/BI-01-C/05,0,2,8,12,0,0,1
73 SM/SLA/SCPK/BI-04-C/01,0,0,8,8,0,0,3
74 SM/SLA/SCPK/BI-04-C/02,0,0,8,8,0,0,8
75 SM/SLA/SCPK/BI-04-C/03,0,0,8,8,0,0,5
76 SM/SLA/SCPK/BI-04-C/04,0,0,8,8,0,0,9
77 # TODO: tester responds with pairing failure during phase 2
78 SM/MAS/SCPK/BI-02-C,0,3,8,8,0,0,4
79 # TODO: tester responds with pairing failure during phase 2
80 SM/SLA/SCPK/BI-03-C,0,3,8,8,0,0,4
81 # TODO: we enter incorrect Passkey, and get DHKey Check error instead of passkey entry failed
82 SM/SLA/SCPK/BI-04-C/05,0,2,8,12,0,0,1
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

View File

@ -30,7 +30,7 @@ SM_AUTHREQ_SECURE_CONNECTION = 0x08
SM_AUTHREQ_KEYPRESS = 0x10
failures = [
'RESERVED',
'',
'PASSKEY_ENTRY_FAILED',
'OOB_NOT_AVAILABLE',
'AUTHENTHICATION_REQUIREMENTS',
@ -46,7 +46,7 @@ failures = [
]
# tester config
debug = True
debug = False
regenerate = False
# usb_paths = ['4', '6']
usb_paths = ['3', '5']
@ -110,6 +110,8 @@ class Node:
if self.failure != None:
args.append('-f')
args.append(self.failure)
args.append('-i')
args.append(self.io_capabilities)
args.append('-r')
args.append(self.auth_req)
print('%s - "%s"' % (self.name, ' '.join(args)))
@ -133,7 +135,9 @@ class Node:
self.peer_addr = addr
def write(self, string):
self.stdin.write(string)
for c in string:
self.stdin.write(string)
time.sleep (0.1);
def terminate(self):
self.write('x')
@ -158,7 +162,7 @@ def run(test_descriptor, nodes):
path = line.split(': ')[1]
node.set_packet_log(path)
print('%s log %s' % (node.get_name(), path))
if line.startswith('BD_ADDR: '):
elif line.startswith('BD_ADDR: '):
addr = line.split(': ')[1]
node.set_bd_addr(addr)
print('%s started' % node.get_name())
@ -177,11 +181,11 @@ def run(test_descriptor, nodes):
master.set_failure(test_descriptor['tester_failure'])
master.start_process()
nodes.append(master)
if line.startswith('CONNECTED:'):
elif line.startswith('CONNECTED:'):
print('%s connected' % node.get_name())
if state == 'W4_CONNECTED':
state = 'W4_PAIRING'
if line.startswith('JUST_WORKS_REQUEST'):
elif line.startswith('JUST_WORKS_REQUEST'):
print('%s just works requested' % node.get_name())
if node.get_name() == 'tester' and test_descriptor['tester_failure'] == '12':
print('Decline bonding')
@ -189,7 +193,21 @@ def run(test_descriptor, nodes):
else:
print('Accept bonding')
node.write('a')
if line.startswith('PAIRING_COMPLETE'):
elif line.startswith('PASSKEY_DISPLAY_NUMBER'):
passkey = line.split(': ')[1]
print('%s passkey display %s' % (node.get_name(), passkey))
test_descriptor['passkey'] = passkey
if state == 'W4_PAIRING':
state = 'W4_PASSKEY_INPUT'
else:
test_descriptor['waiting_node'].write(test_descriptor['passkey'])
elif line.startswith('PASSKEY_INPUT_NUMBER'):
if state == 'W4_PASSKEY_INPUT':
node.write(test_descriptor['passkey'])
else:
test_descriptor['waiting_node'] = node
state = 'W4_PASSKEY_DISPLAY'
elif line.startswith('PAIRING_COMPLETE'):
result = line.split(': ')[1]
(status,reason) = result.split(',')
test_descriptor[node.get_name()+'_pairing_complete_status'] = status
@ -201,7 +219,7 @@ def run(test_descriptor, nodes):
# on error, test is finished, else wait for notify
if status != '0':
return
if line.startswith('COUNTER'):
elif line.startswith('COUNTER'):
print('%s notification received' % node.get_name())
return;
@ -215,8 +233,10 @@ def write_config(fout, test_descriptor):
'io_capabilities',
'mitm',
'secure_connection',
'keypress',
'rfu',
'oob_data',
'passkey',
'pairing_complete_status',
'pairing_complete_reason']
@ -246,9 +266,17 @@ def write_config(fout, test_descriptor):
elif attribute == 'secure_connection':
iut = (int(test_descriptor['iut_auth_req' ]) & SM_AUTHREQ_SECURE_CONNECTION) >> 3
tester = (int(test_descriptor['tester_auth_req']) & SM_AUTHREQ_SECURE_CONNECTION) >> 3
elif attribute == 'keypress':
iut = (int(test_descriptor['iut_auth_req' ]) & SM_AUTHREQ_KEYPRESS) >> 4
tester = (int(test_descriptor['tester_auth_req']) & SM_AUTHREQ_KEYPRESS) >> 4
elif attribute == 'rfu':
iut = (int(test_descriptor['iut_auth_req' ]) & 192) >> 6
tester = (int(test_descriptor['tester_auth_req']) & 192) >> 6
elif attribute == 'passkey':
if not 'passkey' in test_descriptor:
continue
iut = test_descriptor['passkey']
tester = test_descriptor['passkey']
elif attribute == 'failure':
iut = ''
tester = failures[int(test_descriptor['tester_failure'])]