xref: /OK3568_Linux_fs/external/rkwifibt-app/test/rkbtsource.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2017 Rockchip, Inc. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <pthread.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <math.h>
23 #include <linux/input.h>
24 #include <linux/rtc.h>
25 #include <sys/un.h>
26 #include <sys/time.h>
27 #include <sys/select.h>
28 #include <sys/socket.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 
34 #include "rkbtsource_common.h"
35 
36 static pthread_t rk_bt_recv_t = 0, rk_bt_spp_s_t = 0;
37 static int spp_is_connected = 0;
38 static int sockfd = 0, spp_client_fd = 0;
39 static int bt_server_open_state = 0;
40 static int bt_server_close_state = 0;
41 
bt_cmd_list()42 static void bt_cmd_list()
43 {
44 	unsigned int i;
45 	for (i = 1; i < sizeof(bt_command_tbs) / sizeof(bt_commands_t); i++) {
46 		printf("%02d.  %s \n", i, bt_command_tbs[i].cmd);
47 	}
48 }
49 
rk_spp_client_recv(void * p)50 static int rk_spp_client_recv(void *p)
51 {
52 	int bytes_read;
53 	char buf[64];
54 
55 wait_client:
56 	while (spp_is_connected == 0)
57 		sleep(1);
58 
59 	while (1) {
60 		//check spp link
61 		if (spp_is_connected == 0) {
62 			close(spp_client_fd);
63 			spp_client_fd = 0;
64 			spp_is_connected = 0;
65 			goto wait_client;
66 		}
67 
68 		memset(buf, 0, sizeof(buf));
69 		bytes_read = read(spp_client_fd, buf, sizeof(buf));
70 		if (bytes_read < 0) {
71 			printf("[BT SPP] error: %d:%s!\n", bytes_read, strerror(errno));
72 			close(spp_client_fd);
73 			spp_client_fd = 0;
74 			spp_is_connected = 0;
75 			goto wait_client;
76 		}
77 
78 		printf("spp client recv: [%s] \n", buf);
79 
80 		//echo
81 		bytes_read = write(spp_client_fd, buf, sizeof(buf));
82 	}
83 }
84 
rk_bt_check_server(void)85 static int rk_bt_check_server(void)
86 {
87 	if (bt_server_open_state && bt_server_close_state) {
88 		//close socket, exit.
89 		bt_server_open_state = 0;
90 		bt_server_close_state = 0;
91 		close(sockfd);
92 		return 0;
93 	}
94 
95 	return 1;
96 }
97 
rk_bt_recv(void * p)98 static int rk_bt_recv(void *p)
99 {
100 	int ret, status;
101 	bt_msg_t evt;
102 	char buff[256] = "";
103 	struct iovec io;
104 	struct msghdr msg;
105 	struct cmsghdr *cmsg;
106 
107 	while (1) {
108 		memset(&evt, 0, sizeof(bt_msg_t));
109 		io.iov_base = &evt,
110 		io.iov_len = sizeof(bt_msg_t),
111 
112 		msg.msg_iov = &io,
113 		msg.msg_iovlen = 1,
114 		msg.msg_control = buff,
115 		msg.msg_controllen = sizeof(buff),
116 
117 		ret = recvmsg(sockfd, &msg, MSG_CMSG_CLOEXEC);
118 		if (ret <= 0)
119 			continue;
120 
121 		switch(evt.id) {
122 		case RK_BT_EVT_SCAN_ADD_DEV:
123 			printf("%s: device is found\n", PRINT_FLAG_RKBTSOURCE);
124 			printf("		address: %s\n", evt.dev.addr);
125 			printf("		name: %s\n", evt.dev.name);
126 			printf("		role: 0x%x\n", evt.dev.role);
127 			printf("		rssi: %d\n", evt.dev.rssi);
128 			break;
129 		case RK_BT_EVT_SCAN_REMOVE_DEV:
130 			printf("%s: device is removed\n", PRINT_FLAG_RKBTSOURCE);
131 			printf("		address: %s\n", evt.dev.addr);
132 			printf("		name: %s\n", evt.dev.name);
133 			break;
134 		case RK_BT_EVT_SCAN_CHANGE_DEV:
135 			printf("%s: device is changed\n", PRINT_FLAG_RKBTSOURCE);
136 			printf("		address: %s\n", evt.dev.addr);
137 			printf("		name: %s\n", evt.dev.name);
138 			printf("		rssi: %d\n", evt.dev.rssi);
139 			break;
140 		case RK_BT_EVT_PAIRED_DEV:
141 			printf("%s: device is paired\n", PRINT_FLAG_RKBTSOURCE);
142 			printf("		address: %s\n", evt.dev.addr);
143 			printf("		name: %s\n", evt.dev.name);
144 			printf("		is_connected: %d\n", evt.dev.is_connected);
145 			break;
146 		case RK_BT_EVT_SPP_DISCONNECTED:
147 			printf("RK_BT_EVT_SPP_DISCONNECTED\n");
148 			spp_is_connected = 0;
149 			break;
150 		case RK_BT_EVT_SPP_CONNECT_FAILED:
151 			printf("RK_BT_EVT_SPP_CONNECT_FAILED\n");
152 			spp_is_connected = 0;
153 			break;
154 		case RK_BT_EVT_SPP_CONNECTED:
155 			printf("RK_BT_EVT_SPP_CONNECTED\n");
156 			cmsg = CMSG_FIRSTHDR(&msg);
157 			if (cmsg->cmsg_level != SOL_SOCKET)
158 				continue;
159 			if (cmsg->cmsg_level != SCM_RIGHTS)
160 				continue;
161 			spp_client_fd = *((int *)CMSG_DATA(cmsg));
162 			printf("RK_BT_EVT_SPP_CLIENT_FD: %d\n", spp_client_fd);
163 			spp_is_connected = 1;
164 			break;
165 		case RK_BT_EVT_INIT_OK:
166 			printf("RK_BT_SERVER OPEN SUCCESS\n");
167 			bt_server_open_state = 1;
168 			break;
169 		case RK_BT_EVT_DEINIT_OK:
170 			printf("RK_BT_SERVER CLOSED\n");
171 			bt_server_close_state = 1;
172 			return 0;
173 		case RK_BT_EVT_SCAN_ON:
174 			printf("RK_BT_SERVER SCAN\n");
175 			break;
176 		case RK_BT_EVT_SCAN_OFF:
177 			printf("RK_BT_SERVER SCAN OFF\n");
178 			break;
179 		case RK_BT_EVT_SOURCE_OPEN:
180 			printf("RK_BT_SERVER SOURCE OPEN\n");
181 			break;
182 		case RK_BT_EVT_SOURCE_CLOSE:
183 			printf("RK_BT_SERVER SOURCE OFF\n");
184 			break;
185 		case RK_BT_EVT_SOURCE_CONNECTED:
186 			printf("RK_BT_SERVER SOURCE CONNECTED\n");
187 			printf("		address: %s\n", evt.dev.addr);
188 			printf("		name: %s\n", evt.dev.name);
189 			break;
190 		case RK_BT_EVT_SOURCE_DISCONNECTED:
191 			printf("RK_BT_SERVER SOURCE DISCONNECTED\n");
192 			printf("		address: %s\n", evt.dev.addr);
193 			printf("		name: %s\n", evt.dev.name);
194 			break;
195 		case RK_BT_EVT_PONG:
196 			printf("RK_BT_SERVER_LIVE\n");
197 			bt_server_open_state = 1;
198 			break;
199 		default:
200 			printf("[s_t_c: %s]\n", bt_evt_str_table[evt.id].desc);
201 		}
202 	}
203 }
204 
main(int argc,char * argv[])205 int main(int argc, char *argv[])
206 {
207 	int i, item_cnt, ret;
208 	char cmdbuf[64], cmd[64];
209 	char *input_start;
210 	bt_msg_t msg;
211 
212 	bt_server_open_state = 0;
213 	bt_server_close_state = 0;
214 
215 	unlink(RKBTSOURCE_CLIENT_SOCKET_PATH);
216 	//start rkwifibt_server
217 	system("killall rkwifibt_server");
218 	//realpath
219 	system("rkwifibt_server &");
220 
221 	sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
222 	if (sockfd < 0) {
223 		printf("%s: Socket create failed!\n", PRINT_FLAG_ERR);
224 		return -1;
225 	}
226 
227 	struct sockaddr_un addr;
228 	addr.sun_family = AF_UNIX;
229 	strcpy(addr.sun_path, RKBTSOURCE_CLIENT_SOCKET_PATH);
230 	ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
231 	if (ret < 0) {
232 		printf("%s: Bind Local addr failed!\n", PRINT_FLAG_ERR);
233 		goto OUT;
234 	}
235 
236 	struct timeval t = {4, 0};
237 	setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&t, sizeof(t));
238 
239 	/* Set server address */
240 	struct sockaddr_un dst;
241 	dst.sun_family = AF_UNIX;
242 	strcpy(dst.sun_path, RKBTSOURCE_SERVER_SOCKET_PATH);
243 
244 	bt_cmd_list();
245 	item_cnt = sizeof(bt_command_tbs) / sizeof(bt_commands_t);
246 
247 	if (rk_bt_recv_t)
248 		return 0;
249 
250 	if (pthread_create(&rk_bt_recv_t, NULL, rk_bt_recv, NULL)) {
251 		printf("%s: Create rk_bt_init_thread thread failed\n", __func__);
252 		return -1;
253 	}
254 	pthread_setname_np(rk_bt_recv_t, "rk_bt_recv_t");
255 	pthread_detach(rk_bt_recv_t);
256 
257 	if (pthread_create(&rk_bt_spp_s_t, NULL, rk_spp_client_recv, NULL)) {
258 		printf("%s: Create rk_bt_init_thread thread failed\n", __func__);
259 		return -1;
260 	}
261 	pthread_setname_np(rk_bt_spp_s_t, "rk_bt_spp_s_t");
262 	pthread_detach(rk_bt_spp_s_t);
263 
264 	while (1) {
265 		if (!rk_bt_check_server())
266 			return 0;
267 		memset(cmdbuf, 0, sizeof(cmdbuf));
268 		memset(&msg, 0, sizeof(bt_msg_t));
269 		printf("Please input number or help to run: ");
270 
271 		if (fgets(cmdbuf, 64, stdin) == NULL)
272 			continue;
273 
274 		if (!strncmp("help", cmdbuf, 4) || !strncmp("h", cmdbuf, 1))
275 			bt_cmd_list();
276 
277 		//remove end space
278 		cmdbuf[strlen(cmdbuf) - 1] = 0;
279 
280 		input_start = strstr(cmdbuf, "input");
281 		if (input_start == NULL) {
282 			i = atoi(cmdbuf);
283 			if ((i < 1) && (i > item_cnt))
284 				continue;
285 
286 			msg.type = RK_BT_CMD;
287 			msg.id = bt_command_tbs[i].cmd_id;
288 
289 		} else {
290 			memset(cmd, 0, sizeof(cmd));
291 			strncpy(cmd, cmdbuf, strlen(cmdbuf) - strlen(input_start) - 1);
292 			i = atoi(cmd);
293 			if ((i < 1) && (i > item_cnt))
294 				continue;
295 
296 			msg.type = RK_BT_CMD;
297 			msg.id = bt_command_tbs[i].cmd_id;
298 			if (msg.id == RK_BT_INIT)
299 				strncpy(msg.data, input_start + strlen("input") + 1, 17); //set bt name
300 			else
301 				strncpy(msg.addr, input_start + strlen("input") + 1, 17); //set bt addr
302 		}
303 
304 		if (!rk_bt_check_server())
305 			return 0;
306 
307 		ret = sendto(sockfd, &msg, sizeof(bt_msg_t), 0, (struct sockaddr *)&dst, sizeof(dst));
308 		if (ret < 0) {
309 			printf("%s: Socket send failed! ret = %d\n", PRINT_FLAG_ERR, ret);
310 			goto OUT;
311 		}
312 	}
313 
314 OUT:
315 	if(sockfd)
316 		close(sockfd);
317 	return ret;
318 }
319