1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "bt_c_adapter_socket"
17 #endif
18 
19 #include "ohos_bt_socket.h"
20 
21 #include <iostream>
22 #include <cstring>
23 #include <vector>
24 
25 #include "ohos_bt_adapter_utils.h"
26 #include "bluetooth_def.h"
27 #include "bluetooth_gatt_client.h"
28 #include "bluetooth_socket.h"
29 #include "bluetooth_host.h"
30 #include "bluetooth_log.h"
31 #include "bluetooth_utils.h"
32 #include "bluetooth_object_map.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 using namespace std;
39 
40 namespace OHOS {
41 namespace Bluetooth {
42 
43 const int MAX_OBJECT_NUM = 10000;
44 
45 static BluetoothObjectMap<std::shared_ptr<ServerSocket>, MAX_OBJECT_NUM> g_serverMap;
46 static BluetoothObjectMap<std::shared_ptr<ClientSocket>, MAX_OBJECT_NUM> g_clientMap;
47 
48 class BluetoothConnectionObserverWapper : public BluetoothConnectionObserver {
49 public:
BluetoothConnectionObserverWapper(BtSocketConnectionCallback & callback)50     explicit BluetoothConnectionObserverWapper(BtSocketConnectionCallback &callback)
51     {
52         socektConnectCallback = callback;
53     }
54 
55     __attribute__((no_sanitize("cfi")))
OnConnectionStateChanged(const CallbackConnectParam & param)56     void OnConnectionStateChanged(const CallbackConnectParam &param) override
57     {
58         if (socektConnectCallback.connStateCb == nullptr && socektConnectCallback.bleConnStateCb == nullptr) {
59             HILOGE("callback is null");
60             return;
61         }
62         BdAddr addr;
63         GetAddrFromString(param.addr.GetDeviceAddr(), addr.addr);
64         BtUuid btUuid;
65         string strUuid = param.uuid.ToString();
66         btUuid.uuid = (char *)strUuid.c_str();
67         btUuid.uuidLen = strUuid.size();
68         if (param.type == OHOS_SOCKET_SPP_RFCOMM && socektConnectCallback.connStateCb != nullptr) {
69             socektConnectCallback.connStateCb(&addr, btUuid, param.status, param.result);
70         }
71         if (param.type == OHOS_SOCKET_L2CAP_LE && socektConnectCallback.bleConnStateCb != nullptr) {
72             socektConnectCallback.bleConnStateCb(&addr, param.psm, param.status, param.result);
73         }
74     }
75 
76     BtSocketConnectionCallback socektConnectCallback;
77 };
78 
79 static std::map<int, std::shared_ptr<BluetoothConnectionObserverWapper>> g_clientCbMap;
80 static std::mutex g_clientCbMapMutex;
81 using ClientCbIterator = std::map<int, std::shared_ptr<BluetoothConnectionObserverWapper>>::iterator;
82 
GetSocketUuidPara(const BluetoothCreateSocketPara * socketPara,UUID & serverUuid)83 static bool GetSocketUuidPara(const BluetoothCreateSocketPara *socketPara, UUID &serverUuid)
84 {
85     if (socketPara->socketType == OHOS_SOCKET_SPP_RFCOMM) {
86         if (socketPara->uuid.uuid == nullptr || strlen(socketPara->uuid.uuid) != socketPara->uuid.uuidLen) {
87             HILOGE("param uuid invalid!");
88             return false;
89         }
90         string tmpUuid(socketPara->uuid.uuid);
91         if (!IsValidUuid(tmpUuid)) {
92             HILOGE("match the UUID faild.");
93             return false;
94         }
95         serverUuid = UUID::FromString(tmpUuid);
96     } else if (socketPara->socketType == OHOS_SOCKET_L2CAP_LE) {
97         serverUuid = UUID::RandomUUID();
98     } else {
99         HILOGE("param socketType invalid. socketType: %{public}d", socketPara->socketType);
100         return false;
101     }
102     return true;
103 }
104 
105 /**
106  * @brief Creates an server listening socket based on the service record.
107  *
108  * @param socketPara The parameters to create a server socket.
109  * @param name The service's name.
110  * @return Returns a server ID, if create fail return {@link BT_SOCKET_INVALID_ID}.
111  */
SocketServerCreate(const BluetoothCreateSocketPara * socketPara,const char * name)112 int SocketServerCreate(const BluetoothCreateSocketPara *socketPara, const char *name)
113 {
114     HILOGD("SocketServerCreate start!");
115     if (socketPara == nullptr || name == nullptr) {
116         HILOGE("socketPara or name is null.");
117         return BT_SOCKET_INVALID_ID;
118     }
119 
120     if (socketPara->socketType == OHOS_SOCKET_L2CAP_LE) {
121         CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_SOCKET_INVALID_ID, "BLE is not TURN_ON");
122     } else {
123         CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_SOCKET_INVALID_ID, "BR is not TURN_ON");
124     }
125 
126     UUID serverUuid;
127     if (!GetSocketUuidPara(socketPara, serverUuid)) {
128         return BT_SOCKET_INVALID_ID;
129     }
130 
131     string serverName(name);
132     std::shared_ptr<ServerSocket> server = std::make_shared<ServerSocket>(serverName, serverUuid,
133         BtSocketType(socketPara->socketType), socketPara->isEncrypt);
134     int result = server->Listen();
135     if (result != BT_NO_ERROR) {
136         HILOGE("SocketServerCreate fail, result: %{public}d", result);
137         server->Close();
138         HILOGE("SocketServerCreate closed.");
139         return BT_SOCKET_INVALID_ID;
140     }
141     int serverId = g_serverMap.AddObject(server);
142     HILOGI("success, serverId: %{public}d, socketType: %{public}d, isEncrypt: %{public}d", serverId,
143         socketPara->socketType, socketPara->isEncrypt);
144     return serverId;
145 }
146 
147 /**
148  * @brief Waits for a remote device to connect to this server socket.
149  *
150  * This method return a client ID indicates a client socket
151  * can be used to read data from and write data to remote device.
152  * This method will block until a connection is established.
153  *
154  * @param serverId The relative ID used to identify the current server socket, obtain the value by calling
155  * {@link SocketServerCreate}.
156  * @return Returns a client ID, if accept fail return {@link BT_SOCKET_INVALID_ID}.
157  */
SocketServerAccept(int serverId)158 int SocketServerAccept(int serverId)
159 {
160     HILOGI("SocketServerAccept start, serverId: %{public}d", serverId);
161     std::shared_ptr<ServerSocket> server = g_serverMap.GetObject(serverId);
162     if (server == nullptr) {
163         HILOGD("server is null!");
164         return BT_SOCKET_INVALID_ID;
165     }
166 
167     std::shared_ptr<ClientSocket> client = server->Accept(0);
168     if (client == nullptr) {
169         HILOGE("client is null!");
170         return BT_SOCKET_INVALID_ID;
171     }
172     int clientId = g_clientMap.AddObject(client);
173     HILOGI("success, clientId: %{public}d", clientId);
174     return clientId;
175 }
176 
177 /**
178  * @brief Disables an socket server socket and releases related resources.
179  *
180  * @param serverId The relative ID used to identify the current server socket, obtain the value by calling
181  * {@link SocketServerCreate}.
182  * @return Returns the operation result status {@link BtStatus}.
183  */
SocketServerClose(int serverId)184 int SocketServerClose(int serverId)
185 {
186     HILOGI("SocketServerClose start, serverId: %{public}d", serverId);
187     std::shared_ptr<ServerSocket> server = g_serverMap.GetObject(serverId);
188     if (server == nullptr) {
189         HILOGE("server is null!");
190         return OHOS_BT_STATUS_FAIL;
191     }
192     server->Close();
193     g_serverMap.RemoveObject(serverId);
194     return OHOS_BT_STATUS_SUCCESS;
195 }
196 
197 /**
198  * @brief Set fast connection flag
199  *
200  * @param bdAddr The remote device address to connect.
201  * @return Returns the operation result status {@link BtStatus}.
202  */
SocketSetFastConnection(const BdAddr * bdAddr)203 int SocketSetFastConnection(const BdAddr *bdAddr)
204 {
205     string strAddress;
206     int leType = 1;
207     if (bdAddr == nullptr) {
208         HILOGE("bdAddr is nullptr.");
209         return OHOS_BT_STATUS_PARM_INVALID;
210     }
211     ConvertAddr(bdAddr->addr, strAddress);
212     // create a client to reuse requestfastestconn.
213     std::shared_ptr<GattClient> client = nullptr;
214     BluetoothRemoteDevice device(strAddress, leType);
215     client = std::make_shared<GattClient>(device);
216     client->Init();
217     int result = client->RequestFastestConn();
218     if (result != OHOS_BT_STATUS_SUCCESS) {
219         HILOGE("request fastest connect fail.");
220         return OHOS_BT_STATUS_FAIL;
221     }
222     return OHOS_BT_STATUS_SUCCESS;
223 }
224 
225 /**
226  * @brief Connects to a remote device over the socket.
227  * This method will block until a connection is made or the connection fails.
228  *
229  * @param socketPara The param to create a client socket and connect to a remote device.
230  * @param bdAddr The remote device address to connect.
231  * @param psm BluetoothSocketType is {@link OHOS_SOCKET_L2CAP_LE} use dynamic PSM value from remote device.
232  * BluetoothSocketType is {@link OHOS_SOCKET_SPP_RFCOMM} use -1.
233  * @return Returns a client ID, if connect fail return {@link BT_SOCKET_INVALID_ID}.
234  */
SocketConnect(const BluetoothCreateSocketPara * socketPara,const BdAddr * bdAddr,int psm)235 int SocketConnect(const BluetoothCreateSocketPara *socketPara, const BdAddr *bdAddr, int psm)
236 {
237     HILOGI("SocketConnect start.");
238     if (socketPara == nullptr || bdAddr == nullptr) {
239         HILOGE("socketPara is nullptr, or bdAddr is nullptr");
240         return BT_SOCKET_INVALID_ID;
241     }
242 
243     string strAddress;
244     ConvertAddr(bdAddr->addr, strAddress);
245     std::shared_ptr<BluetoothRemoteDevice> device = std::make_shared<BluetoothRemoteDevice>(strAddress, 0);
246 
247     UUID serverUuid;
248     if (!GetSocketUuidPara(socketPara, serverUuid)) {
249         return BT_SOCKET_INVALID_ID;
250     }
251 
252     std::shared_ptr<ClientSocket> client = std::make_shared<ClientSocket>(*device, serverUuid,
253         BtSocketType(socketPara->socketType), socketPara->isEncrypt);
254     HILOGI("socketType: %{public}d, isEncrypt: %{public}d", socketPara->socketType, socketPara->isEncrypt);
255     client->Init();
256     int result = client->Connect(psm);
257     if (result != OHOS_BT_STATUS_SUCCESS) {
258         HILOGE("SocketConnect fail, result: %{public}d", result);
259         client->Close();
260         HILOGE("SocketConnect closed.");
261         return BT_SOCKET_INVALID_ID;
262     }
263     int clientId = g_clientMap.AddObject(client);
264     HILOGI("SocketConnect success, clientId: %{public}d", clientId);
265     return clientId;
266 }
267 
268 /**
269  * @brief Connects to a remote device over the socket.
270  * This method will block until a connection is made or the connection fails.
271  * @param socketPara The param to create a client socket and connect to a remote device.
272  * @param bdAddr The remote device address to connect.
273  * @param psm BluetoothSocketType is {@link OHOS_SOCKET_L2CAP_LE} use dynamic PSM value from remote device.
274  * BluetoothSocketType is {@link OHOS_SOCKET_SPP_RFCOMM} use -1.
275  * @param callback Reference to the socket state observer
276  * @return Returns a client ID, if connect fail return {@link BT_SOCKET_INVALID_ID}.
277  */
SocketConnectEx(const BluetoothCreateSocketPara * socketPara,const BdAddr * bdAddr,int psm,BtSocketConnectionCallback * callback)278 int SocketConnectEx(const BluetoothCreateSocketPara *socketPara, const BdAddr *bdAddr, int psm,
279     BtSocketConnectionCallback *callback)
280 {
281     HILOGI("SocketConnect start.");
282     if (socketPara == nullptr || bdAddr == nullptr || callback == nullptr) {
283         HILOGE("socketPara is nullptr, or bdAddr is nullptr, or callback is nullptr");
284         return BT_SOCKET_INVALID_ID;
285     }
286 
287     string strAddress;
288     ConvertAddr(bdAddr->addr, strAddress);
289     std::shared_ptr<BluetoothRemoteDevice> device = std::make_shared<BluetoothRemoteDevice>(strAddress, 0);
290 
291     UUID serverUuid;
292     if (!GetSocketUuidPara(socketPara, serverUuid)) {
293         return BT_SOCKET_INVALID_ID;
294     }
295 
296     if (socketPara->socketType != OHOS_SOCKET_SPP_RFCOMM && socketPara->socketType != OHOS_SOCKET_L2CAP_LE) {
297         HILOGE("SocketType is not support");
298         return BT_SOCKET_INVALID_TYPE;
299     }
300 
301     std::shared_ptr<BluetoothConnectionObserverWapper> connWrapper =
302         std::make_shared<BluetoothConnectionObserverWapper>(*callback);
303     std::shared_ptr<ClientSocket> client = std::make_shared<ClientSocket>(*device, serverUuid,
304         BtSocketType(socketPara->socketType), socketPara->isEncrypt, connWrapper);
305     HILOGI("socketType: %{public}d, isEncrypt: %{public}d", socketPara->socketType, socketPara->isEncrypt);
306     client->Init();
307     int result = client->Connect(psm);
308     if (result != OHOS_BT_STATUS_SUCCESS) {
309         HILOGE("SocketConnect fail, result: %{public}d", result);
310         client->Close();
311         HILOGE("SocketConnect closed.");
312         return BT_SOCKET_INVALID_ID;
313     }
314     int clientId = g_clientMap.AddObject(client);
315     std::lock_guard<std::mutex> lock(g_clientCbMapMutex);
316     g_clientCbMap.insert(std::pair<int, std::shared_ptr<BluetoothConnectionObserverWapper>>(clientId, connWrapper));
317     HILOGI("SocketConnect success, clientId: %{public}d", clientId);
318     return clientId;
319 }
320 
321 /**
322  * @brief Disables a connection and releases related resources.
323  *
324  * @param clientId The relative ID used to identify the current client socket.
325  * @return Returns the operation result status {@link BtStatus}.
326  */
SocketDisconnect(int clientId)327 int SocketDisconnect(int clientId)
328 {
329     HILOGI("SocketDisconnect start, clientId: %{public}d", clientId);
330     std::shared_ptr<ClientSocket> client = g_clientMap.GetObject(clientId);
331     if (client == nullptr) {
332         HILOGE("client is null, clientId: %{public}d", clientId);
333         return OHOS_BT_STATUS_FAIL;
334     }
335     client->Close();
336     g_clientMap.RemoveObject(clientId);
337     std::lock_guard<std::mutex> lock(g_clientCbMapMutex);
338     ClientCbIterator it = g_clientCbMap.find(clientId);
339     if (it != g_clientCbMap.end()) {
340         g_clientCbMap.erase(it);
341     }
342     HILOGI("SocketDisConnect success, clientId: %{public}d", clientId);
343     return OHOS_BT_STATUS_SUCCESS;
344 }
345 
346 /**
347  * @brief Socket get remote device's address.
348  *
349  * @param clientId The relative ID used to identify the current client socket.
350  * @param remoteAddr Remote device's address, memory allocated by caller.
351  * @return Returns the operation result status {@link BtStatus}.
352  */
SocketGetRemoteAddr(int clientId,BdAddr * remoteAddr)353 int SocketGetRemoteAddr(int clientId, BdAddr *remoteAddr)
354 {
355     HILOGI("SocketGetRemoteAddr clientId: %{public}d", clientId);
356     if (remoteAddr == nullptr) {
357         HILOGE("remoteAddr is null, clientId: %{public}d", clientId);
358         return OHOS_BT_STATUS_PARM_INVALID;
359     }
360     std::shared_ptr<ClientSocket> client = g_clientMap.GetObject(clientId);
361     if (client == nullptr) {
362         HILOGE("client is null, clientId: %{public}d", clientId);
363         return OHOS_BT_STATUS_FAIL;
364     }
365     string tmpAddr = client->GetRemoteDevice().GetDeviceAddr();
366     GetAddrFromString(tmpAddr, remoteAddr->addr);
367     HILOGI("device: %{public}s", GetEncryptAddr(tmpAddr).c_str());
368     return OHOS_BT_STATUS_SUCCESS;
369 }
370 
371 /**
372  * @brief Get the connection status of this socket.
373  *
374  * @param clientId The relative ID used to identify the current client socket.
375  * @return Returns true is connected or false is not connected.
376  */
IsSocketConnected(int clientId)377 bool IsSocketConnected(int clientId)
378 {
379     HILOGI("IsSocketConnected clientId: %{public}d", clientId);
380     std::shared_ptr<ClientSocket> client = g_clientMap.GetObject(clientId);
381     if (client == nullptr) {
382         HILOGE("client is null, clientId: %{public}d", clientId);
383         return false;
384     }
385     bool isConnected = client->IsConnected();
386     HILOGI("clientId: %{public}d, isConnected: %{public}d", clientId, isConnected);
387     return isConnected;
388 }
389 
390 /**
391  * @brief Read data from socket.
392  * This method blocks until input data is available.
393  *
394  * @param clientId The relative ID used to identify the current client socket.
395  * @param buf Indicate the buffer which read in, memory allocated by caller.
396  * @param bufLen Indicate the buffer length.
397  * @return Returns the length greater than 0 as read the actual length.
398  * Returns {@link BT_SOCKET_READ_SOCKET_CLOSED} if the socket is closed.
399  * Returns {@link BT_SOCKET_READ_FAILED} if the operation failed.
400  */
SocketRead(int clientId,uint8_t * buf,uint32_t bufLen)401 int SocketRead(int clientId, uint8_t *buf, uint32_t bufLen)
402 {
403     HILOGD("SocketRead start, clientId: %{public}d, bufLen: %{public}d", clientId, bufLen);
404     if (buf == nullptr || bufLen == 0) {
405         HILOGE("buf is null or bufLen is 0! clientId: %{public}d", clientId);
406         return BT_SOCKET_READ_FAILED;
407     }
408     std::shared_ptr<ClientSocket> client = g_clientMap.GetObject(clientId);
409     if (client == nullptr) {
410         HILOGE("client is null, clientId: %{public}d", clientId);
411         return BT_SOCKET_READ_FAILED;
412     }
413     if (client->GetInputStream() == nullptr) {
414         HILOGE("inputStream is null, clientId: %{public}d", clientId);
415         return BT_SOCKET_READ_FAILED;
416     }
417     int readLen = client->GetInputStream()->Read(buf, bufLen);
418     HILOGD("SocketRead ret, clientId: %{public}d, readLen: %{public}d", clientId, readLen);
419     return readLen;
420 }
421 
422 /**
423  * @brief Client write data to socket.
424  *
425  * @param clientId The relative ID used to identify the current client socket.
426  * @param data Indicate the data to be written.
427  * @return Returns the actual write length.
428  * Returns {@link BT_SOCKET_WRITE_FAILED} if the operation failed.
429  */
SocketWrite(int clientId,const uint8_t * data,uint32_t len)430 int SocketWrite(int clientId, const uint8_t *data, uint32_t len)
431 {
432     HILOGD("SocketWrite start, clientId: %{public}d, len: %{public}d", clientId, len);
433     if (data == nullptr || len == 0) {
434         HILOGE("data is null or len is 0! clientId: %{public}d", clientId);
435         return BT_SOCKET_WRITE_FAILED;
436     }
437     std::shared_ptr<ClientSocket> client = g_clientMap.GetObject(clientId);
438     if (client == nullptr) {
439         HILOGE("client is null! clientId: %{public}d", clientId);
440         return BT_SOCKET_WRITE_FAILED;
441     }
442     if (client->GetOutputStream() == nullptr) {
443         HILOGE("outputStream is null, clientId: %{public}d", clientId);
444         return BT_SOCKET_READ_FAILED;
445     }
446     int writeLen = client->GetOutputStream()->Write(data, len);
447     HILOGD("end, writeLen: %{public}d", writeLen);
448     return writeLen;
449 }
450 
451 /**
452  * @brief Get dynamic PSM value for OHOS_SOCKET_L2CAP.
453  *
454  * @param serverId The relative ID used to identify the current server socket, obtain the value by calling
455  * {@link SocketServerCreate}.
456  * @return Returns the PSM value.
457  * Returns {@link BT_SOCKET_INVALID_PSM} if the operation failed.
458  */
SocketGetPsm(int serverId)459 int SocketGetPsm(int serverId)
460 {
461     HILOGI("serverId: %{public}d", serverId);
462     std::shared_ptr<ServerSocket> server = g_serverMap.GetObject(serverId);
463     CHECK_AND_RETURN_LOG_RET(server, BT_SOCKET_INVALID_PSM, "server is null!");
464     return server->GetL2capPsm();
465 }
466 
467 /**
468  * @brief Get server channel number for OHOS_SOCKET_RFCOMM.
469  *
470  * @param serverId The relative ID used to identify the current server socket, obtain the value by calling
471  * {@link SocketServerCreate}.
472  * @return Returns the scn.
473  * Returns {@link BT_SOCKET_INVALID_PSM} if the operation failed.
474  */
SocketGetScn(int serverId)475 int SocketGetScn(int serverId)
476 {
477     HILOGI("serverId: %{public}d", serverId);
478     std::shared_ptr<ServerSocket> server = g_serverMap.GetObject(serverId);
479     CHECK_AND_RETURN_LOG_RET(server, BT_SOCKET_INVALID_SCN, "server is null!");
480     return server->GetRfcommScn();
481 }
482 
483 /**
484  * @brief Adjust the socket send and recv buffer size, limit range is 4KB to 50KB
485  *
486  * @param clientId The relative ID used to identify the current client socket.
487  * @param bufferSize The buffer size want to set, unit is byte.
488  * @return  Returns the operation result status {@link BtStatus}.
489  */
SetSocketBufferSize(int clientId,uint32_t bufferSize)490 int SetSocketBufferSize(int clientId, uint32_t bufferSize)
491 {
492     HILOGI("start, clientId: %{public}d, bufferSize: %{public}d", clientId, bufferSize);
493     std::shared_ptr<ClientSocket> client = g_clientMap.GetObject(clientId);
494     if (client == nullptr) {
495         HILOGE("client is null! clientId: %{public}d", clientId);
496         return OHOS_BT_STATUS_FAIL;
497     }
498     int ret = client->SetBufferSize(bufferSize);
499     if (ret == RET_BAD_PARAM) {
500         return OHOS_BT_STATUS_PARM_INVALID;
501     } else if (ret == RET_BAD_STATUS) {
502         return OHOS_BT_STATUS_FAIL;
503     }
504     return OHOS_BT_STATUS_SUCCESS;
505 }
506 /**
507  * @brief Update the coc connection params
508  *
509  * @param param CocUpdateSocketParam instance for carry params.
510  * @param bdAddr The remote device address to connect.
511  * @return Returns the operation result status {@link BtStatus}.
512  */
SocketUpdateCocConnectionParams(BluetoothCocUpdateSocketParam * param,const BdAddr * bdAddr)513 int SocketUpdateCocConnectionParams(BluetoothCocUpdateSocketParam* param, const BdAddr *bdAddr)
514 {
515     CocUpdateSocketParam params;
516 
517     HILOGI("Socket update coc params start");
518     CHECK_AND_RETURN_LOG_RET(param, OHOS_BT_STATUS_FAIL, "param is null");
519     CHECK_AND_RETURN_LOG_RET(bdAddr, OHOS_BT_STATUS_FAIL, "bdAddr is null");
520     ConvertAddr(bdAddr->addr, params.addr);
521     params.minInterval = param->minInterval;
522     params.maxInterval = param->maxInterval;
523     params.peripheralLatency = param->peripheralLatency;
524     params.supervisionTimeout = param->supervisionTimeout;
525     params.minConnEventLen = param->minConnEventLen;
526     params.maxConnEventLen = param->maxConnEventLen;
527 
528     std::shared_ptr<BluetoothRemoteDevice> device = std::make_shared<BluetoothRemoteDevice>(params.addr,
529         OHOS_SOCKET_SPP_RFCOMM);
530     std::shared_ptr<ClientSocket> client = std::make_shared<ClientSocket>(*device, UUID::RandomUUID(),
531         TYPE_L2CAP_LE, false);
532     CHECK_AND_RETURN_LOG_RET(client, OHOS_BT_STATUS_FAIL, "client is null");
533     return client->UpdateCocConnectionParams(params);
534 }
535 
536 }  // namespace Bluetooth
537 }  // namespace OHOS
538 #ifdef __cplusplus
539 }
540 #endif