Remote device changes for SMP certification
Use Case:
Certification test cases for SMP require various scenarios
where the remote device needs to show a specific behavior
where it fails the pairing in a certain way, and the DUT is
required to abort the pairing properly.
In abcense of a proper PTS suite to execute these test cases,
we can use another device running the same host by configuring
certain run time property.
Test Cases:
TP/SCJW/BI-02-C
TP/SCJW/BV-02-C
TP/SCPK/BI-03-C
TP/SCPK/BI-04-C
TP/SCPK/BV-02-C
TP/SCPK/BV-03-C
TP/SCJW/BI-01-C
TP/SCCT/BV-01-C
TP/SCCT/BV-02-C
TP/SCPK/BI-01-C
TP/SCPK/BI-02-C
TP/SCPK/BV-04-C
TP/SCPK/BV-01-C
Fix:
Added a property in the bt_stack.conf file. The property name
is "SmpFailureCase". The values 2 to 6(inclusive), are forcausing SMP
failures with various failure reasons.
Failure case 1 and 9 are for producing error "Confirm value failure".
Cases 7 and 8 are for generating specific errors at pair cancel.
Note:
The default use of this feature is controlled using a compile
time flag BTM_BLE_SMP_CERTIFICATION.
The BTM_BLE_SMP_CERTIFICATION = TRUE is needed only while we
wait for the PTS support for the LE Secure connections.
Bug: 27852645
Change-Id: I1f7a8ff2659d85b5978b75870c57162a34d394d0
diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc
index 81cf1ac..7b6e385 100644
--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -2915,7 +2915,7 @@
** add a node with label "SmpOptions" to the config file
** and assign it a comma separated list of 5 values in the
** format: auth, io, ikey, rkey, ksize, oob
-** eg: SmpOptions=0xD,0x4,0xf,0xf,0x10
+** eg: PTS_SmpOptions=0xD,0x4,0xf,0xf,0x10
**
** Parameters: tBTE_APPL_CFG*: pointer to struct defining pairing options
**
@@ -2924,13 +2924,13 @@
*******************************************************************************/
BOOLEAN btif_dm_get_smp_config(tBTE_APPL_CFG* p_cfg) {
- if(!stack_config_get_interface()->get_smp_options()) {
+ if(!stack_config_get_interface()->get_pts_smp_options()) {
BTIF_TRACE_DEBUG ("%s: SMP options not found in configuration", __func__);
return FALSE;
}
char conf[64];
- const char* recv = stack_config_get_interface()->get_smp_options();
+ const char* recv = stack_config_get_interface()->get_pts_smp_options();
char* pch;
char* endptr;
diff --git a/conf/bt_stack.conf b/conf/bt_stack.conf
index c7bbb5a..3a7f48b 100644
--- a/conf/bt_stack.conf
+++ b/conf/bt_stack.conf
@@ -40,7 +40,7 @@
TRC_BNEP=2
TRC_PAN=2
-# PTS testing helps
+# PTS testing helpers
# Secure connections only mode.
# PTS_SecurePairOnly=true
@@ -53,3 +53,19 @@
# SMP Pair options (formatted as hex bytes) auth, io, ikey, rkey, ksize
#PTS_SmpOptions=0xD,0x4,0xf,0xf,0x10
+
+# SMP Certification Failure Cases
+# Fail case number range from 1 to 9 will set up remote device for test
+# case execution. Setting PTS_SmpFailureCase to 0 means normal operation.
+# Failure modes:
+# 1 = SMP_CONFIRM_VALUE_ERR
+# 2 = SMP_PAIR_AUTH_FAIL
+# 3 = SMP_PAIR_FAIL_UNKNOWN
+# 4 = SMP_PAIR_NOT_SUPPORT
+# 5 = SMP_PASSKEY_ENTRY_FAIL
+# 6 = SMP_REPEATED_ATTEMPTS
+# 7 = PIN generation failure?
+# 8 = SMP_PASSKEY_ENTRY_FAIL
+# 9 = SMP_NUMERIC_COMPAR_FAIL;
+#PTS_SmpFailureCase=0
+
diff --git a/include/stack_config.h b/include/stack_config.h
index eb52071..b5278ce 100644
--- a/include/stack_config.h
+++ b/include/stack_config.h
@@ -37,7 +37,8 @@
bool (*get_pts_secure_only_mode)(void);
bool (*get_pts_conn_updates_disabled)(void);
bool (*get_pts_crosskey_sdp_disable)(void);
- const char* (*get_smp_options)(void);
+ const char* (*get_pts_smp_options)(void);
+ int (*get_pts_smp_failure_case)(void);
config_t *(*get_all)(void);
} stack_config_t;
diff --git a/main/stack_config.c b/main/stack_config.c
index 09904e3..3f8b8af 100644
--- a/main/stack_config.c
+++ b/main/stack_config.c
@@ -33,6 +33,7 @@
const char *PTS_LE_CONN_UPDATED_DISABLED = "PTS_DisableConnUpdates";
const char *PTS_DISABLE_SDP_LE_PAIR = "PTS_DisableSDPOnLEPair";
const char *PTS_SMP_PAIRING_OPTIONS_KEY = "PTS_SmpOptions";
+const char *PTS_SMP_FAILURE_CASE_KEY = "PTS_SmpFailureCase";
static config_t *config;
@@ -108,6 +109,10 @@
return config_get_string(config, CONFIG_DEFAULT_SECTION, PTS_SMP_PAIRING_OPTIONS_KEY, NULL);
}
+static int get_pts_smp_failure_case(void) {
+ return config_get_int(config, CONFIG_DEFAULT_SECTION, PTS_SMP_FAILURE_CASE_KEY, 0);
+}
+
static config_t *get_all(void) {
return config;
}
@@ -121,6 +126,7 @@
get_pts_conn_updates_disabled,
get_pts_crosskey_sdp_disable,
get_pts_smp_options,
+ get_pts_smp_failure_case,
get_all
};
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index c8fe9b2..1e3effe 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -63,6 +63,42 @@
return acl->lmp_version < version;
}
+static bool pts_test_send_authentication_complete_failure(tSMP_CB *p_cb)
+{
+ uint8_t reason = 0;
+
+ if (p_cb->cert_failure < 2 || p_cb->cert_failure > 6)
+ return false;
+
+ SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure);
+
+ switch (p_cb->cert_failure)
+ {
+ case 2:
+ reason = SMP_PAIR_AUTH_FAIL;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ break;
+ case 3:
+ reason = SMP_PAIR_FAIL_UNKNOWN;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ break;
+ case 4:
+ reason = SMP_PAIR_NOT_SUPPORT;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ break;
+ case 5:
+ reason = SMP_PASSKEY_ENTRY_FAIL;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ break;
+ case 6:
+ reason = SMP_REPEATED_ATTEMPTS;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ break;
+ }
+
+ return true;;
+}
+
/*******************************************************************************
** Function smp_update_key_mask
** Description This function updates the key mask for sending or receiving.
@@ -550,6 +586,10 @@
return;
}
+ // PTS Testing failure modes
+ if (pts_test_send_authentication_complete_failure(p_cb))
+ return;
+
if (p_cb->role == HCI_ROLE_SLAVE)
{
if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD))
@@ -1403,6 +1443,11 @@
{
if (smp_request_oob_data(p_cb)) return;
}
+
+ // PTS Testing failure modes
+ if (pts_test_send_authentication_complete_failure(p_cb))
+ return;
+
smp_send_pair_rsp(p_cb, NULL);
}
}
@@ -1638,6 +1683,14 @@
SMP_TRACE_DEBUG("%s start ", __func__);
+ // PTS Testing failure modes
+ if (p_cb->cert_failure == 1) {
+ SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure);
+ reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ return;
+ }
+
switch(p_cb->selected_association_model)
{
case SMP_MODEL_SEC_CONN_JUSTWORKS:
@@ -1671,7 +1724,7 @@
break;
case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
- if (!smp_check_commitment(p_cb))
+ if (!smp_check_commitment(p_cb) && p_cb->cert_failure != 9)
{
reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
diff --git a/stack/smp/smp_api.c b/stack/smp/smp_api.c
index 03f7518..b3373b5 100644
--- a/stack/smp/smp_api.c
+++ b/stack/smp/smp_api.c
@@ -26,6 +26,8 @@
#include "bt_target.h"
#include "bt_utils.h"
+#include "stack_config.h"
+
#if SMP_INCLUDED == TRUE
#include "smp_int.h"
#include "smp_api.h"
@@ -61,6 +63,11 @@
smp_l2cap_if_init();
/* initialization of P-256 parameters */
p_256_init_curve(KEY_LENGTH_DWORDS_P256);
+
+ /* Initialize failure case for certification */
+ smp_cb.cert_failure = stack_config_get_interface()->get_pts_smp_failure_case();
+ if (smp_cb.cert_failure)
+ SMP_TRACE_ERROR ("%s PTS FAILURE MODE IN EFFECT (CASE %d)", __func__, smp_cb.cert_failure);
}
@@ -219,6 +226,12 @@
UINT8 err_code = SMP_PAIR_FAIL_UNKNOWN;
BOOLEAN status = FALSE;
+ // PTS SMP failure test cases
+ if (p_cb->cert_failure == 7)
+ err_code = SMP_PASSKEY_ENTRY_FAIL;
+ else if (p_cb->cert_failure == 8)
+ err_code = SMP_NUMERIC_COMPAR_FAIL;
+
BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
if ( (p_cb->state != SMP_STATE_IDLE) &&
(!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index 8f272da..54f2371 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -343,7 +343,8 @@
UINT8 rcvd_cmd_len;
UINT16 total_tx_unacked;
BOOLEAN wait_for_authorization_complete;
-}tSMP_CB;
+ UINT8 cert_failure; /*failure case for certification */
+} tSMP_CB;
/* Server Action functions are of this type */
typedef void (*tSMP_ACT)(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);