• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <string.h>
21 #include "securec.h"
22 #include "nimble/hci_common.h"
23 #include "host/ble_hs_hci.h"
24 #include "ble_hs_priv.h"
25 
ble_hs_hci_util_handle_pb_bc_join(uint16_t handle,uint8_t pb,uint8_t bc)26 uint16_t ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc)
27 {
28     BLE_HS_DBG_ASSERT(handle <= 0x0fff);
29     BLE_HS_DBG_ASSERT(pb <= 0x03);
30     BLE_HS_DBG_ASSERT(bc <= 0x03);
31     return (handle  << 0)   |
32            (pb      << 12)  | // 12:byte alignment
33            (bc      << 14);   // 14:byte alignment
34 }
35 
ble_hs_hci_util_read_adv_tx_pwr(int8_t * out_tx_pwr)36 int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr)
37 {
38     struct ble_hci_le_rd_adv_chan_txpwr_rp rsp;
39     int rc;
40     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
41                                       BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR),
42                            NULL, 0, &rsp, sizeof(rsp));
43     if (rc != 0) {
44         return rc;
45     }
46 
47     *out_tx_pwr = rsp.power_level;
48     if (*out_tx_pwr < BLE_HCI_ADV_CHAN_TXPWR_MIN ||
49             *out_tx_pwr > BLE_HCI_ADV_CHAN_TXPWR_MAX) {
50         BLE_HS_LOG(WARN, "advertiser txpwr out of range\n");
51     }
52 
53     return 0;
54 }
55 
ble_hs_hci_util_rand(void * dst,int len)56 int ble_hs_hci_util_rand(void *dst, int len)
57 {
58     int len_tmp = len;
59     struct ble_hci_le_rand_rp rsp;
60     uint8_t *u8ptr;
61 
62     u8ptr = dst;
63 
64     while (len_tmp > 0) {
65         int rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RAND), NULL, 0, &rsp, sizeof(rsp));
66         if (rc != 0) {
67             return rc;
68         }
69 
70         int chunk_sz = min(len_tmp, sizeof(rsp));
71         memcpy_s(u8ptr, sizeof(u8ptr), &rsp.random_number, chunk_sz);
72         len_tmp -= chunk_sz;
73         u8ptr += chunk_sz;
74     }
75 
76     return 0;
77 }
78 
ble_hs_hci_util_read_rssi(uint16_t conn_handle,int8_t * out_rssi)79 int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi)
80 {
81     struct ble_hci_rd_rssi_cp cmd;
82     struct ble_hci_rd_rssi_rp rsp;
83     int rc;
84     cmd.handle = htole16(conn_handle);
85     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_STATUS_PARAMS, BLE_HCI_OCF_RD_RSSI), &cmd, sizeof(cmd),
86                            &rsp, sizeof(rsp));
87     if (rc != 0) {
88         return rc;
89     }
90 
91     if (le16toh(rsp.handle) != conn_handle) {
92         return BLE_HS_ECONTROLLER;
93     }
94 
95     *out_rssi = rsp.rssi;
96     return 0;
97 }
98 
ble_hs_hci_util_set_random_addr(const uint8_t * addr)99 int ble_hs_hci_util_set_random_addr(const uint8_t *addr)
100 {
101     struct ble_hci_le_set_rand_addr_cp cmd;
102     memcpy_s(cmd.addr, sizeof(cmd.addr), addr, BLE_DEV_ADDR_LEN);
103     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
104                                         BLE_HCI_OCF_LE_SET_RAND_ADDR),
105                              &cmd, sizeof(cmd), NULL, 0);
106 }
107 
ble_hs_hci_util_set_data_len(uint16_t conn_handle,uint16_t tx_octets,uint16_t tx_time)108 int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time)
109 {
110     struct ble_hci_le_set_data_len_cp cmd;
111     struct ble_hci_le_set_data_len_rp rsp;
112     int rc;
113 
114     if (tx_octets < BLE_HCI_SET_DATALEN_TX_OCTETS_MIN ||
115             tx_octets > BLE_HCI_SET_DATALEN_TX_OCTETS_MAX) {
116         return BLE_HS_EINVAL;
117     }
118 
119     if (tx_time < BLE_HCI_SET_DATALEN_TX_TIME_MIN ||
120             tx_time > BLE_HCI_SET_DATALEN_TX_TIME_MAX) {
121         return BLE_HS_EINVAL;
122     }
123 
124     cmd.conn_handle = htole16(conn_handle);
125     cmd.tx_octets = htole16(tx_octets);
126     cmd.tx_time = htole16(tx_time);
127     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
128                                       BLE_HCI_OCF_LE_SET_DATA_LEN),
129                            &cmd, sizeof(cmd), NULL, 0);
130     if (rc != 0) {
131         return rc;
132     }
133 
134     if (le16toh(rsp.conn_handle) != conn_handle) {
135         return BLE_HS_ECONTROLLER;
136     }
137 
138     return 0;
139 }
140 
ble_hs_hci_util_data_hdr_strip(struct os_mbuf * om,struct hci_data_hdr * out_hdr)141 int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr)
142 {
143     int rc;
144     rc = os_mbuf_copydata(om, 0, BLE_HCI_DATA_HDR_SZ, out_hdr);
145     if (rc != 0) {
146         return BLE_HS_ECONTROLLER;
147     }
148 
149     /* Strip HCI ACL data header from the front of the packet. */
150     os_mbuf_adj(om, BLE_HCI_DATA_HDR_SZ);
151     out_hdr->hdh_handle_pb_bc = get_le16(&out_hdr->hdh_handle_pb_bc);
152     out_hdr->hdh_len = get_le16(&out_hdr->hdh_len);
153     return 0;
154 }
155 
ble_hs_hci_read_chan_map(uint16_t conn_handle,uint8_t * out_chan_map)156 int ble_hs_hci_read_chan_map(uint16_t conn_handle, uint8_t *out_chan_map)
157 {
158     struct ble_hci_le_rd_chan_map_cp cmd;
159     struct ble_hci_le_rd_chan_map_rp rsp;
160     int rc;
161     cmd.conn_handle = htole16(conn_handle);
162     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
163                                       BLE_HCI_OCF_LE_RD_CHAN_MAP),
164                            &cmd, sizeof(cmd), &rsp, sizeof(rsp));
165     if (rc != 0) {
166         return rc;
167     }
168 
169     if (le16toh(rsp.conn_handle) != conn_handle) {
170         return BLE_HS_ECONTROLLER;
171     }
172 
173     memcpy_s(out_chan_map, sizeof(out_chan_map), rsp.chan_map, 5); // 5:size
174     return 0;
175 }
176 
ble_hs_hci_set_chan_class(const uint8_t * chan_map)177 int ble_hs_hci_set_chan_class(const uint8_t *chan_map)
178 {
179     struct ble_hci_le_set_host_chan_class_cp cmd;
180     memcpy_s(cmd.chan_map, sizeof(cmd.chan_map), chan_map, sizeof(cmd.chan_map));
181     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
182                                         BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS),
183                              &cmd, sizeof(cmd), NULL, 0);
184 }