@@ -1205,9 +1205,126 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
12051205 sizeof (cp ), & cp , HCI_CMD_TIMEOUT );
12061206}
12071207
1208+ static int
1209+ hci_set_ext_adv_params_sync (struct hci_dev * hdev , struct adv_info * adv ,
1210+ const struct hci_cp_le_set_ext_adv_params * cp ,
1211+ struct hci_rp_le_set_ext_adv_params * rp )
1212+ {
1213+ struct sk_buff * skb ;
1214+
1215+ skb = __hci_cmd_sync (hdev , HCI_OP_LE_SET_EXT_ADV_PARAMS , sizeof (* cp ),
1216+ cp , HCI_CMD_TIMEOUT );
1217+
1218+ /* If command return a status event, skb will be set to -ENODATA */
1219+ if (skb == ERR_PTR (- ENODATA ))
1220+ return 0 ;
1221+
1222+ if (IS_ERR (skb )) {
1223+ bt_dev_err (hdev , "Opcode 0x%4.4x failed: %ld" ,
1224+ HCI_OP_LE_SET_EXT_ADV_PARAMS , PTR_ERR (skb ));
1225+ return PTR_ERR (skb );
1226+ }
1227+
1228+ if (skb -> len != sizeof (* rp )) {
1229+ bt_dev_err (hdev , "Invalid response length for 0x%4.4x: %u" ,
1230+ HCI_OP_LE_SET_EXT_ADV_PARAMS , skb -> len );
1231+ kfree_skb (skb );
1232+ return - EIO ;
1233+ }
1234+
1235+ memcpy (rp , skb -> data , sizeof (* rp ));
1236+ kfree_skb (skb );
1237+
1238+ if (!rp -> status ) {
1239+ hdev -> adv_addr_type = cp -> own_addr_type ;
1240+ if (!cp -> handle ) {
1241+ /* Store in hdev for instance 0 */
1242+ hdev -> adv_tx_power = rp -> tx_power ;
1243+ } else if (adv ) {
1244+ adv -> tx_power = rp -> tx_power ;
1245+ }
1246+ }
1247+
1248+ return rp -> status ;
1249+ }
1250+
1251+ static int hci_set_ext_adv_data_sync (struct hci_dev * hdev , u8 instance )
1252+ {
1253+ DEFINE_FLEX (struct hci_cp_le_set_ext_adv_data , pdu , data , length ,
1254+ HCI_MAX_EXT_AD_LENGTH );
1255+ u8 len ;
1256+ struct adv_info * adv = NULL ;
1257+ int err ;
1258+
1259+ if (instance ) {
1260+ adv = hci_find_adv_instance (hdev , instance );
1261+ if (!adv || !adv -> adv_data_changed )
1262+ return 0 ;
1263+ }
1264+
1265+ len = eir_create_adv_data (hdev , instance , pdu -> data ,
1266+ HCI_MAX_EXT_AD_LENGTH );
1267+
1268+ pdu -> length = len ;
1269+ pdu -> handle = adv ? adv -> handle : instance ;
1270+ pdu -> operation = LE_SET_ADV_DATA_OP_COMPLETE ;
1271+ pdu -> frag_pref = LE_SET_ADV_DATA_NO_FRAG ;
1272+
1273+ err = __hci_cmd_sync_status (hdev , HCI_OP_LE_SET_EXT_ADV_DATA ,
1274+ struct_size (pdu , data , len ), pdu ,
1275+ HCI_CMD_TIMEOUT );
1276+ if (err )
1277+ return err ;
1278+
1279+ /* Update data if the command succeed */
1280+ if (adv ) {
1281+ adv -> adv_data_changed = false;
1282+ } else {
1283+ memcpy (hdev -> adv_data , pdu -> data , len );
1284+ hdev -> adv_data_len = len ;
1285+ }
1286+
1287+ return 0 ;
1288+ }
1289+
1290+ static int hci_set_adv_data_sync (struct hci_dev * hdev , u8 instance )
1291+ {
1292+ struct hci_cp_le_set_adv_data cp ;
1293+ u8 len ;
1294+
1295+ memset (& cp , 0 , sizeof (cp ));
1296+
1297+ len = eir_create_adv_data (hdev , instance , cp .data , sizeof (cp .data ));
1298+
1299+ /* There's nothing to do if the data hasn't changed */
1300+ if (hdev -> adv_data_len == len &&
1301+ memcmp (cp .data , hdev -> adv_data , len ) == 0 )
1302+ return 0 ;
1303+
1304+ memcpy (hdev -> adv_data , cp .data , sizeof (cp .data ));
1305+ hdev -> adv_data_len = len ;
1306+
1307+ cp .length = len ;
1308+
1309+ return __hci_cmd_sync_status (hdev , HCI_OP_LE_SET_ADV_DATA ,
1310+ sizeof (cp ), & cp , HCI_CMD_TIMEOUT );
1311+ }
1312+
1313+ int hci_update_adv_data_sync (struct hci_dev * hdev , u8 instance )
1314+ {
1315+ if (!hci_dev_test_flag (hdev , HCI_LE_ENABLED ))
1316+ return 0 ;
1317+
1318+ if (ext_adv_capable (hdev ))
1319+ return hci_set_ext_adv_data_sync (hdev , instance );
1320+
1321+ return hci_set_adv_data_sync (hdev , instance );
1322+ }
1323+
12081324int hci_setup_ext_adv_instance_sync (struct hci_dev * hdev , u8 instance )
12091325{
12101326 struct hci_cp_le_set_ext_adv_params cp ;
1327+ struct hci_rp_le_set_ext_adv_params rp ;
12111328 bool connectable ;
12121329 u32 flags ;
12131330 bdaddr_t random_addr ;
@@ -1316,8 +1433,12 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
13161433 cp .secondary_phy = HCI_ADV_PHY_1M ;
13171434 }
13181435
1319- err = __hci_cmd_sync_status (hdev , HCI_OP_LE_SET_EXT_ADV_PARAMS ,
1320- sizeof (cp ), & cp , HCI_CMD_TIMEOUT );
1436+ err = hci_set_ext_adv_params_sync (hdev , adv , & cp , & rp );
1437+ if (err )
1438+ return err ;
1439+
1440+ /* Update adv data as tx power is known now */
1441+ err = hci_set_ext_adv_data_sync (hdev , cp .handle );
13211442 if (err )
13221443 return err ;
13231444
@@ -1822,79 +1943,6 @@ int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason)
18221943 sizeof (cp ), & cp , HCI_CMD_TIMEOUT );
18231944}
18241945
1825- static int hci_set_ext_adv_data_sync (struct hci_dev * hdev , u8 instance )
1826- {
1827- DEFINE_FLEX (struct hci_cp_le_set_ext_adv_data , pdu , data , length ,
1828- HCI_MAX_EXT_AD_LENGTH );
1829- u8 len ;
1830- struct adv_info * adv = NULL ;
1831- int err ;
1832-
1833- if (instance ) {
1834- adv = hci_find_adv_instance (hdev , instance );
1835- if (!adv || !adv -> adv_data_changed )
1836- return 0 ;
1837- }
1838-
1839- len = eir_create_adv_data (hdev , instance , pdu -> data ,
1840- HCI_MAX_EXT_AD_LENGTH );
1841-
1842- pdu -> length = len ;
1843- pdu -> handle = adv ? adv -> handle : instance ;
1844- pdu -> operation = LE_SET_ADV_DATA_OP_COMPLETE ;
1845- pdu -> frag_pref = LE_SET_ADV_DATA_NO_FRAG ;
1846-
1847- err = __hci_cmd_sync_status (hdev , HCI_OP_LE_SET_EXT_ADV_DATA ,
1848- struct_size (pdu , data , len ), pdu ,
1849- HCI_CMD_TIMEOUT );
1850- if (err )
1851- return err ;
1852-
1853- /* Update data if the command succeed */
1854- if (adv ) {
1855- adv -> adv_data_changed = false;
1856- } else {
1857- memcpy (hdev -> adv_data , pdu -> data , len );
1858- hdev -> adv_data_len = len ;
1859- }
1860-
1861- return 0 ;
1862- }
1863-
1864- static int hci_set_adv_data_sync (struct hci_dev * hdev , u8 instance )
1865- {
1866- struct hci_cp_le_set_adv_data cp ;
1867- u8 len ;
1868-
1869- memset (& cp , 0 , sizeof (cp ));
1870-
1871- len = eir_create_adv_data (hdev , instance , cp .data , sizeof (cp .data ));
1872-
1873- /* There's nothing to do if the data hasn't changed */
1874- if (hdev -> adv_data_len == len &&
1875- memcmp (cp .data , hdev -> adv_data , len ) == 0 )
1876- return 0 ;
1877-
1878- memcpy (hdev -> adv_data , cp .data , sizeof (cp .data ));
1879- hdev -> adv_data_len = len ;
1880-
1881- cp .length = len ;
1882-
1883- return __hci_cmd_sync_status (hdev , HCI_OP_LE_SET_ADV_DATA ,
1884- sizeof (cp ), & cp , HCI_CMD_TIMEOUT );
1885- }
1886-
1887- int hci_update_adv_data_sync (struct hci_dev * hdev , u8 instance )
1888- {
1889- if (!hci_dev_test_flag (hdev , HCI_LE_ENABLED ))
1890- return 0 ;
1891-
1892- if (ext_adv_capable (hdev ))
1893- return hci_set_ext_adv_data_sync (hdev , instance );
1894-
1895- return hci_set_adv_data_sync (hdev , instance );
1896- }
1897-
18981946int hci_schedule_adv_instance_sync (struct hci_dev * hdev , u8 instance ,
18991947 bool force )
19001948{
@@ -6273,6 +6321,7 @@ static int hci_le_ext_directed_advertising_sync(struct hci_dev *hdev,
62736321 struct hci_conn * conn )
62746322{
62756323 struct hci_cp_le_set_ext_adv_params cp ;
6324+ struct hci_rp_le_set_ext_adv_params rp ;
62766325 int err ;
62776326 bdaddr_t random_addr ;
62786327 u8 own_addr_type ;
@@ -6314,8 +6363,12 @@ static int hci_le_ext_directed_advertising_sync(struct hci_dev *hdev,
63146363 if (err )
63156364 return err ;
63166365
6317- err = __hci_cmd_sync_status (hdev , HCI_OP_LE_SET_EXT_ADV_PARAMS ,
6318- sizeof (cp ), & cp , HCI_CMD_TIMEOUT );
6366+ err = hci_set_ext_adv_params_sync (hdev , NULL , & cp , & rp );
6367+ if (err )
6368+ return err ;
6369+
6370+ /* Update adv data as tx power is known now */
6371+ err = hci_set_ext_adv_data_sync (hdev , cp .handle );
63196372 if (err )
63206373 return err ;
63216374
0 commit comments