remote_bitbang: fix native windows build
[openocd.git] / src / jtag / drivers / remote_bitbang.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Richard Uhler *
3 * ruhler@mit.edu *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #ifndef _WIN32
26 #include <sys/un.h>
27 #include <netdb.h>
28 #endif
29 #include <jtag/interface.h>
30 #include "bitbang.h"
31
32 #ifndef UNIX_PATH_LEN
33 #define UNIX_PATH_LEN 108
34 #endif
35
36 /* arbitrary limit on host name length: */
37 #define REMOTE_BITBANG_HOST_MAX 255
38
39 #define REMOTE_BITBANG_RAISE_ERROR(expr ...) \
40 do { \
41 LOG_ERROR(expr); \
42 LOG_ERROR("Terminating openocd."); \
43 exit(-1); \
44 } while (0)
45
46 static char remote_bitbang_host[REMOTE_BITBANG_HOST_MAX] = "openocd";
47 static uint16_t remote_bitbang_port;
48
49 FILE *remote_bitbang_in;
50 FILE *remote_bitbang_out;
51
52 static void remote_bitbang_putc(int c)
53 {
54 if (EOF == fputc(c, remote_bitbang_out))
55 REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno));
56 }
57
58 static int remote_bitbang_quit(void)
59 {
60 if (EOF == fputc('Q', remote_bitbang_out)) {
61 LOG_ERROR("fputs: %s", strerror(errno));
62 return ERROR_FAIL;
63 }
64
65 if (EOF == fflush(remote_bitbang_out)) {
66 LOG_ERROR("fflush: %s", strerror(errno));
67 return ERROR_FAIL;
68 }
69
70 /* We only need to close one of the FILE*s, because they both use the same */
71 /* underlying file descriptor. */
72 if (EOF == fclose(remote_bitbang_out)) {
73 LOG_ERROR("fclose: %s", strerror(errno));
74 return ERROR_FAIL;
75 }
76
77 LOG_INFO("remote_bitbang interface quit");
78 return ERROR_OK;
79 }
80
81 /* Get the next read response. */
82 static int remote_bitbang_rread(void)
83 {
84 if (EOF == fflush(remote_bitbang_out)) {
85 remote_bitbang_quit();
86 REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno));
87 }
88
89 int c = fgetc(remote_bitbang_in);
90 switch (c) {
91 case '0':
92 return 0;
93 case '1':
94 return 1;
95 default:
96 remote_bitbang_quit();
97 REMOTE_BITBANG_RAISE_ERROR(
98 "remote_bitbang: invalid read response: %c(%i)", c, c);
99 }
100 }
101
102 static int remote_bitbang_read(void)
103 {
104 remote_bitbang_putc('R');
105 return remote_bitbang_rread();
106 }
107
108 static void remote_bitbang_write(int tck, int tms, int tdi)
109 {
110 char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
111 remote_bitbang_putc(c);
112 }
113
114 static void remote_bitbang_reset(int trst, int srst)
115 {
116 char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
117 remote_bitbang_putc(c);
118 }
119
120 static void remote_bitbang_blink(int on)
121 {
122 char c = on ? 'B' : 'b';
123 remote_bitbang_putc(c);
124 }
125
126 static struct bitbang_interface remote_bitbang_bitbang = {
127 .read = &remote_bitbang_read,
128 .write = &remote_bitbang_write,
129 .reset = &remote_bitbang_reset,
130 .blink = &remote_bitbang_blink,
131 };
132
133 static int remote_bitbang_speed(int speed)
134 {
135 return ERROR_OK;
136 }
137
138 static int remote_bitbang_init_tcp(void)
139 {
140 LOG_INFO("Connecting to %s:%i", remote_bitbang_host, remote_bitbang_port);
141 int fd = socket(PF_INET, SOCK_STREAM, 0);
142 if (fd < 0) {
143 LOG_ERROR("socket: %s", strerror(errno));
144 return ERROR_FAIL;
145 }
146
147 struct hostent *hent = gethostbyname(remote_bitbang_host);
148 if (hent == NULL) {
149 char *errorstr = "???";
150 switch (h_errno) {
151 case HOST_NOT_FOUND:
152 errorstr = "host not found";
153 break;
154 case NO_ADDRESS:
155 errorstr = "no address";
156 break;
157 case NO_RECOVERY:
158 errorstr = "no recovery";
159 break;
160 case TRY_AGAIN:
161 errorstr = "try again";
162 break;
163 }
164 LOG_ERROR("gethostbyname: %s", errorstr);
165 return ERROR_FAIL;
166 }
167
168 struct sockaddr_in addr;
169 addr.sin_family = AF_INET;
170 addr.sin_port = htons(remote_bitbang_port);
171 addr.sin_addr = *(struct in_addr *)hent->h_addr;
172 if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
173 LOG_ERROR("connect: %s", strerror(errno));
174 return ERROR_FAIL;
175 }
176
177 remote_bitbang_in = fdopen(fd, "r");
178 if (remote_bitbang_in == NULL) {
179 LOG_ERROR("fdopen: failed to open read stream");
180 return ERROR_FAIL;
181 }
182
183 remote_bitbang_out = fdopen(fd, "w");
184 if (remote_bitbang_out == NULL) {
185 LOG_ERROR("fdopen: failed to open write stream");
186 return ERROR_FAIL;
187 }
188
189 LOG_INFO("remote_bitbang driver initialized");
190 return ERROR_OK;
191 }
192
193 static int remote_bitbang_init_unix(void)
194 {
195 LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
196 int fd = socket(PF_UNIX, SOCK_STREAM, 0);
197 if (fd < 0) {
198 LOG_ERROR("socket: %s", strerror(errno));
199 return ERROR_FAIL;
200 }
201
202 struct sockaddr_un addr;
203 addr.sun_family = AF_UNIX;
204 strncpy(addr.sun_path, remote_bitbang_host, UNIX_PATH_LEN);
205 addr.sun_path[UNIX_PATH_LEN-1] = '\0';
206
207 if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
208 LOG_ERROR("connect: %s", strerror(errno));
209 return ERROR_FAIL;
210 }
211
212 remote_bitbang_in = fdopen(fd, "r");
213 if (remote_bitbang_in == NULL) {
214 LOG_ERROR("fdopen: failed to open read stream");
215 return ERROR_FAIL;
216 }
217
218 remote_bitbang_out = fdopen(fd, "w");
219 if (remote_bitbang_out == NULL) {
220 LOG_ERROR("fdopen: failed to open write stream");
221 return ERROR_FAIL;
222 }
223
224 LOG_INFO("remote_bitbang driver initialized");
225 return ERROR_OK;
226 }
227
228 static int remote_bitbang_init(void)
229 {
230 bitbang_interface = &remote_bitbang_bitbang;
231
232 LOG_INFO("Initializing remote_bitbang driver");
233 if (remote_bitbang_port == 0)
234 return remote_bitbang_init_unix();
235 return remote_bitbang_init_tcp();
236 }
237
238 static int remote_bitbang_khz(int khz, int *jtag_speed)
239 {
240 *jtag_speed = 0;
241 return ERROR_OK;
242 }
243
244 static int remote_bitbang_speed_div(int speed, int *khz)
245 {
246 /* I don't think this really matters any. */
247 *khz = 1;
248 return ERROR_OK;
249 }
250
251 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
252 {
253 if (CMD_ARGC == 1) {
254 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], remote_bitbang_port);
255 return ERROR_OK;
256 }
257 return ERROR_COMMAND_SYNTAX_ERROR;
258 }
259
260 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
261 {
262 if (CMD_ARGC == 1) {
263 strncpy(remote_bitbang_host, CMD_ARGV[0], REMOTE_BITBANG_HOST_MAX);
264 remote_bitbang_host[REMOTE_BITBANG_HOST_MAX-1] = '\0';
265 return ERROR_OK;
266 }
267 return ERROR_COMMAND_SYNTAX_ERROR;
268 }
269
270 static const struct command_registration remote_bitbang_command_handlers[] = {
271 {
272 .name = "remote_bitbang_port",
273 .handler = remote_bitbang_handle_remote_bitbang_port_command,
274 .mode = COMMAND_CONFIG,
275 .help = "Set the port to use to connect to the remote jtag.\n"
276 " if 0, use unix sockets to connect to the remote jtag.",
277 .usage = "port_number",
278 },
279 {
280 .name = "remote_bitbang_host",
281 .handler = remote_bitbang_handle_remote_bitbang_host_command,
282 .mode = COMMAND_CONFIG,
283 .help = "Set the host to use to connect to the remote jtag.\n"
284 " if port is 0, this is the name of the unix socket to use.",
285 .usage = "host_name",
286 },
287 COMMAND_REGISTRATION_DONE,
288 };
289
290 struct jtag_interface remote_bitbang_interface = {
291 .name = "remote_bitbang",
292 .execute_queue = &bitbang_execute_queue,
293 .speed = &remote_bitbang_speed,
294 .commands = remote_bitbang_command_handlers,
295 .init = &remote_bitbang_init,
296 .quit = &remote_bitbang_quit,
297 .khz = &remote_bitbang_khz,
298 .speed_div = &remote_bitbang_speed_div,
299 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)