@@ -1642,6 +1642,66 @@ static int cnum_handle(struct at_client *hf_at)
1642
1642
return 0 ;
1643
1643
}
1644
1644
1645
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATORS )
1646
+ static int bind_handle (struct at_client * hf_at )
1647
+ {
1648
+ struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
1649
+ int err ;
1650
+ uint32_t index ;
1651
+ uint32_t value ;
1652
+ uint32_t ind = 0 ;
1653
+ uint32_t ind_enable = hf -> ind_enable ;
1654
+
1655
+ err = at_open_list (hf_at );
1656
+ if (!err ) {
1657
+ /* It is a list. */
1658
+ while (at_has_next_list (hf_at )) {
1659
+ err = at_get_number (hf_at , & index );
1660
+ if (err ) {
1661
+ LOG_INF ("Cannot get indicator" );
1662
+ goto failed ;
1663
+ }
1664
+
1665
+ ind |= BIT (index );
1666
+ }
1667
+
1668
+ if (at_close_list (hf_at ) < 0 ) {
1669
+ LOG_ERR ("Could not get close list" );
1670
+ goto failed ;
1671
+ }
1672
+
1673
+ hf -> ag_ind = ind ;
1674
+ return 0 ;
1675
+ }
1676
+
1677
+ err = at_get_number (hf_at , & index );
1678
+ if (err ) {
1679
+ LOG_INF ("Cannot get indicator" );
1680
+ goto failed ;
1681
+ }
1682
+
1683
+ err = at_get_number (hf_at , & value );
1684
+ if (err ) {
1685
+ LOG_INF ("Cannot get status" );
1686
+ goto failed ;
1687
+ }
1688
+
1689
+ if (!value ) {
1690
+ ind_enable &= ~BIT (index );
1691
+ } else {
1692
+ ind_enable |= BIT (index );
1693
+ }
1694
+
1695
+ hf -> ind_enable = ind_enable ;
1696
+ return 0 ;
1697
+
1698
+ failed :
1699
+ LOG_ERR ("Error on AT+BIND response" );
1700
+ hf_slc_error (hf_at );
1701
+ return - EINVAL ;
1702
+ }
1703
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
1704
+
1645
1705
static const struct unsolicited {
1646
1706
const char * cmd ;
1647
1707
enum at_cmd_type type ;
@@ -1672,6 +1732,9 @@ static const struct unsolicited {
1672
1732
{ "BVRA" , AT_CMD_TYPE_UNSOLICITED , bvra_handle },
1673
1733
#endif /* CONFIG_BT_HFP_HF_VOICE_RECG */
1674
1734
{ "CNUM" , AT_CMD_TYPE_UNSOLICITED , cnum_handle },
1735
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATORS )
1736
+ { "BIND" , AT_CMD_TYPE_UNSOLICITED , bind_handle },
1737
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
1675
1738
};
1676
1739
1677
1740
static const struct unsolicited * hfp_hf_unsol_lookup (struct at_client * hf_at )
@@ -1913,6 +1976,51 @@ static void slc_completed(struct at_client *hf_at)
1913
1976
}
1914
1977
}
1915
1978
1979
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATORS )
1980
+ static int send_at_bind_status (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1981
+ {
1982
+ return hfp_hf_send_cmd (hf , NULL , cb , "AT+BIND?" );
1983
+ }
1984
+
1985
+ static int send_at_bind_hf_supported (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1986
+ {
1987
+ char buffer [4 ];
1988
+ char * bind ;
1989
+
1990
+ hf -> hf_ind = 0 ;
1991
+
1992
+ bind = & buffer [0 ];
1993
+ if (IS_ENABLED (CONFIG_BT_HFP_HF_HF_INDICATOR_ENH_SAFETY )) {
1994
+ * bind = '0' + HFP_HF_ENHANCED_SAFETY_IND ;
1995
+ bind ++ ;
1996
+ * bind = ',' ;
1997
+ bind ++ ;
1998
+ hf -> hf_ind |= BIT (HFP_HF_ENHANCED_SAFETY_IND );
1999
+ }
2000
+
2001
+ if (IS_ENABLED (CONFIG_BT_HFP_HF_HF_INDICATOR_BATTERY )) {
2002
+ * bind = '0' + HFP_HF_BATTERY_LEVEL_IND ;
2003
+ bind ++ ;
2004
+ * bind = ',' ;
2005
+ bind ++ ;
2006
+ hf -> hf_ind |= BIT (HFP_HF_BATTERY_LEVEL_IND );
2007
+ }
2008
+
2009
+ if (bind <= & buffer [0 ]) {
2010
+ return - EINVAL ;
2011
+ }
2012
+
2013
+ bind -- ;
2014
+ * bind = '\0' ;
2015
+ return hfp_hf_send_cmd (hf , NULL , cb , "AT+BIND=%s" , buffer );
2016
+ }
2017
+
2018
+ static int send_at_bind_supported (struct bt_hfp_hf * hf , at_finish_cb_t cb )
2019
+ {
2020
+ return hfp_hf_send_cmd (hf , NULL , cb , "AT+BIND=?" );
2021
+ }
2022
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
2023
+
1916
2024
#if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1917
2025
static int send_at_chld_supported (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1918
2026
{
@@ -1989,6 +2097,11 @@ static struct slc_init
1989
2097
#if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1990
2098
{send_at_chld_supported , true, BT_HFP_AG_FEATURE_3WAY_CALL },
1991
2099
#endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
2100
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATORS )
2101
+ {send_at_bind_hf_supported , true, BT_HFP_AG_FEATURE_HF_IND },
2102
+ {send_at_bind_supported , true, BT_HFP_AG_FEATURE_HF_IND },
2103
+ {send_at_bind_status , true, BT_HFP_AG_FEATURE_HF_IND },
2104
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
1992
2105
};
1993
2106
1994
2107
static int slc_init_start (struct bt_hfp_hf * hf );
@@ -2512,6 +2625,115 @@ int bt_hfp_hf_indicator_status(struct bt_hfp_hf *hf, uint8_t status)
2512
2625
return err ;
2513
2626
}
2514
2627
2628
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATOR_ENH_SAFETY )
2629
+ static int biev_enh_safety_finish (struct at_client * hf_at ,
2630
+ enum at_result result , enum at_cme cme_err )
2631
+ {
2632
+ struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
2633
+
2634
+ LOG_DBG ("AT+BIEV (result %d) on %p" , result , hf );
2635
+
2636
+ return 0 ;
2637
+ }
2638
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATOR_ENH_SAFETY */
2639
+
2640
+ int bt_hfp_hf_enhanced_safety (struct bt_hfp_hf * hf , bool enable )
2641
+ {
2642
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATOR_ENH_SAFETY )
2643
+ int err ;
2644
+
2645
+ LOG_DBG ("" );
2646
+
2647
+ if (!hf ) {
2648
+ LOG_ERR ("No HF connection found" );
2649
+ return - ENOTCONN ;
2650
+ }
2651
+
2652
+ if (!atomic_test_bit (hf -> flags , BT_HFP_HF_FLAG_CONNECTED )) {
2653
+ LOG_ERR ("SLC is not established on %p" , hf );
2654
+ return - ENOTCONN ;
2655
+ }
2656
+
2657
+ if (!((hf -> hf_ind & BIT (HFP_HF_ENHANCED_SAFETY_IND )) &&
2658
+ (hf -> ag_ind & BIT (HFP_HF_ENHANCED_SAFETY_IND )))) {
2659
+ LOG_ERR ("The indicator is unsupported" );
2660
+ return - ENOTSUP ;
2661
+ }
2662
+
2663
+ if (!(hf -> ind_enable & BIT (HFP_HF_ENHANCED_SAFETY_IND ))) {
2664
+ LOG_ERR ("The indicator is disabled" );
2665
+ return - EINVAL ;
2666
+ }
2667
+
2668
+ err = hfp_hf_send_cmd (hf , NULL , biev_enh_safety_finish , "AT+BIEV=%d,%d" ,
2669
+ HFP_HF_ENHANCED_SAFETY_IND , enable ? 1 : 0 );
2670
+ if (err < 0 ) {
2671
+ LOG_ERR ("Fail to transfer enhanced safety value on %p" , hf );
2672
+ }
2673
+
2674
+ return err ;
2675
+ #else
2676
+ return - ENOTSUP ;
2677
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATOR_ENH_SAFETY */
2678
+ }
2679
+
2680
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATOR_BATTERY )
2681
+ static int biev_battery_finish (struct at_client * hf_at ,
2682
+ enum at_result result , enum at_cme cme_err )
2683
+ {
2684
+ struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
2685
+
2686
+ LOG_DBG ("AT+BIEV (result %d) on %p" , result , hf );
2687
+
2688
+ return 0 ;
2689
+ }
2690
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATOR_BATTERY */
2691
+
2692
+ int bt_hfp_hf_battery (struct bt_hfp_hf * hf , uint8_t level )
2693
+ {
2694
+ #if defined(CONFIG_BT_HFP_HF_HF_INDICATOR_BATTERY )
2695
+ int err ;
2696
+
2697
+ LOG_DBG ("" );
2698
+
2699
+ if (!hf ) {
2700
+ LOG_ERR ("No HF connection found" );
2701
+ return - ENOTCONN ;
2702
+ }
2703
+
2704
+ if (!atomic_test_bit (hf -> flags , BT_HFP_HF_FLAG_CONNECTED )) {
2705
+ LOG_ERR ("SLC is not established on %p" , hf );
2706
+ return - ENOTCONN ;
2707
+ }
2708
+
2709
+ if (!((hf -> hf_ind & BIT (HFP_HF_BATTERY_LEVEL_IND )) &&
2710
+ (hf -> ag_ind & BIT (HFP_HF_BATTERY_LEVEL_IND )))) {
2711
+ LOG_ERR ("The indicator is unsupported" );
2712
+ return - ENOTSUP ;
2713
+ }
2714
+
2715
+ if (!(hf -> ind_enable & BIT (HFP_HF_BATTERY_LEVEL_IND ))) {
2716
+ LOG_ERR ("The indicator is disabled" );
2717
+ return - EINVAL ;
2718
+ }
2719
+
2720
+ if (!IS_VALID_BATTERY_LEVEL (level )) {
2721
+ LOG_ERR ("Invalid battery level %d" , level );
2722
+ return - EINVAL ;
2723
+ }
2724
+
2725
+ err = hfp_hf_send_cmd (hf , NULL , biev_battery_finish , "AT+BIEV=%d,%d" ,
2726
+ HFP_HF_BATTERY_LEVEL_IND , level );
2727
+ if (err < 0 ) {
2728
+ LOG_ERR ("Fail to transfer remaining battery level on %p" , hf );
2729
+ }
2730
+
2731
+ return err ;
2732
+ #else
2733
+ return - ENOTSUP ;
2734
+ #endif /* CONFIG_BT_HFP_HF_HF_INDICATOR_BATTERY */
2735
+ }
2736
+
2515
2737
static int ata_finish (struct at_client * hf_at , enum at_result result ,
2516
2738
enum at_cme cme_err )
2517
2739
{
0 commit comments