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