1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2018 Realtek Corporation.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <stdio.h>
19 #include <getopt.h>
20 #include <string.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <syslog.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <sys/un.h>
27 #include <stddef.h>
28 #include <signal.h>
29 #include <unistd.h>
30
31 #define UNIX_DOMAIN "@/data/misc/bluedroid/rtkbt_service.sock"
32
33 typedef struct Rtk_Socket_Data
34 {
35 unsigned char type; // hci,other,inner
36 unsigned char opcodeh;
37 unsigned char opcodel;
38 unsigned char parameter_len;
39 unsigned char parameter[0];
40 } Rtk_Socket_Data;
41
42 /*typedef struct
43 {
44 unsigned short event;
45 unsigned short len;
46 unsigned short offset;
47 unsigned short layer_specific;
48 unsigned char data[];
49 } HC_BT_HDR;
50 */
51 const char shortOptions[] = "f:r:h";
52 const struct option longOptions[] = {
53 {"fullhcicmd", required_argument, NULL, 'f'},
54 {"read", required_argument, NULL, 'r'},
55 {"help", no_argument, NULL, 'h'},
56 {0, 0, 0, 0}};
57
usage(void)58 static void usage(void)
59 {
60 fprintf(stderr, "Usage: rtkcmd [options]\n\n"
61 "Options:\n"
62 "-f | --fullhcicmd [opcode,parameter_len,parameter] send hci cmd\n"
63 "-r | --read [address] read register address \n"
64 "-h | --help Print this message\n\n");
65 }
66
Rtkbt_Sendcmd(int socketfd,char * p)67 int Rtkbt_Sendcmd(int socketfd, char *p)
68 {
69 char *token = NULL;
70 int i = 0;
71 unsigned short OpCode = 0;
72 unsigned char ParamLen = 0;
73 unsigned char ParamLen_1 = 0;
74 int sendlen = 0;
75 int params_count = 0;
76 int ret = 0;
77 Rtk_Socket_Data *p_buf = NULL;
78
79 token = strtok(p, ",");
80 if (token != NULL)
81 {
82 OpCode = strtol(token, NULL, 0);
83 // printf("OpCode = %x\n",OpCode);
84 params_count++;
85 }
86 else
87 {
88 // ret = FUNCTION_PARAMETER_ERROR;
89 printf("parameter error\n");
90 return -1;
91 }
92
93 token = strtok(NULL, ",");
94 if (token != NULL)
95 {
96 ParamLen = strtol(token, NULL, 0);
97 // printf("ParamLen = %d\n",ParamLen);
98 params_count++;
99 }
100 else
101 {
102 printf("parameter error\n");
103 return -1;
104 }
105
106 p_buf = (Rtk_Socket_Data *)malloc(sizeof(Rtk_Socket_Data) + sizeof(char) * ParamLen);
107 p_buf->type = 0x01;
108 p_buf->opcodeh = OpCode >> 8;
109 p_buf->opcodel = OpCode & 0xff;
110 p_buf->parameter_len = ParamLen;
111
112 ParamLen_1 = ParamLen;
113 while (ParamLen_1--)
114 {
115 token = strtok(NULL, ",");
116 if (token != NULL)
117 {
118 p_buf->parameter[i++] = strtol(token, NULL, 0);
119 params_count++;
120 }
121 else
122 {
123 printf("parameter error\n");
124 return -1;
125 }
126 }
127
128 if (params_count != ParamLen + 2)
129 {
130 printf("parameter error\n");
131 return -1;
132 }
133
134 sendlen = sizeof(Rtk_Socket_Data) + sizeof(char) * p_buf->parameter_len;
135 ret = write(socketfd, p_buf, sendlen);
136 if (ret != sendlen)
137 return -1;
138
139 free(p_buf);
140 return 0;
141 }
142
Rtkbt_Getevent(int sock_fd)143 int Rtkbt_Getevent(int sock_fd)
144 {
145 unsigned short event = 0;
146 unsigned short event_len = 0;
147 unsigned short offset = 0;
148 unsigned short layer_specific = 0;
149 unsigned char *recvbuf = NULL;
150 int ret = 0;
151 int i;
152
153 ret = read(sock_fd, &event, 2);
154 if (ret <= 0)
155 return -1;
156 // printf("event = %x\n",event);
157
158 ret = read(sock_fd, &event_len, 2);
159 if (ret <= 0)
160 return -1;
161 // printf("event_len = %x\n",event_len);
162
163 ret = read(sock_fd, &offset, 2);
164 if (ret <= 0)
165 return -1;
166 // printf("offset = %x\n",offset);
167
168 ret = read(sock_fd, &layer_specific, 2);
169 if (ret <= 0)
170 return -1;
171 // printf("layer_specific = %x\n",layer_specific);
172
173 recvbuf = (unsigned char *)malloc(sizeof(char) * event_len);
174 ret = read(sock_fd, recvbuf, event_len);
175 if (ret < event_len)
176 return -1;
177
178 printf("Event: ");
179 for (i = 0; i < event_len - 1; i++)
180 printf("0x%02x ", recvbuf[i]);
181 printf("0x%02x\n", recvbuf[event_len - 1]);
182
183 free(recvbuf);
184 return 0;
185 }
186
socketinit()187 int socketinit()
188 {
189 int sock_fd;
190 struct sockaddr_un un;
191 int len;
192 memset(&un, 0, sizeof(un)); /* fill socket address structure with our address */
193 un.sun_family = AF_UNIX;
194 strcpy(un.sun_path, UNIX_DOMAIN);
195 un.sun_path[0] = 0;
196 len = offsetof(struct sockaddr_un, sun_path) + strlen(UNIX_DOMAIN);
197
198 sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
199 if (sock_fd < 0)
200 {
201 printf("socket failed %s\n", strerror(errno));
202 return -1;
203 }
204 if (connect(sock_fd, (struct sockaddr *)&un, len) < 0)
205 {
206 printf("connect failed %s\n", strerror(errno));
207 close(sock_fd);
208 return -1;
209 }
210
211 return sock_fd;
212 }
213
main(int argc,char * argv[])214 int main(int argc, char *argv[])
215 {
216 int index;
217 int c;
218 int ret;
219 int socketfd;
220
221 socketfd = socketinit();
222 if (socketfd < 0)
223 {
224 printf("socketinit failed\n");
225 exit(0);
226 }
227
228 c = getopt_long(argc, argv, shortOptions, longOptions, &index);
229
230 if (c == -1)
231 {
232 usage();
233 }
234 else
235 {
236 switch (c)
237 {
238 case 'f':
239 {
240 printf("Hcicmd %s\n", optarg);
241 ret = Rtkbt_Sendcmd(socketfd, optarg);
242 if (ret >= 0)
243 {
244 if (Rtkbt_Getevent(socketfd) < 0)
245 printf("Getevent fail\n");
246 }
247 break;
248 }
249 case 'r':
250 {
251 printf("read register %s\n", optarg);
252 // Rtkbt_Readreg(socketfd,optarg);
253 break;
254 }
255 case 'h':
256 {
257 usage();
258 break;
259 }
260 }
261 }
262
263 close(socketfd);
264 }