1 /*
2 * Copyright (C) 2021-2022 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_spp"
17 #endif
18
19 #include "ohos_bt_spp.h"
20 #include "ohos_bt_socket.h"
21
22 #include <iostream>
23 #include <cstring>
24 #include <vector>
25
26 #include "ohos_bt_adapter_utils.h"
27 #include "bluetooth_socket.h"
28 #include "bluetooth_host.h"
29 #include "bluetooth_log.h"
30 #include "bluetooth_utils.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 using namespace std;
37
38 namespace OHOS {
39 namespace Bluetooth {
40 static mutex g_writeMutex;
41
42 /**
43 * @brief Creates an server listening socket based on the service record.
44 *
45 * @param socketPara The parameters to create a server socket.
46 * @param name The service's name.
47 * @param len The length of the service's name.
48 * @return Returns a server ID, if create fail return {@link BT_SPP_INVALID_ID}.
49 */
SppServerCreate(BtCreateSocketPara * socketPara,const char * name,unsigned int len)50 int SppServerCreate(BtCreateSocketPara *socketPara, const char *name, unsigned int len)
51 {
52 HILOGD("start!");
53 if (socketPara == nullptr) {
54 HILOGI("socketPara is invalid!");
55 return BT_SPP_INVALID_ID;
56 }
57 BluetoothCreateSocketPara btsocketPara;
58 btsocketPara.isEncrypt = socketPara->isEncrypt;
59 btsocketPara.socketType = BluetoothSocketType(socketPara->socketType);
60 btsocketPara.uuid.uuidLen = socketPara->uuid.uuidLen;
61 btsocketPara.uuid.uuid = socketPara->uuid.uuid;
62
63 return SocketServerCreate(&btsocketPara, name);
64 }
65
66 /**
67 * @brief Waits for a remote device to connect to this server socket.
68 *
69 * This method return a client ID indicates a client socket
70 * can be used to read data from and write data to remote device.
71 *
72 * @param serverId The relative ID used to identify the current server socket, obtain the value by calling
73 * {@link SppServerCreate}.
74 * @return Returns a client ID, if accept fail return {@link BT_SPP_INVALID_ID}.
75 */
SppServerAccept(int serverId)76 int SppServerAccept(int serverId)
77 {
78 HILOGI("start, serverId: %{public}d", serverId);
79 return SocketServerAccept(serverId);
80 }
81
82 /**
83 * @brief Disables an spp server socket and releases related resources.
84 *
85 * @param serverId The relative ID used to identify the current server socket, obtain the value by calling
86 * {@link SppServerCreate}.
87 * @return Returns the operation result status {@link BtStatus}.
88 */
SppServerClose(int serverId)89 int SppServerClose(int serverId)
90 {
91 HILOGI("serverId: %{public}d", serverId);
92 return SocketServerClose(serverId);
93 }
94
95 /**
96 * @brief Connects to a remote device over the socket.
97 *
98 * @param socketPara The param to create a client socket and connect to a remote device.
99 * @return Returns a client ID, if connect fail return {@link BT_SPP_INVALID_ID}.
100 */
SppConnect(BtCreateSocketPara * socketPara,const BdAddr * bdAddr)101 int SppConnect(BtCreateSocketPara *socketPara, const BdAddr *bdAddr)
102 {
103 HILOGI("SppConnect start");
104 if (socketPara == nullptr) {
105 HILOGI("socketPara is invalid!");
106 return BT_SPP_INVALID_ID;
107 }
108 BluetoothCreateSocketPara btsocketPara;
109 btsocketPara.isEncrypt = socketPara->isEncrypt;
110 btsocketPara.socketType = BluetoothSocketType(socketPara->socketType);
111 btsocketPara.uuid.uuidLen = socketPara->uuid.uuidLen;
112 btsocketPara.uuid.uuid = socketPara->uuid.uuid;
113 return SocketConnect(&btsocketPara, bdAddr, SPP_SOCKET_PSM_VALUE);
114 }
115
116 /**
117 * @brief Disables a connection and releases related resources.
118 *
119 * @param clientId The relative ID used to identify the current client socket.
120 * @return Returns the operation result status {@link BtStatus}.
121 */
SppDisconnect(int clientId)122 int SppDisconnect(int clientId)
123 {
124 lock_guard<mutex> lock(g_writeMutex);
125 HILOGI("clientId: %{public}d", clientId);
126 return SocketDisconnect(clientId);
127 }
128
129 /**
130 * @brief Spp get remote device's address.
131 *
132 * @param clientId The relative ID used to identify the current client socket.
133 * @param remoteAddr Remote device's address, memory allocated by caller.
134 * @return Returns the operation result status {@link BtStatus}.
135 */
SppGetRemoteAddr(int clientId,BdAddr * remoteAddr)136 int SppGetRemoteAddr(int clientId, BdAddr *remoteAddr)
137 {
138 HILOGI("clientId: %{public}d", clientId);
139 return SocketGetRemoteAddr(clientId, remoteAddr);
140 }
141
142 /**
143 * @brief Get the connection status of this socket.
144 *
145 * @param clientId The relative ID used to identify the current client socket.
146 * @return Returns true is connected or false is not connected.
147 */
IsSppConnected(int clientId)148 bool IsSppConnected(int clientId)
149 {
150 HILOGI("clientId: %{public}d", clientId);
151 return IsSocketConnected(clientId);
152 }
153
154 /**
155 * @brief Read data from socket.
156 *
157 * @param clientId The relative ID used to identify the current client socket.
158 * @param buf Indicate the buffer which read in, memory allocated by caller.
159 * @param bufLen Indicate the buffer length.
160 * @return Returns the length greater than 0 as read the actual length.
161 * Returns {@link BT_SPP_READ_SOCKET_CLOSED} if the socket is closed.
162 * Returns {@link BT_SPP_READ_FAILED} if the operation failed.
163 */
SppRead(int clientId,char * buf,const unsigned int bufLen)164 int SppRead(int clientId, char *buf, const unsigned int bufLen)
165 {
166 return SocketRead(clientId, reinterpret_cast<uint8_t*>(buf), bufLen);
167 }
168
169 /**
170 * @brief Client write data to socket.
171 *
172 * @param clientId The relative ID used to identify the current client socket.
173 * @param data Indicate the data to be written.
174 * @return Returns the actual write length.
175 * Returns {@link BT_SPP_WRITE_FAILED} if the operation failed.
176 */
SppWrite(int clientId,const char * data,const unsigned int len)177 int SppWrite(int clientId, const char *data, const unsigned int len)
178 {
179 lock_guard<mutex> lock(g_writeMutex);
180 HILOGD("start, clientId: %{public}d, len: %{public}d", clientId, len);
181 return SocketWrite(clientId, reinterpret_cast<const uint8_t*>(data), len);
182 }
183
184 /**
185 * @brief Adjust the socket send and recv buffer size, limit range is 4KB to 50KB
186 *
187 * @param clientId The relative ID used to identify the current client socket.
188 * @param bufferSize The buffer size want to set, unit is byte.
189 * @return Returns the operation result status {@link BtStatus}.
190 */
SppSetSocketBufferSize(int clientId,int bufferSize)191 int SppSetSocketBufferSize(int clientId, int bufferSize)
192 {
193 HILOGI("start, clientId: %{public}d, size: %{public}d", clientId, bufferSize);
194 if (bufferSize < 0) {
195 return OHOS_BT_STATUS_PARM_INVALID;
196 }
197 return SetSocketBufferSize(clientId, bufferSize);
198 }
199 } // namespace Bluetooth
200 } // namespace OHOS
201 #ifdef __cplusplus
202 }
203 #endif