@@ -1508,6 +1508,7 @@ static int bt_hfp_ag_bind_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1508
1508
{
1509
1509
uint32_t indicator ;
1510
1510
uint32_t hf_indicators = 0U ;
1511
+ uint32_t supported_indicators = 0U ;
1511
1512
int err ;
1512
1513
char * data ;
1513
1514
uint32_t len ;
@@ -1526,20 +1527,27 @@ static int bt_hfp_ag_bind_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1526
1527
}
1527
1528
1528
1529
hfp_ag_lock (ag );
1529
- hf_indicators = ag -> hf_indicators_of_hf & ag -> hf_indicators_of_ag ;
1530
+ hf_indicators = ag -> hf_indicators ;
1531
+ supported_indicators = ag -> hf_indicators_of_ag & ag -> hf_indicators_of_hf ;
1530
1532
hfp_ag_unlock (ag );
1531
- len = (sizeof (hf_indicators ) * 8 ) > HFP_HF_IND_MAX ? HFP_HF_IND_MAX
1532
- : (sizeof (hf_indicators ) * 8 );
1533
+ len = MIN (NUM_BITS (sizeof (supported_indicators )), HFP_HF_IND_MAX );
1533
1534
for (int i = 1 ; i < len ; i ++ ) {
1534
- if ( BIT ( i ) & hf_indicators ) {
1535
- err = hfp_ag_send_data ( ag , NULL , NULL , "\r\n+BIND:%d,%d\r\n" , i , 1 );
1536
- } else {
1537
- err = hfp_ag_send_data ( ag , NULL , NULL , "\r\n+BIND:%d,%d\r\n" , i , 0 ) ;
1535
+ bool enabled ;
1536
+
1537
+ if (!( BIT ( i ) & supported_indicators )) {
1538
+ continue ;
1538
1539
}
1539
- if (err < 0 ) {
1540
+
1541
+ enabled = BIT (i ) & hf_indicators ;
1542
+ err = hfp_ag_send_data (ag , NULL , NULL , "\r\n+BIND:%d,%d\r\n" , i ,
1543
+ enabled ? 1 : 0 );
1544
+ if (err ) {
1540
1545
return err ;
1541
1546
}
1542
- if (hf_indicators == 0 ) {
1547
+
1548
+ supported_indicators &= ~BIT (i );
1549
+
1550
+ if (!supported_indicators ) {
1543
1551
break ;
1544
1552
}
1545
1553
}
@@ -1561,12 +1569,11 @@ static int bt_hfp_ag_bind_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1561
1569
hfp_ag_lock (ag );
1562
1570
hf_indicators = ag -> hf_indicators_of_ag ;
1563
1571
hfp_ag_unlock (ag );
1564
- len = (sizeof (hf_indicators ) * 8 ) > HFP_HF_IND_MAX ? HFP_HF_IND_MAX
1565
- : (sizeof (hf_indicators ) * 8 );
1572
+ len = MIN (NUM_BITS (sizeof (hf_indicators )), HFP_HF_IND_MAX );
1566
1573
for (int i = 1 ; (i < len ) && (hf_indicators != 0 ); i ++ ) {
1567
1574
if (BIT (i ) & hf_indicators ) {
1568
1575
int length = snprintk (
1569
- data , (char * )& ag -> buffer [HF_MAX_BUF_LEN - 1 ] - data - 3 ,
1576
+ data , (char * )& ag -> buffer [HF_MAX_BUF_LEN - 1 ] - data - 2 ,
1570
1577
"%d" , i );
1571
1578
data += length ;
1572
1579
hf_indicators &= ~BIT (i );
@@ -1578,8 +1585,6 @@ static int bt_hfp_ag_bind_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1578
1585
}
1579
1586
* data = ')' ;
1580
1587
data ++ ;
1581
- * data = '\r' ;
1582
- data ++ ;
1583
1588
* data = '\0' ;
1584
1589
data ++ ;
1585
1590
@@ -1599,7 +1604,7 @@ static int bt_hfp_ag_bind_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1599
1604
}
1600
1605
}
1601
1606
1602
- if (indicator < (sizeof (hf_indicators ) * 8 )) {
1607
+ if (indicator < NUM_BITS (sizeof (hf_indicators ))) {
1603
1608
hf_indicators |= BIT (indicator );
1604
1609
}
1605
1610
}
@@ -3089,6 +3094,47 @@ static int bt_hfp_ag_cnum_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
3089
3094
return 0 ;
3090
3095
}
3091
3096
3097
+ static int bt_hfp_ag_biev_handler (struct bt_hfp_ag * ag , struct net_buf * buf )
3098
+ {
3099
+ uint32_t indicator ;
3100
+ uint32_t value ;
3101
+
3102
+ if (!is_char (buf , '=' )) {
3103
+ return - ENOTSUP ;
3104
+ }
3105
+
3106
+ if (get_number (buf , & indicator )) {
3107
+ return - ENOTSUP ;
3108
+ }
3109
+
3110
+ if (!is_char (buf , ',' )) {
3111
+ return - ENOTSUP ;
3112
+ }
3113
+
3114
+ if (get_number (buf , & value )) {
3115
+ return - ENOTSUP ;
3116
+ }
3117
+
3118
+ if (!is_char (buf , '\r' )) {
3119
+ return - ENOTSUP ;
3120
+ }
3121
+
3122
+ hfp_ag_lock (ag );
3123
+ if (!(ag -> hf_indicators_of_ag & BIT (indicator ))) {
3124
+ hfp_ag_unlock (ag );
3125
+ return - ENOTSUP ;
3126
+ }
3127
+ hfp_ag_unlock (ag );
3128
+
3129
+ #if defined(CONFIG_BT_HFP_AG_HF_INDICATORS )
3130
+ if (bt_ag && bt_ag -> hf_indicator_value ) {
3131
+ bt_ag -> hf_indicator_value (ag , indicator , value );
3132
+ }
3133
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
3134
+
3135
+ return 0 ;
3136
+ }
3137
+
3092
3138
static struct bt_hfp_ag_at_cmd_handler cmd_handlers [] = {
3093
3139
{"AT+BRSF" , bt_hfp_ag_brsf_handler }, {"AT+BAC" , bt_hfp_ag_bac_handler },
3094
3140
{"AT+CIND" , bt_hfp_ag_cind_handler }, {"AT+CMER" , bt_hfp_ag_cmer_handler },
@@ -3103,6 +3149,7 @@ static struct bt_hfp_ag_at_cmd_handler cmd_handlers[] = {
3103
3149
{"AT+BTRH" , bt_hfp_ag_btrh_handler }, {"AT+CCWA" , bt_hfp_ag_ccwa_handler },
3104
3150
{"AT+BVRA" , bt_hfp_ag_bvra_handler }, {"AT+BINP" , bt_hfp_ag_binp_handler },
3105
3151
{"AT+VTS" , bt_hfp_ag_vts_handler }, {"AT+CNUM" , bt_hfp_ag_cnum_handler },
3152
+ {"AT+BIEV" , bt_hfp_ag_biev_handler },
3106
3153
};
3107
3154
3108
3155
static void hfp_ag_connected (struct bt_rfcomm_dlc * dlc )
@@ -3492,6 +3539,17 @@ int bt_hfp_ag_connect(struct bt_conn *conn, struct bt_hfp_ag **ag, uint8_t chann
3492
3539
/* Set the supported features*/
3493
3540
_ag -> ag_features = BT_HFP_AG_SUPPORTED_FEATURES ;
3494
3541
3542
+ /* Support HF indicators */
3543
+ if (IS_ENABLED (CONFIG_BT_HFP_AG_HF_INDICATOR_ENH_SAFETY )) {
3544
+ _ag -> hf_indicators_of_ag |= BIT (HFP_HF_ENHANCED_SAFETY_IND );
3545
+ }
3546
+
3547
+ if (IS_ENABLED (CONFIG_BT_HFP_AG_HF_INDICATOR_BATTERY )) {
3548
+ _ag -> hf_indicators_of_ag |= BIT (HFP_HF_BATTERY_LEVEL_IND );
3549
+ }
3550
+
3551
+ _ag -> hf_indicators = _ag -> hf_indicators_of_ag ;
3552
+
3495
3553
/* If supported codec ids cannot be notified, disable codec negotiation. */
3496
3554
if (!(bt_ag && bt_ag -> codec )) {
3497
3555
_ag -> ag_features &= ~BT_HFP_AG_FEATURE_CODEC_NEG ;
@@ -4730,3 +4788,49 @@ int bt_hfp_ag_service_availability(struct bt_hfp_ag *ag, bool available)
4730
4788
4731
4789
return err ;
4732
4790
}
4791
+
4792
+ int bt_hfp_ag_hf_indicator (struct bt_hfp_ag * ag , enum hfp_ag_hf_indicators indicator , bool enable )
4793
+ {
4794
+ #if defined(CONFIG_BT_HFP_AG_HF_INDICATORS )
4795
+ int err ;
4796
+ uint32_t supported_indicators ;
4797
+
4798
+ LOG_DBG ("" );
4799
+
4800
+ if (ag == NULL ) {
4801
+ return - EINVAL ;
4802
+ }
4803
+
4804
+ hfp_ag_lock (ag );
4805
+ if (ag -> state != BT_HFP_CONNECTED ) {
4806
+ hfp_ag_unlock (ag );
4807
+ return - ENOTCONN ;
4808
+ }
4809
+
4810
+ supported_indicators = ag -> hf_indicators_of_ag & ag -> hf_indicators_of_hf ;
4811
+ hfp_ag_unlock (ag );
4812
+
4813
+ if (!(supported_indicators & BIT (indicator ))) {
4814
+ LOG_ERR ("Unsupported indicator %d" , indicator );
4815
+ return - ENOTSUP ;
4816
+ }
4817
+
4818
+ hfp_ag_lock (ag );
4819
+ if (enable ) {
4820
+ ag -> hf_indicators |= BIT (indicator );
4821
+ } else {
4822
+ ag -> hf_indicators &= ~BIT (indicator );
4823
+ }
4824
+ hfp_ag_unlock (ag );
4825
+
4826
+ err = hfp_ag_send_data (ag , NULL , NULL , "\r\n+BIND:%d,%d\r\n" ,
4827
+ indicator , enable ? 1 : 0 );
4828
+ if (err ) {
4829
+ LOG_ERR ("Fail to update registration status of indicator:(%d)" , err );
4830
+ }
4831
+
4832
+ return err ;
4833
+ #else
4834
+ return - ENOTSUP ;
4835
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
4836
+ }
0 commit comments