@@ -1789,51 +1789,6 @@ static int at_vgs_finish(struct at_client *hf_at, enum at_result result,
1789
1789
}
1790
1790
#endif /* CONFIG_BT_HFP_HF_VOLUME */
1791
1791
1792
- #if defined(CONFIG_BT_HFP_HF_CODEC_NEG )
1793
- static void get_codec_ids (struct bt_hfp_hf * hf , char * buffer , size_t buffer_len )
1794
- {
1795
- size_t len = 0 ;
1796
- uint8_t ids = hf -> hf_codec_ids ;
1797
- int index = 0 ;
1798
-
1799
- while (ids && (len < (buffer_len - 2 ))) {
1800
- if (ids & 0x01 ) {
1801
- buffer [len ++ ] = index + '0' ;
1802
- buffer [len ++ ] = ',' ;
1803
- }
1804
- index ++ ;
1805
- ids = ids >> 1 ;
1806
- }
1807
-
1808
- if (len > 0 ) {
1809
- len -- ;
1810
- }
1811
-
1812
- buffer [len ] = '\0' ;
1813
- }
1814
-
1815
- static int send_at_bac (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1816
- {
1817
- if (hf -> ag_features & BT_HFP_AG_FEATURE_CODEC_NEG ) {
1818
- char ids [sizeof (hf -> hf_codec_ids )* 2 * 8 + 1 ];
1819
- get_codec_ids (hf , & ids [0 ], ARRAY_SIZE (ids ));
1820
- return hfp_hf_send_cmd (hf , NULL , cb , "AT+BAC=%s" , ids );
1821
- }
1822
-
1823
- return - ENOTSUP ;
1824
- }
1825
-
1826
- static int at_bac_finish (struct at_client * hf_at , enum at_result result ,
1827
- enum at_cme cme_err )
1828
- {
1829
- struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
1830
-
1831
- LOG_DBG ("BAC set (result %d) on %p" , result , hf );
1832
-
1833
- return 0 ;
1834
- }
1835
- #endif /* CONFIG_BT_HFP_HF_CODEC_NEG */
1836
-
1837
1792
#if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1838
1793
static int send_at_ccwa (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1839
1794
{
@@ -1876,9 +1831,6 @@ static struct at_cmd_init
1876
1831
#if defined(CONFIG_BT_HFP_HF_CLI )
1877
1832
{send_at_clip , at_clip_finish , false},
1878
1833
#endif /* CONFIG_BT_HFP_HF_CLI */
1879
- #if defined(CONFIG_BT_HFP_HF_CODEC_NEG )
1880
- {send_at_bac , at_bac_finish , false},
1881
- #endif /* CONFIG_BT_HFP_HF_CODEC_NEG */
1882
1834
#if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1883
1835
{send_at_ccwa , at_ccwa_finish , false},
1884
1836
#endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
@@ -1962,114 +1914,152 @@ static void slc_completed(struct at_client *hf_at)
1962
1914
}
1963
1915
1964
1916
#if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1965
- int chld_finish (struct at_client * hf_at , enum at_result result ,
1966
- enum at_cme cme_err )
1917
+ static int send_at_chld_supported (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1967
1918
{
1968
- if (result != AT_RESULT_OK ) {
1969
- LOG_ERR ("SLC Connection ERROR in response" );
1970
- hf_slc_error (hf_at );
1971
- return - EINVAL ;
1972
- }
1919
+ return hfp_hf_send_cmd (hf , NULL , cb , "AT+CHLD=?" );
1920
+ }
1921
+ #endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
1973
1922
1974
- slc_completed (hf_at );
1923
+ static int send_at_cmer (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1924
+ {
1925
+ at_register_unsolicited (& hf -> at , unsolicited_cb );
1926
+ return hfp_hf_send_cmd (hf , NULL , cb , "AT+CMER=3,0,0,1" );
1927
+ }
1975
1928
1976
- return 0 ;
1929
+ static int send_at_cind_status (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1930
+ {
1931
+ return hfp_hf_send_cmd (hf , cind_status_resp , cb , "AT+CIND?" );
1977
1932
}
1978
- #endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
1979
1933
1980
- int cmer_finish (struct at_client * hf_at , enum at_result result ,
1981
- enum at_cme cme_err )
1934
+ static int send_at_cind_supported (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1982
1935
{
1983
- #if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1984
- struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
1985
- int err ;
1986
- #endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
1936
+ return hfp_hf_send_cmd (hf , cind_resp , cb , "AT+CIND=?" );
1937
+ }
1987
1938
1988
- if (result != AT_RESULT_OK ) {
1989
- LOG_ERR ("SLC Connection ERROR in response" );
1990
- hf_slc_error (hf_at );
1991
- return - EINVAL ;
1992
- }
1939
+ #if defined(CONFIG_BT_HFP_HF_CODEC_NEG )
1940
+ static void get_codec_ids (struct bt_hfp_hf * hf , char * buffer , size_t buffer_len )
1941
+ {
1942
+ size_t len = 0 ;
1943
+ uint8_t ids = hf -> hf_codec_ids ;
1944
+ int index = 0 ;
1993
1945
1994
- #if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1995
- if ((hf -> ag_features & BT_HFP_AG_FEATURE_3WAY_CALL ) &&
1996
- (hf -> hf_features & BT_HFP_HF_FEATURE_3WAY_CALL )) {
1997
- err = hfp_hf_send_cmd (hf , NULL , chld_finish , "AT+CHLD=?" );
1998
- if (err < 0 ) {
1999
- hf_slc_error (hf_at );
1946
+ while (ids && (len < (buffer_len - 2 ))) {
1947
+ if (ids & 0x01 ) {
1948
+ buffer [len ++ ] = index + '0' ;
1949
+ buffer [len ++ ] = ',' ;
2000
1950
}
2001
- return err ;
1951
+ index ++ ;
1952
+ ids = ids >> 1 ;
2002
1953
}
2003
- #endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
2004
1954
2005
- slc_completed (hf_at );
1955
+ if (len > 0 ) {
1956
+ len -- ;
1957
+ }
2006
1958
2007
- return 0 ;
1959
+ buffer [ len ] = '\0' ;
2008
1960
}
2009
1961
2010
- int cind_status_finish (struct at_client * hf_at , enum at_result result ,
2011
- enum at_cme cme_err )
1962
+ static int send_at_bac (struct bt_hfp_hf * hf , at_finish_cb_t cb )
2012
1963
{
2013
- struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
2014
- int err ;
2015
-
2016
- if (result != AT_RESULT_OK ) {
2017
- LOG_ERR ("SLC Connection ERROR in response" );
2018
- hf_slc_error (hf_at );
2019
- return - EINVAL ;
2020
- }
1964
+ char ids [sizeof (hf -> hf_codec_ids )* 2 * 8 + 1 ];
2021
1965
2022
- at_register_unsolicited (hf_at , unsolicited_cb );
2023
- err = hfp_hf_send_cmd (hf , NULL , cmer_finish , "AT+CMER=3,0,0,1" );
2024
- if (err < 0 ) {
2025
- hf_slc_error (hf_at );
2026
- return err ;
2027
- }
1966
+ get_codec_ids (hf , & ids [0 ], ARRAY_SIZE (ids ));
1967
+ return hfp_hf_send_cmd (hf , NULL , cb , "AT+BAC=%s" , ids );
1968
+ }
1969
+ #endif /* CONFIG_BT_HFP_HF_CODEC_NEG */
2028
1970
2029
- return 0 ;
1971
+ static int send_at_brsf (struct bt_hfp_hf * hf , at_finish_cb_t cb )
1972
+ {
1973
+ return hfp_hf_send_cmd (hf , brsf_resp , cb , "AT+BRSF=%u" , hf -> hf_features );
2030
1974
}
2031
1975
2032
- int cind_finish (struct at_client * hf_at , enum at_result result ,
2033
- enum at_cme cme_err )
1976
+ static struct slc_init
1977
+ {
1978
+ at_send_t send ;
1979
+ bool disconnect ; /* Disconnect if command failed. */
1980
+ uint32_t ag_feature_mask ; /* AG feature mask */
1981
+ } slc_init_list [] = {
1982
+ {send_at_brsf , true, 0 },
1983
+ #if defined(CONFIG_BT_HFP_HF_CODEC_NEG )
1984
+ {send_at_bac , true, BT_HFP_AG_FEATURE_CODEC_NEG },
1985
+ #endif /* CONFIG_BT_HFP_HF_CODEC_NEG */
1986
+ {send_at_cind_supported , true, 0 },
1987
+ {send_at_cind_status , true, 0 },
1988
+ {send_at_cmer , true, 0 },
1989
+ #if defined(CONFIG_BT_HFP_HF_3WAY_CALL )
1990
+ {send_at_chld_supported , true, BT_HFP_AG_FEATURE_3WAY_CALL },
1991
+ #endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
1992
+ };
1993
+
1994
+ static int slc_init_start (struct bt_hfp_hf * hf );
1995
+
1996
+ static int slc_init_finish (struct at_client * hf_at , enum at_result result ,
1997
+ enum at_cme cme_err )
2034
1998
{
2035
1999
struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
2036
- int err ;
2037
2000
2038
2001
if (result != AT_RESULT_OK ) {
2039
- LOG_ERR ("SLC Connection ERROR in response" );
2040
- hf_slc_error (hf_at );
2041
- return - EINVAL ;
2002
+ LOG_WRN ("It is ERROR response of AT command %d." , hf -> cmd_init_seq );
2003
+ if (slc_init_list [hf -> cmd_init_seq ].disconnect ) {
2004
+ hf_slc_error (& hf -> at );
2005
+ return 0 ;
2006
+ }
2042
2007
}
2043
2008
2044
- err = hfp_hf_send_cmd (hf , cind_status_resp , cind_status_finish ,
2045
- "AT+CIND?" );
2046
- if (err < 0 ) {
2047
- hf_slc_error (hf_at );
2048
- return err ;
2009
+ if (ARRAY_SIZE (slc_init_list ) <= hf -> cmd_init_seq ) {
2010
+ LOG_ERR ("Invalid indicator (%d>=%d)" , hf -> cmd_init_seq ,
2011
+ ARRAY_SIZE (slc_init_list ));
2049
2012
}
2050
2013
2014
+ /* Goto next AT command */
2015
+ hf -> cmd_init_seq ++ ;
2016
+ (void )slc_init_start (hf );
2051
2017
return 0 ;
2052
2018
}
2053
2019
2054
- int brsf_finish (struct at_client * hf_at , enum at_result result ,
2055
- enum at_cme cme_err )
2020
+ static int slc_init_start (struct bt_hfp_hf * hf )
2056
2021
{
2057
- struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
2058
- int err ;
2022
+ at_send_t send ;
2023
+ uint32_t feture_mask ;
2024
+ int err = - EINVAL ;
2059
2025
2060
- if (result != AT_RESULT_OK ) {
2061
- LOG_ERR ("SLC Connection ERROR in response" );
2062
- hf_slc_error (hf_at );
2063
- return - EINVAL ;
2026
+ while (ARRAY_SIZE (slc_init_list ) > hf -> cmd_init_seq ) {
2027
+ LOG_DBG ("Fetch AT command (%d)" , hf -> cmd_init_seq );
2028
+ feture_mask = slc_init_list [hf -> cmd_init_seq ].ag_feature_mask ;
2029
+ if (feture_mask && (!(feture_mask & hf -> ag_features ))) {
2030
+ /* The feature is not supported by AG. Skip the step. */
2031
+ LOG_INF ("Skip SLC init step %d" , hf -> cmd_init_seq );
2032
+ hf -> cmd_init_seq ++ ;
2033
+ continue ;
2034
+ }
2035
+
2036
+ send = slc_init_list [hf -> cmd_init_seq ].send ;
2037
+ if (send ) {
2038
+ LOG_DBG ("Send AT command" );
2039
+ err = send (hf , slc_init_finish );
2040
+ } else {
2041
+ LOG_WRN ("Invalid send func of AT command" );
2042
+ }
2043
+
2044
+ if (!err ) {
2045
+ break ;
2046
+ }
2047
+
2048
+ LOG_WRN ("AT command sending failed" );
2049
+ if (slc_init_list [hf -> cmd_init_seq ].disconnect ) {
2050
+ hfp_hf_send_failed (hf );
2051
+ break ;
2052
+ }
2053
+ /* Goto next AT command */
2054
+ LOG_WRN ("Send next AT command" );
2055
+ hf -> cmd_init_seq ++ ;
2064
2056
}
2065
2057
2066
- err = hfp_hf_send_cmd (hf , cind_resp , cind_finish , "AT+CIND=?" );
2067
- if (err < 0 ) {
2068
- hf_slc_error (hf_at );
2069
- return err ;
2058
+ if (ARRAY_SIZE (slc_init_list ) <= hf -> cmd_init_seq ) {
2059
+ slc_completed (& hf -> at );
2070
2060
}
2071
2061
2072
- return 0 ;
2062
+ return err ;
2073
2063
}
2074
2064
2075
2065
int hf_slc_establish (struct bt_hfp_hf * hf )
@@ -2078,8 +2068,8 @@ int hf_slc_establish(struct bt_hfp_hf *hf)
2078
2068
2079
2069
LOG_DBG ("" );
2080
2070
2081
- err = hfp_hf_send_cmd ( hf , brsf_resp , brsf_finish , "AT+BRSF=%u" ,
2082
- hf -> hf_features );
2071
+ hf -> cmd_init_seq = 0 ;
2072
+ err = slc_init_start ( hf );
2083
2073
if (err < 0 ) {
2084
2074
hf_slc_error (& hf -> at );
2085
2075
return err ;
0 commit comments