@@ -275,7 +275,7 @@ u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
275275#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ )
276276 if (!conn -> llcp_conn_param .disabled &&
277277 (!conn -> common .fex_valid ||
278- (conn -> llcp_feature .features &
278+ (conn -> llcp_feature .features_conn &
279279 BIT (BT_LE_FEAT_BIT_CONN_PARAM_REQ )))) {
280280 cmd ++ ;
281281 } else if (conn -> lll .role ) {
@@ -2499,7 +2499,8 @@ static inline void event_enc_reject_prep(struct ll_conn *conn,
24992499 pdu -> ll_id = PDU_DATA_LLID_CTRL ;
25002500
25012501 if (conn -> common .fex_valid &&
2502- (conn -> llcp_feature .features & BIT (BT_LE_FEAT_BIT_EXT_REJ_IND ))) {
2502+ (conn -> llcp_feature .features_conn &
2503+ BIT (BT_LE_FEAT_BIT_EXT_REJ_IND ))) {
25032504 struct pdu_data_llctrl_reject_ext_ind * p ;
25042505
25052506 pdu -> llctrl .opcode = PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND ;
@@ -2727,7 +2728,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
27272728 pdu -> llctrl .opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP ;
27282729 (void )memset (& pdu -> llctrl .feature_rsp .features [0 ], 0x00 ,
27292730 sizeof (pdu -> llctrl .feature_rsp .features ));
2730- sys_put_le24 (conn -> llcp_feature .features ,
2731+ sys_put_le24 (conn -> llcp_feature .features_peer ,
27312732 pdu -> llctrl .feature_req .features );
27322733
27332734 /* enqueue feature rsp structure into rx queue */
@@ -2745,7 +2746,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
27452746 conn -> llcp_feature .ack -- ;
27462747
27472748 /* use initial feature bitmap */
2748- conn -> llcp_feature .features = LL_FEAT ;
2749+ conn -> llcp_feature .features_conn = LL_FEAT ;
27492750
27502751 /* place the feature exchange req packet as next in tx queue */
27512752 pdu -> ll_id = PDU_DATA_LLID_CTRL ;
@@ -2757,7 +2758,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
27572758 (void )memset (& pdu -> llctrl .feature_req .features [0 ],
27582759 0x00 ,
27592760 sizeof (pdu -> llctrl .feature_req .features ));
2760- sys_put_le24 (conn -> llcp_feature .features ,
2761+ sys_put_le24 (conn -> llcp_feature .features_conn ,
27612762 pdu -> llctrl .feature_req .features );
27622763
27632764 ctrl_tx_enqueue (conn , tx );
@@ -3162,14 +3163,14 @@ static inline void dle_max_time_get(const struct ll_conn *conn,
31623163
31633164#if defined(CONFIG_BT_CTLR_PHY )
31643165#if defined(CONFIG_BT_CTLR_PHY_CODED )
3165- feature_coded_phy = (conn -> llcp_feature .features &
3166+ feature_coded_phy = (conn -> llcp_feature .features_conn &
31663167 BIT (BT_LE_FEAT_BIT_PHY_CODED ));
31673168#else
31683169 feature_coded_phy = 0 ;
31693170#endif
31703171
31713172#if defined(CONFIG_BT_CTLR_PHY_2M )
3172- feature_phy_2m = (conn -> llcp_feature .features &
3173+ feature_phy_2m = (conn -> llcp_feature .features_conn &
31733174 BIT (BT_LE_FEAT_BIT_PHY_2M ));
31743175#else
31753176 feature_phy_2m = 0 ;
@@ -4007,12 +4008,28 @@ static inline u32_t feat_get(u8_t *features)
40074008 return feat ;
40084009}
40094010
4011+ /*
4012+ * Perform a logical and on octet0 and keep the remaining bits of the
4013+ * first input parameter
4014+ */
4015+ static inline u32_t feat_land_octet0 (u32_t feat_to_keep , u32_t feat_octet0 )
4016+ {
4017+ u32_t feat_result ;
4018+
4019+ feat_result = feat_to_keep & feat_octet0 ;
4020+ feat_result &= 0xFF ;
4021+ feat_result |= feat_to_keep & LL_FEAT_FILTER_OCTET0 ;
4022+
4023+ return feat_result ;
4024+ }
4025+
40104026static int feature_rsp_send (struct ll_conn * conn , struct node_rx_pdu * rx ,
40114027 struct pdu_data * pdu_rx )
40124028{
40134029 struct pdu_data_llctrl_feature_req * req ;
40144030 struct node_tx * tx ;
40154031 struct pdu_data * pdu_tx ;
4032+ u32_t feat ;
40164033
40174034 /* acquire tx mem */
40184035 tx = mem_acquire (& mem_conn_tx_ctrl .free );
@@ -4022,7 +4039,14 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
40224039
40234040 /* AND the feature set to get Feature USED */
40244041 req = & pdu_rx -> llctrl .feature_req ;
4025- conn -> llcp_feature .features &= feat_get (& req -> features [0 ]);
4042+ conn -> llcp_feature .features_conn &= feat_get (& req -> features [0 ]);
4043+ /*
4044+ * Get all the features of peer, except octet 0.
4045+ * Octet 0 is the actual features used on the link
4046+ * See BTCore V5.2, Vol. 6, Part B, chapter 5.1.4
4047+ */
4048+ conn -> llcp_feature .features_peer =
4049+ feat_land_octet0 (feat_get (& req -> features [0 ]), LL_FEAT );
40264050
40274051 /* features exchanged */
40284052 conn -> common .fex_valid = 1U ;
@@ -4031,12 +4055,16 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
40314055 pdu_tx = (void * )tx -> pdu ;
40324056 pdu_tx -> ll_id = PDU_DATA_LLID_CTRL ;
40334057 pdu_tx -> len = offsetof(struct pdu_data_llctrl , feature_rsp ) +
4034- sizeof (struct pdu_data_llctrl_feature_rsp );
4058+ sizeof (struct pdu_data_llctrl_feature_rsp );
40354059 pdu_tx -> llctrl .opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP ;
40364060 (void )memset (& pdu_tx -> llctrl .feature_rsp .features [0 ], 0x00 ,
40374061 sizeof (pdu_tx -> llctrl .feature_rsp .features ));
4038- sys_put_le24 (conn -> llcp_feature .features ,
4039- pdu_tx -> llctrl .feature_req .features );
4062+ /*
4063+ * On feature response we send the local supported features.
4064+ * See BTCore V5.2 VOl 6 Part B, chapter 5.1.4
4065+ */
4066+ feat = feat_land_octet0 (LL_FEAT , conn -> llcp_feature .features_conn );
4067+ sys_put_le24 (feat , pdu_tx -> llctrl .feature_rsp .features );
40404068
40414069 ctrl_tx_sec_enqueue (conn , tx );
40424070
@@ -4053,7 +4081,14 @@ static void feature_rsp_recv(struct ll_conn *conn, struct pdu_data *pdu_rx)
40534081 rsp = & pdu_rx -> llctrl .feature_rsp ;
40544082
40554083 /* AND the feature set to get Feature USED */
4056- conn -> llcp_feature .features &= feat_get (& rsp -> features [0 ]);
4084+ conn -> llcp_feature .features_conn &= feat_get (& rsp -> features [0 ]);
4085+ /*
4086+ * Get all the features of peer, except octet 0.
4087+ * Octet 0 is the actual features used on the link
4088+ * See BTCore V5.2, Vol. 6, Part B, chapter 5.1.4
4089+ */
4090+ conn -> llcp_feature .features_peer =
4091+ feat_land_octet0 (feat_get (& rsp -> features [0 ]), LL_FEAT );
40574092
40584093 /* features exchanged */
40594094 conn -> common .fex_valid = 1U ;
0 commit comments