Attachment 'ap51-flash-update.patch'
Download 1 Index: utils/ap51-flash/files/ap51-flash.init
2 ===================================================================
3 --- utils/ap51-flash/files/ap51-flash.init (revision 21552)
4 +++ utils/ap51-flash/files/ap51-flash.init (working copy)
5 @@ -1,45 +1,68 @@
6 #!/bin/sh /etc/rc.common
7 # Copyright (C) 2010 OpenWrt.org
8
9 -START=20
10 +START=45
11
12 NAME=ap51-flash
13 +PIPE_PATH="/tmp/ap51-flash-pipe"
14
15 start_daemon() {
16 local cfg="$1"
17 + local ifname="$1"
18
19 + if [ -z "`ifconfig | grep "^$cfg`" ]; then
20 + ifname="`echo $cfg | sed 's/_/./'`"
21 + fi
22 +
23 config_get_bool loop "$cfg" loop
24 - config_get ifname "$cfg" ifname
25 config_get rootfs "$cfg" rootfs
26 config_get kernel "$cfg" kernel
27 config_get ubnt "$cfg" ubnt
28 +
29 + [ -n "$rootfs" ] && rootfs="--rootfs $rootfs"
30 + [ -n "$kernel" ] && kernel="--kernel $kernel"
31 + [ -n "$ubnt" ] && ubnt="--ubnt $ubnt"
32 +
33 [ "$loop" != "1" ] && loop=0
34 if [ -n "$ifname" -a -n "$rootfs" -a -n "$kernel" ] || \
35 [ -n "$ifname" -a -n "$ubnt" ]; then
36 - PID="`cat /var/run/$NAME.sh-$ifname.pid 2> /dev/null`"
37 + PID="`cat /var/run/$NAME-$ifname.pid 2> /dev/null`"
38 [ -z "`ps | grep "^.[ ]*$PID "`" ] && \
39 - rm /var/run/$NAME.sh-$ifname.pid
40 - [ -n "`ls /var/run/$NAME.sh-$ifname.pid 2> /dev/null`" ] && {
41 + rm /var/run/$NAME-$ifname.pid
42 + [ -n "`ls /var/run/$NAME-$ifname.pid 2> /dev/null`" ] && {
43 echo "Can't start more than one ap51-flash for interface $ifname!"
44 return 0
45 }
46 - start-stop-daemon -S -b -m -p /var/run/$NAME.sh-$ifname.pid -n $NAME.sh \
47 - -x /usr/lib/ap51-flash/$NAME.sh -- "$loop" "$ifname" "$rootfs" "$kernel" "$ubnt"
48 + start-stop-daemon -S -b -m -p /var/run/$NAME-$ifname.pid -n $NAME \
49 + -x /usr/sbin/$NAME -- --flash-from-file --pipe $PIPE_PATH $rootfs $kernel $ubnt $ifname
50 fi
51 }
52
53 +start_loop_script() {
54 + PID="`cat /var/run/$NAME.sh-$ifname.pid 2> /dev/null`"
55 + [ -z "`ps | grep "^.[ ]*$PID "`" ] && \
56 + rm /var/run/$NAME.sh.pid
57 + [ -n "`ls /var/run/$NAME.sh.pid 2> /dev/null`" ] && {
58 + echo "Can't start more than one ap51-flash loop script!"
59 + return 0
60 + }
61 + start-stop-daemon -S -b -m -p /var/run/$NAME.sh.pid -n $NAME.sh \
62 + -x /usr/lib/ap51-flash/ap51-flash.sh
63 +}
64 +
65 start() {
66 + mount -a
67 + [ -e "$PIPE_PATH" ] || mkfifo $PIPE_PATH
68 config_load ap51-flash
69 config_foreach start_daemon flash
70 + sleep 1
71 + [ -e "$PIPE_PATH" ] && start_loop_script
72 }
73
74 stop() {
75 - # Terminating all ap51-flash processes
76 - echo "WARNING: Going to teminate all ap51-flash processes! (hope you made sure that they're not flashing right now)"
77 - echo "OR you can stop this with Ctrl+c within 10 seconds"
78 - sleep 10
79 + # Terminating all ap51-flash processes (if they are not flashing anymore)
80 local pidfile
81 - for pidfile in `ls /var/run/${NAME}.sh-*.pid 2> /dev/null`; do
82 + for pidfile in `ls /var/run/${NAME}.sh.pid 2> /dev/null`; do
83 start-stop-daemon -K -s TERM -p "${pidfile}" -n "${NAME}.sh" >/dev/null
84 rm -f "${pidfile}"
85 done
86 @@ -47,4 +70,19 @@
87 start-stop-daemon -K -s TERM -p "${pidfile}" -n "${NAME}" >/dev/null
88 rm -f "${pidfile}"
89 done
90 + [ -e "$PIPE_PATH" ] && rm $PIPE_PATH
91 }
92 +
93 +forcestop() {
94 + # Kill all ap51-flash processes
95 + local pidfile
96 + for pidfile in `ls /var/run/${NAME}.sh.pid 2> /dev/null`; do
97 + start-stop-daemon -K -s KILL -p "${pidfile}" -n "${NAME}.sh" >/dev/null
98 + rm -f "${pidfile}"
99 + done
100 + for pidfile in `ls /var/run/${NAME}.pid 2> /dev/null`; do
101 + start-stop-daemon -K -s KILL -p "${pidfile}" -n "${NAME}" >/dev/null
102 + rm -f "${pidfile}"
103 + done
104 + [ -e "$PIPE_PATH" ] && rm $PIPE_PATH
105 +}
106 Index: utils/ap51-flash/files/ap51-flash.sh
107 ===================================================================
108 --- utils/ap51-flash/files/ap51-flash.sh (revision 21552)
109 +++ utils/ap51-flash/files/ap51-flash.sh (working copy)
110 @@ -1,21 +1,47 @@
111 -#!/bin/sh
112 +#!/bin/sh /etc/rc.common
113 +# Copyright (C) 2010 OpenWrt.org
114
115 NAME=ap51-flash
116 -rootfs=""
117 -kernel=""
118 -ubnt=""
119 +PIPE_PATH="/tmp/ap51-flash-pipe"
120
121 -[ $1 -eq "1" ] && loop="1"
122 -ifname="$2"
123 -[ -n "$3" ] && rootfs="--rootfs $3"
124 -[ -n "$4" ] && kernel="--kernel $4"
125 -[ -n "$5" ] && ubnt="--ubnt $5"
126 +config_load ap51-flash
127 +[ -e "$PIPE_PATH" ] || mkfifo $PIPE_PATH
128
129 -while [ 1 ]; do
130 - start-stop-daemon -S -m -p /var/run/$NAME-$ifname.pid -n $NAME \
131 - -x /usr/sbin/$NAME -- --flash-from-file $rootfs $kernel $ubnt $ifname
132 +while true; do
133 + read ifname evtype msg < $PIPE_PATH
134 + echo "iface: $ifname, evtype: $evtype, msg: $msg" >> /tmp/ap51-flash.log
135
136 + [ "$evtype" != "SUCCESS" ] && continue
137 +
138 + PID="`cat /var/run/$NAME-$ifname.pid 2> /dev/null`"
139 rm /var/run/$NAME-$ifname.pid
140 - [ "$loop" != "1" ] && break
141 - sleep 15
142 +
143 + local cfg="$ifname"
144 + [ -z "`grep \"^$ifname\"`" ] && \
145 + cfg="`echo $cfg | sed 's/\./_/'`"
146 +
147 + config_get_bool loop "$cfg" loop
148 + config_get rootfs "$cfg" rootfs
149 + config_get kernel "$cfg" kernel
150 + config_get ubnt "$cfg" ubnt
151 +
152 + [ "$loop" != "1" ] && continue
153 +
154 + [ -n "$rootfs" ] && rootfs="--rootfs $rootfs"
155 + [ -n "$kernel" ] && kernel="--kernel $kernel"
156 + [ -n "$ubnt" ] && ubnt="--ubnt $ubnt"
157 +
158 + wait $PID
159 +
160 + if [ -n "$ifname" -a -n "$rootfs" -a -n "$kernel" ] || \
161 + [ -n "$ifname" -a -n "$ubnt" ]; then
162 + [ -z "`ps | grep "^.[ ]*$PID "`" ] && \
163 + rm /var/run/$NAME.sh-$ifname.pid
164 + [ -n "`ls /var/run/$NAME.sh-$ifname.pid 2> /dev/null`" ] && {
165 + echo "Can't start more than one ap51-flash for interface $ifname!"
166 + return 0
167 + }
168 + start-stop-daemon -S -b -m -p /var/run/$NAME-$ifname.pid -n $NAME \
169 + -x /usr/sbin/$NAME -- --flash-from-file --pipe $PIPE_PATH $rootfs $kernel $ubnt $ifname
170 + fi
171 done
172 Index: utils/ap51-flash/patches/0007-ap51-flash-Add-countdown-waits-for-flash-from-file-m.patch
173 ===================================================================
174 --- utils/ap51-flash/patches/0007-ap51-flash-Add-countdown-waits-for-flash-from-file-m.patch (revision 0)
175 +++ utils/ap51-flash/patches/0007-ap51-flash-Add-countdown-waits-for-flash-from-file-m.patch (revision 0)
176 @@ -0,0 +1,71 @@
177 +From 1a7b22d7fa6d83105748a459fe88b521ef7cf209 Mon Sep 17 00:00:00 2001
178 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
179 +Date: Sun, 25 Apr 2010 13:33:50 +0200
180 +Subject: [PATCH 7/7] ap51-flash: Add countdown/waits for flash-from-file mode
181 +MIME-Version: 1.0
182 +Content-Type: text/plain; charset=UTF-8
183 +Content-Transfer-Encoding: 8bit
184 +
185 +It is safer to add some time in between informing applications/users of
186 +a starting flash-procedure and the actual start of the flash-procedure
187 +itself. A user might unplug a router which is just going to be flashed.
188 +This patch shell avoid this "human-machine" race condition by giving
189 +him/her a 5 seconds reaction/noticing time.
190 +Also adding a 15 seconds wait after flashing procedure (after the reboot
191 +detection) to make sure to only terminate ap51-flash when the just
192 +flashed device is no more in its flashing-critical section.
193 +
194 +Signed-off-by: Linus Lüssing <linus.luessing@web.de>
195 +---
196 + ap51-flash.c | 11 +++++++++++
197 + ap51-flash.h | 5 +++++
198 + 2 files changed, 16 insertions(+), 0 deletions(-)
199 +
200 +diff --git a/ap51-flash.c b/ap51-flash.c
201 +index 891fe44..7307064 100644
202 +--- a/ap51-flash.c
203 ++++ b/ap51-flash.c
204 +@@ -438,6 +438,12 @@ sanity_check:
205 + goto err_close;
206 + }
207 +
208 ++#if defined(LINUX) && defined(FLASH_FROM_FILE)
209 ++ /* Some time (for the UI) to react/notice */
210 ++ printf("Starting flash procedure in %d seconds!\n", COUNTDOWN_TIMER);
211 ++ sleep(COUNTDOWN_TIMER);
212 ++#endif
213 ++
214 + if (device_info->kernel_part_size < kernel_size)
215 + device_info->kernel_part_size = kernel_size;
216 +
217 +@@ -1122,6 +1128,11 @@ init_socket:
218 + goto sock_close;
219 +
220 + ret = detect_reboot(flash_mode, &srcipaddr, &dstipaddr, &srcmac, &dstmac);
221 ++#if defined(LINUX) && defined(FLASH_FROM_FILE)
222 ++ /* Avoid reflashing the same device (in looping scripts i.e.),
223 ++ * wait until a device left its critical flashing section */
224 ++ sleep(COUNTDOWN_TIMER);
225 ++#endif
226 + if (ret != 0)
227 + pipe_msg("ERROR", "could not detect the reboot of the same device");
228 + else
229 +diff --git a/ap51-flash.h b/ap51-flash.h
230 +index 6e064de..cbc2875 100644
231 +--- a/ap51-flash.h
232 ++++ b/ap51-flash.h
233 +@@ -67,6 +67,11 @@
234 + #error Unsupported PLATFORM
235 + #endif
236 +
237 ++#if defined(FLASH_FROM_FILE)
238 ++#define COUNTDOWN_TIMER 5
239 ++#define BOOTWAIT_TIMER 15
240 ++#endif
241 ++
242 + typedef struct ap51_flash_state {
243 + struct psock p;
244 + char inputbuffer[4096];
245 +--
246 +1.7.1
247 +
248 Index: utils/ap51-flash/patches/0002-print-status-to-pipe.patch
249 ===================================================================
250 --- utils/ap51-flash/patches/0002-print-status-to-pipe.patch (revision 0)
251 +++ utils/ap51-flash/patches/0002-print-status-to-pipe.patch (revision 0)
252 @@ -0,0 +1,276 @@
253 +From 32644d1de0e70c0d3a6d091b7fcc09dbf7fbe615 Mon Sep 17 00:00:00 2001
254 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
255 +Date: Sun, 25 Apr 2010 12:54:20 +0200
256 +Subject: [PATCH 2/7] print status to pipe
257 +
258 +from Marek
259 +---
260 + ap51-flash.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
261 + ap51-flash.h | 4 +++
262 + main.c | 8 +++++-
263 + packet.c | 2 +
264 + 4 files changed, 92 insertions(+), 3 deletions(-)
265 +
266 +diff --git a/ap51-flash.c b/ap51-flash.c
267 +index 3244620..a1072ab 100644
268 +--- a/ap51-flash.c
269 ++++ b/ap51-flash.c
270 +@@ -39,6 +39,11 @@ static int uncomp_loader = 0;
271 + static int nvram_part_size = 0x00000000;
272 + static int rootfs_part_size = 0x00000000;
273 +
274 ++#if defined(LINUX) && defined(FLASH_FROM_FILE)
275 ++static char *ap51_iface = NULL;
276 ++char *pipe_path = NULL;
277 ++#endif
278 ++
279 + char flash_mode = MODE_NONE;
280 + int flash_from_file = 0;
281 + struct flash_from_file fff_data[FFF_NUM];
282 +@@ -86,6 +91,40 @@ void uip_log(char *m)
283 + #endif
284 + }
285 +
286 ++#if defined(LINUX) && defined(FLASH_FROM_FILE)
287 ++void pipe_msg(char *event_type, char *msg)
288 ++{
289 ++ int fd, ret;
290 ++
291 ++ if (!flash_from_file)
292 ++ return;
293 ++
294 ++ if (!pipe_path)
295 ++ return;
296 ++
297 ++ if (!ap51_iface)
298 ++ return;
299 ++
300 ++ fd = open(pipe_path, O_WRONLY);
301 ++ if (fd < 0)
302 ++ return;
303 ++
304 ++ ret = flock(fd, LOCK_EX);
305 ++ if (ret < 0)
306 ++ goto out;
307 ++
308 ++ dprintf(fd, "%s %s %s\n", ap51_iface, event_type, msg);
309 ++ flock(fd, LOCK_UN);
310 ++
311 ++out:
312 ++ close(fd);
313 ++}
314 ++#else
315 ++void pipe_msg(char *event_type, char *msg)
316 ++{
317 ++}
318 ++#endif
319 ++
320 + static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac, struct uip_eth_addr* dmac, int special)
321 + {
322 + int ret, len, arp_replies = 0, arp_grat_packets = 0;
323 +@@ -348,6 +387,11 @@ sanity_check:
324 + rootfs_part_size, device_info->kernel_part_size, nvram_part_size,
325 + rootfs_part_size + device_info->kernel_part_size + nvram_part_size);
326 +
327 ++ if (device_info == &flash_8mb_info)
328 ++ pipe_msg("FLASHING", "redboot_8MB");
329 ++ else
330 ++ pipe_msg("FLASHING", "redboot_4MB");
331 ++
332 + sprintf(str, "ip_addr -l %d.%d.%d.%d/8 -h %d.%d.%d.%d\n",
333 + P(&dstipaddr)[0], P(&dstipaddr)[1], P(&dstipaddr)[2], P(&dstipaddr)[3],
334 + P(&srcipaddr)[0], P(&srcipaddr)[1], P(&srcipaddr)[2], P(&srcipaddr)[3]);
335 +@@ -687,6 +731,7 @@ int ap51_flash(char *iface, char *rootfs_filename, char *kernel_filename, int nv
336 + nvram_part_size = FLASH_PAGE_SIZE;
337 +
338 + #if defined(FLASH_FROM_FILE)
339 ++ char *fff_desc;
340 + int i;
341 +
342 + if (flash_from_file) {
343 +@@ -700,9 +745,24 @@ int ap51_flash(char *iface, char *rootfs_filename, char *kernel_filename, int nv
344 + if (ret != 0)
345 + return ret;
346 +
347 ++ switch (i) {
348 ++ case 0:
349 ++ fff_desc = "rootfs";
350 ++ break;
351 ++ case 1:
352 ++ fff_desc = "kernel";
353 ++ break;
354 ++ case 2:
355 ++ fff_desc = "ubnt";
356 ++ break;
357 ++ case 3:
358 ++ default:
359 ++ fff_desc = "uboot";
360 ++ break;
361 ++ }
362 ++
363 + printf("Reading %s file %s with %d bytes ...\n",
364 +- (i == 0 ? "rootfs" : (i == 1 ? "kernel" : "ubnt")),
365 +- fff_data[i].fname, fff_data[i].flash_size);
366 ++ fff_desc, fff_data[i].fname, fff_data[i].flash_size);
367 + }
368 +
369 + goto init_socket;
370 +@@ -822,6 +882,10 @@ init_socket:
371 + if (!socket_dev)
372 + socket_dev = iface;
373 +
374 ++#if defined(LINUX) && defined(FLASH_FROM_FILE)
375 ++ ap51_iface = socket_dev;
376 ++#endif
377 ++
378 + ret = ap51_init(socket_dev, &srcipaddr, &dstipaddr, &srcmac, &dstmac, special);
379 +
380 + if (ret != 0)
381 +@@ -849,6 +913,7 @@ init_socket:
382 + if ((!fff_data[FFF_ROOTFS].fname) ||
383 + (!fff_data[FFF_KERNEL].fname)) {
384 + fprintf(stderr, "Error - redboot enabled device detected but rootfs & kernel file not available\n");
385 ++ pipe_msg("ERROR", "no kernel and rootfs for redboot available");
386 + goto sock_close;
387 + }
388 + } else {
389 +@@ -908,6 +973,7 @@ init_socket:
390 + if (flash_from_file) {
391 + if (!fff_data[FFF_UBNT].fname) {
392 + fprintf(stderr, "Error - ubiquiti device detected but ubiquiti file not available\n");
393 ++ pipe_msg("ERROR", "no image for ubiquiti available");
394 + goto sock_close;
395 + }
396 + } else {
397 +@@ -924,6 +990,7 @@ init_socket:
398 + tftp_xfer_buff = (flash_from_file ? (unsigned char *)&fff_data[FFF_UBNT] : rootfs_buf);
399 + tftp_xfer_size = (flash_from_file ? fff_data[FFF_UBNT].flash_size : rootfs_size);
400 + printf("Ubiquiti device detected - using TFTP client to flash\n");
401 ++ pipe_msg("FLASHING", "ubiquiti");
402 + break;
403 + case MODE_TFTP_SERVER:
404 + #if defined(EMBEDDED_DATA)
405 +@@ -962,6 +1029,7 @@ init_socket:
406 + if (flash_from_file) {
407 + if (!fff_data[FFF_UBOOT].fname) {
408 + fprintf(stderr, "Error - uboot device detected but uboot file not available\n");
409 ++ pipe_msg("ERROR", "no image for uboot available");
410 + goto sock_close;
411 + }
412 + } else {
413 +@@ -976,14 +1044,23 @@ init_socket:
414 + }
415 +
416 + printf("Uboot device detected - using TFTP server to flash\n");
417 ++ pipe_msg("FLASHING", "uboot");
418 + break;
419 + default:
420 + fprintf(stderr, "Error - could not auto-detect flash mode!\n");
421 ++ pipe_msg("ERROR", "could not auto-detect flash mode");
422 + goto sock_close;
423 + }
424 +
425 ++#if defined(LINUX) && defined(FLASH_FROM_FILE)
426 ++ signal(SIGTERM, SIG_IGN);
427 ++#endif
428 ++
429 + ret = fw_upload();
430 +
431 ++ if (ret == 0)
432 ++ pipe_msg("SUCCESS", "");
433 ++
434 + sock_close:
435 + socket_close(socket_dev);
436 + return ret;
437 +diff --git a/ap51-flash.h b/ap51-flash.h
438 +index 2e59519..4dec003 100644
439 +--- a/ap51-flash.h
440 ++++ b/ap51-flash.h
441 +@@ -57,6 +57,8 @@
442 + #include <netinet/tcp.h>
443 + #include <netinet/udp.h>
444 + #include <arpa/inet.h>
445 ++#include <signal.h>
446 ++#include <sys/file.h>
447 + #define PCAP_TIMEOUT_MS 200
448 + #if !defined(NO_LIBPCAP)
449 + #include <pcap.h>
450 +@@ -138,6 +140,7 @@ enum {
451 + typedef int uip_udp_appstate_t;
452 + void ap51_flash_tftp_appcall(void);
453 +
454 ++void pipe_msg(char *event_type, char *msg);
455 + int ap51_flash(char* device, char* rootfs_filename, char* kernel_filename, int nvram, int uncomp, int special);
456 + void ap51_flash_appcall(void);
457 + void handle_uip_tcp(const unsigned char *packet_buff, unsigned int packet_len);
458 +@@ -153,6 +156,7 @@ extern int rootfs_size;
459 + extern int kernel_size;
460 + extern char flash_mode;
461 + extern int flash_from_file;
462 ++extern char *pipe_path;
463 + extern struct flash_from_file fff_data[];
464 +
465 + #endif /* __ap51_FLASH_H__ */
466 +diff --git a/main.c b/main.c
467 +index 44f0386..9e5c0da 100644
468 +--- a/main.c
469 ++++ b/main.c
470 +@@ -48,6 +48,7 @@ void usage(char *prgname)
471 + fprintf(stderr, " --kernel path to kernel file\n");
472 + fprintf(stderr, " --ubnt path to ubiquiti image\n");
473 + fprintf(stderr, " --uboot path to uboot image\n");
474 ++ fprintf(stderr, " --pipe write status messages to pipe\n");
475 + #endif
476 +
477 + fprintf(stderr, "\nThe 'ethdevice' has to be one of the devices that are part of the supported device list which follows.\nYou can either specify its name or the interface number.\n");
478 +@@ -66,6 +67,7 @@ int main(int argc, char* argv[])
479 + {
480 + {"uboot", required_argument, 0, 'b'},
481 + {"flash-from-file", no_argument, 0, 'f'},
482 ++ {"pipe", required_argument, 0, 'p'},
483 + {"rootfs", required_argument, 0, 'r'},
484 + {"kernel", required_argument, 0, 'k'},
485 + {"ubnt", required_argument, 0, 'u'},
486 +@@ -118,7 +120,7 @@ int main(int argc, char* argv[])
487 + for (i = 0; i < FFF_NUM; i++)
488 + fff_data[i].fname = NULL;
489 +
490 +- while ((optchar = getopt_long(argc, argv, "fb:k:r:u:", long_options, &option_index)) != -1) {
491 ++ while ((optchar = getopt_long(argc, argv, "fb:k:p:r:u:", long_options, &option_index)) != -1) {
492 + switch (optchar) {
493 + case 'b':
494 + fff_data[FFF_UBOOT].fname = optarg;
495 +@@ -132,6 +134,10 @@ int main(int argc, char* argv[])
496 + fff_data[FFF_KERNEL].fname = optarg;
497 + found_args += 2;
498 + break;
499 ++ case 'p':
500 ++ pipe_path = optarg;
501 ++ found_args += 2;
502 ++ break;
503 + case 'r':
504 + fff_data[FFF_ROOTFS].fname = optarg;
505 + found_args += 2;
506 +diff --git a/packet.c b/packet.c
507 +index 61ea04b..a932098 100644
508 +--- a/packet.c
509 ++++ b/packet.c
510 +@@ -184,6 +184,7 @@ static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_l
511 + ((tftp_xfer_size + 511) / 512));
512 + } else {
513 + fprintf(stderr, "Unknown file name: %s\n", file_name);
514 ++ pipe_msg("ERROR", "unknown TFTP file name requested");
515 + return -1;
516 + }
517 +
518 +@@ -256,6 +257,7 @@ static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_l
519 + else
520 + fprintf(stderr, "Received TFTP error code: %d\n", block);
521 +
522 ++ pipe_msg("ERROR", "received TFTP error");
523 + return -1;
524 + break;
525 + default:
526 +--
527 +1.7.1
528 +
529 Index: utils/ap51-flash/patches/0006-ap51-flash-Return-SUCCESS-exit-only-if-reboot-detect.patch
530 ===================================================================
531 --- utils/ap51-flash/patches/0006-ap51-flash-Return-SUCCESS-exit-only-if-reboot-detect.patch (revision 0)
532 +++ utils/ap51-flash/patches/0006-ap51-flash-Return-SUCCESS-exit-only-if-reboot-detect.patch (revision 0)
533 @@ -0,0 +1,88 @@
534 +From 4730a17161f08dfe86bf6d888027cb702a760726 Mon Sep 17 00:00:00 2001
535 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
536 +Date: Tue, 4 May 2010 02:55:45 +0200
537 +Subject: [PATCH 6/7] ap51-flash: Return SUCCESS / exit only if reboot detected
538 +MIME-Version: 1.0
539 +Content-Type: text/plain; charset=UTF-8
540 +Content-Transfer-Encoding: 8bit
541 +
542 +At least for devices using uboot or redboot, the reboot can be
543 +determined very reliably by just starting and waiting for the device
544 +detection of the same one again. This is informing the ap51-flash user
545 +more reliably too, in that this user can be sure that the flashing
546 +procedure for the uboot/redboot devices has really finished.
547 +
548 +Signed-off-by: Linus Lüssing <linus.luessing@web.de>
549 +---
550 + ap51-flash.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
551 + 1 files changed, 46 insertions(+), 1 deletions(-)
552 +
553 +diff --git a/ap51-flash.c b/ap51-flash.c
554 +index 9b4028b..891fe44 100644
555 +--- a/ap51-flash.c
556 ++++ b/ap51-flash.c
557 +@@ -246,6 +246,46 @@ read_packet:
558 + return flash_mode;
559 + }
560 +
561 ++/* Returns 0 if the same device is being detected again */
562 ++static int detect_reboot(const char flash_mode, uip_ipaddr_t* sip, uip_ipaddr_t* dip,
563 ++ struct uip_eth_addr* smac, struct uip_eth_addr* dmac)
564 ++{
565 ++ char new_flash_mode;
566 ++ struct ether_header *recv_ethhdr = NULL;
567 ++ uip_ipaddr_t new_sip, new_dip;
568 ++ struct uip_eth_addr new_dmac;
569 ++
570 ++ // We are not able to detect a ubnt-devices reboot reliably, therefore
571 ++ // ignoring it and returning true anyway (as it had been done before).
572 ++ if (flash_mode == MODE_TFTP_SERVER)
573 ++ return 0;
574 ++
575 ++ arp_packet_init();
576 ++
577 ++ arphdr->ea_hdr.ar_op = htons(ARPOP_REQUEST);
578 ++ memcpy(arphdr->arp_sha, smac->addr, ETH_ALEN);
579 ++ // Resetting arp-target mac, got somehow set somewhere?
580 ++ memset(arphdr->arp_tha, 0, ETH_ALEN);
581 ++ *((unsigned int *)arphdr->arp_spa) = htonl(ubnt_local_ip);
582 ++ *((unsigned int *)arphdr->arp_tpa) = htonl(ubnt_remote_ip);
583 ++
584 ++ new_flash_mode = detect_mode(&recv_ethhdr);
585 ++ extract_ethhdr_info(recv_ethhdr, &new_sip, &new_dip, &new_dmac);
586 ++
587 ++ if ((flash_mode == MODE_REDBOOT) || (flash_mode == MODE_MAYBE_REDBOOT))
588 ++ P(new_sip)[3] = 0 == P(new_sip)[3] ? 1 : 0;
589 ++
590 ++ if (flash_mode != new_flash_mode)
591 ++ return 1;
592 ++
593 ++ if (memcmp(sip, &new_sip, sizeof(new_sip)) ||
594 ++ memcmp(dip, &new_dip, sizeof(new_dip)) ||
595 ++ memcmp(dmac, &new_dmac, sizeof(new_dmac)) )
596 ++ return 1;
597 ++
598 ++ return 0;
599 ++}
600 ++
601 + static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac,
602 + struct uip_eth_addr* dmac, int special, char *flash_mode)
603 + {
604 +@@ -1078,8 +1118,13 @@ init_socket:
605 + #endif
606 +
607 + ret = fw_upload(flash_mode);
608 ++ if (ret != 0)
609 ++ goto sock_close;
610 +
611 +- if (ret == 0)
612 ++ ret = detect_reboot(flash_mode, &srcipaddr, &dstipaddr, &srcmac, &dstmac);
613 ++ if (ret != 0)
614 ++ pipe_msg("ERROR", "could not detect the reboot of the same device");
615 ++ else
616 + pipe_msg("SUCCESS", "");
617 +
618 + sock_close:
619 +--
620 +1.7.1
621 +
622 Index: utils/ap51-flash/patches/0003-ap51-flash-Convert-flash_mode-to-local-variable.patch
623 ===================================================================
624 --- utils/ap51-flash/patches/0003-ap51-flash-Convert-flash_mode-to-local-variable.patch (revision 0)
625 +++ utils/ap51-flash/patches/0003-ap51-flash-Convert-flash_mode-to-local-variable.patch (revision 0)
626 @@ -0,0 +1,167 @@
627 +From 478b06d9dad452fe4d74b18601da171f4f57754c Mon Sep 17 00:00:00 2001
628 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
629 +Date: Sun, 25 Apr 2010 13:41:01 +0200
630 +Subject: [PATCH 3/7] ap51-flash: Convert flash_mode to local variable
631 +MIME-Version: 1.0
632 +Content-Type: text/plain; charset=UTF-8
633 +Content-Transfer-Encoding: 8bit
634 +
635 +Not all functions (will) need the flash_mode information. Therefore
636 +making it a local variable to achieve a little more tight cohesion.
637 +
638 +Signed-off-by: Linus Lüssing <linus.luessing@web.de>
639 +---
640 + ap51-flash.c | 19 ++++++++++---------
641 + ap51-flash.h | 1 -
642 + packet.c | 6 +++---
643 + packet.h | 2 +-
644 + 4 files changed, 14 insertions(+), 14 deletions(-)
645 +
646 +diff --git a/ap51-flash.c b/ap51-flash.c
647 +index a1072ab..f7be682 100644
648 +--- a/ap51-flash.c
649 ++++ b/ap51-flash.c
650 +@@ -44,7 +44,6 @@ static char *ap51_iface = NULL;
651 + char *pipe_path = NULL;
652 + #endif
653 +
654 +-char flash_mode = MODE_NONE;
655 + int flash_from_file = 0;
656 + struct flash_from_file fff_data[FFF_NUM];
657 + unsigned int remote_ip;
658 +@@ -125,7 +124,8 @@ void pipe_msg(char *event_type, char *msg)
659 + }
660 + #endif
661 +
662 +-static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac, struct uip_eth_addr* dmac, int special)
663 ++static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac,
664 ++ struct uip_eth_addr* dmac, int special, char *flash_mode)
665 + {
666 + int ret, len, arp_replies = 0, arp_grat_packets = 0;
667 + const unsigned char *packet;
668 +@@ -211,7 +211,7 @@ read_packet:
669 + continue;
670 + }
671 +
672 +- flash_mode = MODE_TFTP_CLIENT;
673 ++ *flash_mode = MODE_TFTP_CLIENT;
674 + break;
675 + }
676 +
677 +@@ -223,7 +223,7 @@ read_packet:
678 + }
679 +
680 + if (*((unsigned int *)recv_arphdr->arp_tpa) == htonl(mr500_local_ip)) {
681 +- flash_mode = MODE_TFTP_SERVER;
682 ++ *flash_mode = MODE_TFTP_SERVER;
683 + break;
684 + }
685 +
686 +@@ -241,14 +241,14 @@ read_packet:
687 + continue;
688 + }
689 +
690 +- flash_mode = MODE_MAYBE_REDBOOT;
691 ++ *flash_mode = MODE_MAYBE_REDBOOT;
692 + break;
693 + }
694 +
695 + #if defined(DEBUG)
696 + fprintf(stderr, "device detection: redboot detected\n");
697 + #endif
698 +- flash_mode = MODE_REDBOOT;
699 ++ *flash_mode = MODE_REDBOOT;
700 + break;
701 + }
702 +
703 +@@ -259,7 +259,7 @@ read_packet:
704 + memmove(dip, recv_arphdr->arp_spa, 4);
705 + memmove(sip, recv_arphdr->arp_tpa, 4);
706 +
707 +- if ((flash_mode == MODE_REDBOOT) || (flash_mode == MODE_MAYBE_REDBOOT))
708 ++ if ((*flash_mode == MODE_REDBOOT) || (*flash_mode == MODE_MAYBE_REDBOOT))
709 + P(*sip)[3] = 0 == P(*sip)[3] ? 1 : 0;
710 +
711 + memcpy(&remote_ip, dip, 4);
712 +@@ -715,6 +715,7 @@ int ap51_flash(char *iface, char *rootfs_filename, char *kernel_filename, int nv
713 + uip_ipaddr_t netmask;
714 + struct uip_eth_addr srcmac, dstmac, brcmac;
715 + int ret, img_type = IMG_REDBOOT, fd, size = 0;
716 ++ char flash_mode = MODE_NONE;
717 + unsigned char *buf = 0;
718 + char *socket_dev;
719 +
720 +@@ -886,7 +887,7 @@ init_socket:
721 + ap51_iface = socket_dev;
722 + #endif
723 +
724 +- ret = ap51_init(socket_dev, &srcipaddr, &dstipaddr, &srcmac, &dstmac, special);
725 ++ ret = ap51_init(socket_dev, &srcipaddr, &dstipaddr, &srcmac, &dstmac, special, &flash_mode);
726 +
727 + if (ret != 0)
728 + return ret;
729 +@@ -1056,7 +1057,7 @@ init_socket:
730 + signal(SIGTERM, SIG_IGN);
731 + #endif
732 +
733 +- ret = fw_upload();
734 ++ ret = fw_upload(flash_mode);
735 +
736 + if (ret == 0)
737 + pipe_msg("SUCCESS", "");
738 +diff --git a/ap51-flash.h b/ap51-flash.h
739 +index 4dec003..6e064de 100644
740 +--- a/ap51-flash.h
741 ++++ b/ap51-flash.h
742 +@@ -154,7 +154,6 @@ extern unsigned char *rootfs_buf;
743 + extern unsigned char *kernel_buf;
744 + extern int rootfs_size;
745 + extern int kernel_size;
746 +-extern char flash_mode;
747 + extern int flash_from_file;
748 + extern char *pipe_path;
749 + extern struct flash_from_file fff_data[];
750 +diff --git a/packet.c b/packet.c
751 +index a932098..3ec07d1 100644
752 +--- a/packet.c
753 ++++ b/packet.c
754 +@@ -144,7 +144,7 @@ static int read_from_file(void *target_buff, void *data, int len, int seek_pos)
755 + return 0;
756 + }
757 +
758 +-static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_len)
759 ++static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_len, char flash_mode)
760 + {
761 + struct udphdr *rcv_udphdr = (struct udphdr *)packet_buff;
762 + unsigned short opcode, block;
763 +@@ -269,7 +269,7 @@ static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_l
764 + return 1;
765 + }
766 +
767 +-int fw_upload(void)
768 ++int fw_upload(char flash_mode)
769 + {
770 + const unsigned char *packet;
771 + struct ether_arp *rcv_arphdr;
772 +@@ -393,7 +393,7 @@ int fw_upload(void)
773 + switch (rcv_iphdr->protocol) {
774 + case IPPROTO_UDP:
775 + ret = tftp_transfer(packet + ETH_HLEN + (rcv_iphdr->ihl * 4),
776 +- len - ETH_HLEN - (rcv_iphdr->ihl * 4));
777 ++ len - ETH_HLEN - (rcv_iphdr->ihl * 4), flash_mode);
778 +
779 + if (ret < 0)
780 + return 1; /* error */
781 +diff --git a/packet.h b/packet.h
782 +index 3e06a43..a19b378 100644
783 +--- a/packet.h
784 ++++ b/packet.h
785 +@@ -36,4 +36,4 @@ extern char tcp_status;
786 +
787 + void arp_packet_init(void);
788 + int arp_packet_send(void);
789 +-int fw_upload(void);
790 ++int fw_upload(char flash_mode);
791 +--
792 +1.7.1
793 +
794 Index: utils/ap51-flash/patches/0004-ap51-flash-Export-device-detection-to-seperate-funct.patch
795 ===================================================================
796 --- utils/ap51-flash/patches/0004-ap51-flash-Export-device-detection-to-seperate-funct.patch (revision 0)
797 +++ utils/ap51-flash/patches/0004-ap51-flash-Export-device-detection-to-seperate-funct.patch (revision 0)
798 @@ -0,0 +1,153 @@
799 +From f5ba2ea8b085aa4d865083824c5571844a2273e0 Mon Sep 17 00:00:00 2001
800 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
801 +Date: Tue, 4 May 2010 02:54:05 +0200
802 +Subject: [PATCH 4/7] ap51-flash: Export device detection to seperate function
803 +MIME-Version: 1.0
804 +Content-Type: text/plain; charset=UTF-8
805 +Content-Transfer-Encoding: 8bit
806 +
807 +This will shrink the ap51_init() method to make its scope clearer and to
808 +enhance its readability. The device detection could then also be called
809 +in several places (if someone would like to detect the reboot of a
810 +device for verifying the flashing-procedure for instance).
811 +
812 +Signed-off-by: Linus Lüssing <linus.luessing@web.de>
813 +---
814 + ap51-flash.c | 79 +++++++++++++++++++++++++++++++++------------------------
815 + 1 files changed, 46 insertions(+), 33 deletions(-)
816 +
817 +diff --git a/ap51-flash.c b/ap51-flash.c
818 +index f7be682..3c6b495 100644
819 +--- a/ap51-flash.c
820 ++++ b/ap51-flash.c
821 +@@ -124,37 +124,13 @@ void pipe_msg(char *event_type, char *msg)
822 + }
823 + #endif
824 +
825 +-static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac,
826 +- struct uip_eth_addr* dmac, int special, char *flash_mode)
827 ++/* Returns the detected flash-mode and sets recv_ethhdr */
828 ++static char detect_mode(struct ether_header **recv_ethhdr)
829 + {
830 + int ret, len, arp_replies = 0, arp_grat_packets = 0;
831 ++ char flash_mode = MODE_NONE;
832 + const unsigned char *packet;
833 +- struct ether_header *recv_ethhdr;
834 + struct ether_arp *recv_arphdr;
835 +-#if defined(DEBUG)
836 +- int i;
837 +-#endif
838 +-
839 +- /* Open the output adapter */
840 +- ret = socket_open(dev);
841 +- if (ret != 0)
842 +- return ret;
843 +-
844 +- arp_packet_init();
845 +- memset(ethhdr->ether_dhost, 0xff, ETH_ALEN);
846 +- memcpy(ethhdr->ether_shost, smac->addr, ETH_ALEN);
847 +-
848 +- arphdr->ea_hdr.ar_op = htons(ARPOP_REQUEST);
849 +- memcpy(arphdr->arp_sha, smac->addr, ETH_ALEN);
850 +- *((unsigned int *)arphdr->arp_spa) = htonl(ubnt_local_ip);
851 +- *((unsigned int *)arphdr->arp_tpa) = htonl(ubnt_remote_ip);
852 +-
853 +-#if !defined(OSX)
854 +- // TODO: This is a seeming bug in OSX - won't work if we turn on non blocking - Lokkju
855 +- ret = socket_setnonblock();
856 +- if (ret != 0)
857 +- return ret;
858 +-#endif
859 +
860 + fprintf(stderr, "Waiting for device to run auto-detection.\nMake sure the device is connected directly!\n");
861 +
862 +@@ -175,9 +151,9 @@ read_packet:
863 + return ret;
864 + }
865 +
866 +- recv_ethhdr = (struct ether_header *)packet;
867 ++ *recv_ethhdr = (struct ether_header *)packet;
868 +
869 +- if (recv_ethhdr->ether_type != htons(ETHERTYPE_ARP)) {
870 ++ if ((*recv_ethhdr)->ether_type != htons(ETHERTYPE_ARP)) {
871 + #if defined(DEBUG)
872 + fprintf(stderr, "device detection: non-arp packet received\n");
873 + #endif
874 +@@ -211,7 +187,7 @@ read_packet:
875 + continue;
876 + }
877 +
878 +- *flash_mode = MODE_TFTP_CLIENT;
879 ++ flash_mode = MODE_TFTP_CLIENT;
880 + break;
881 + }
882 +
883 +@@ -223,7 +199,7 @@ read_packet:
884 + }
885 +
886 + if (*((unsigned int *)recv_arphdr->arp_tpa) == htonl(mr500_local_ip)) {
887 +- *flash_mode = MODE_TFTP_SERVER;
888 ++ flash_mode = MODE_TFTP_SERVER;
889 + break;
890 + }
891 +
892 +@@ -241,17 +217,54 @@ read_packet:
893 + continue;
894 + }
895 +
896 +- *flash_mode = MODE_MAYBE_REDBOOT;
897 ++ flash_mode = MODE_MAYBE_REDBOOT;
898 + break;
899 + }
900 +
901 + #if defined(DEBUG)
902 + fprintf(stderr, "device detection: redboot detected\n");
903 + #endif
904 +- *flash_mode = MODE_REDBOOT;
905 ++ flash_mode = MODE_REDBOOT;
906 + break;
907 + }
908 +
909 ++ return flash_mode;
910 ++}
911 ++
912 ++static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip_eth_addr* smac,
913 ++ struct uip_eth_addr* dmac, int special, char *flash_mode)
914 ++{
915 ++ int ret = 0;
916 ++ struct ether_header *recv_ethhdr = NULL;
917 ++ struct ether_arp *recv_arphdr;
918 ++#if defined(DEBUG)
919 ++ int i;
920 ++#endif
921 ++
922 ++ /* Open the output adapter */
923 ++ ret = socket_open(dev);
924 ++ if (ret != 0)
925 ++ return ret;
926 ++
927 ++ arp_packet_init();
928 ++ memset(ethhdr->ether_dhost, 0xff, ETH_ALEN);
929 ++ memcpy(ethhdr->ether_shost, smac->addr, ETH_ALEN);
930 ++
931 ++ arphdr->ea_hdr.ar_op = htons(ARPOP_REQUEST);
932 ++ memcpy(arphdr->arp_sha, smac->addr, ETH_ALEN);
933 ++ *((unsigned int *)arphdr->arp_spa) = htonl(ubnt_local_ip);
934 ++ *((unsigned int *)arphdr->arp_tpa) = htonl(ubnt_remote_ip);
935 ++
936 ++#if !defined(OSX)
937 ++ // TODO: This is a seeming bug in OSX - won't work if we turn on non blocking - Lokkju
938 ++ ret = socket_setnonblock();
939 ++ if (ret != 0)
940 ++ return ret;
941 ++#endif
942 ++
943 ++ *flash_mode = detect_mode(&recv_ethhdr);
944 ++ recv_arphdr = (struct ether_arp *)(recv_ethhdr + 1);
945 ++
946 + /* Grab MAC adress of device */
947 + memmove(dmac, recv_ethhdr->ether_shost, ETH_ALEN);
948 + memcpy(ethhdr->ether_dhost, recv_ethhdr->ether_shost, ETH_ALEN);
949 +--
950 +1.7.1
951 +
952 Index: utils/ap51-flash/patches/0005-ap51-flash-Exporting-ip-mac-determination-to-helper-.patch
953 ===================================================================
954 --- utils/ap51-flash/patches/0005-ap51-flash-Exporting-ip-mac-determination-to-helper-.patch (revision 0)
955 +++ utils/ap51-flash/patches/0005-ap51-flash-Exporting-ip-mac-determination-to-helper-.patch (revision 0)
956 @@ -0,0 +1,70 @@
957 +From 437a6e0b6f5cf6f26c7be1c21fe1b48ea9dd153c Mon Sep 17 00:00:00 2001
958 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
959 +Date: Tue, 4 May 2010 02:54:58 +0200
960 +Subject: [PATCH 5/7] ap51-flash: Exporting ip/mac determination to helper-function
961 +MIME-Version: 1.0
962 +Content-Type: text/plain; charset=UTF-8
963 +Content-Transfer-Encoding: 8bit
964 +
965 +This makes ap51_init() even smaller and abstracts the ip/mac
966 +determination/extraction in the ap51_init() method, leaving the task
967 +to the new helper function.
968 +
969 +Signed-off-by: Linus Lüssing <linus.luessing@web.de>
970 +---
971 + ap51-flash.c | 25 ++++++++++++++++---------
972 + 1 files changed, 16 insertions(+), 9 deletions(-)
973 +
974 +diff --git a/ap51-flash.c b/ap51-flash.c
975 +index 3c6b495..9b4028b 100644
976 +--- a/ap51-flash.c
977 ++++ b/ap51-flash.c
978 +@@ -124,6 +124,21 @@ void pipe_msg(char *event_type, char *msg)
979 + }
980 + #endif
981 +
982 ++static void extract_ethhdr_info(const struct ether_header *recv_ethhdr,
983 ++ uip_ipaddr_t *sip, uip_ipaddr_t *dip,
984 ++ struct uip_eth_addr *dmac)
985 ++{
986 ++ struct ether_arp *recv_arphdr =
987 ++ (struct ether_arp *)(recv_ethhdr + 1);
988 ++
989 ++ /* Grab MAC adress of device */
990 ++ memmove(dmac, recv_ethhdr->ether_shost, ETH_ALEN);
991 ++ memcpy(ethhdr->ether_dhost, recv_ethhdr->ether_shost, ETH_ALEN);
992 ++ /* Grab IP adress of device */
993 ++ memmove(dip, recv_arphdr->arp_spa, 4);
994 ++ memmove(sip, recv_arphdr->arp_tpa, 4);
995 ++}
996 ++
997 + /* Returns the detected flash-mode and sets recv_ethhdr */
998 + static char detect_mode(struct ether_header **recv_ethhdr)
999 + {
1000 +@@ -236,7 +251,6 @@ static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip
1001 + {
1002 + int ret = 0;
1003 + struct ether_header *recv_ethhdr = NULL;
1004 +- struct ether_arp *recv_arphdr;
1005 + #if defined(DEBUG)
1006 + int i;
1007 + #endif
1008 +@@ -263,14 +277,7 @@ static int ap51_init(char *dev, uip_ipaddr_t* sip, uip_ipaddr_t* dip, struct uip
1009 + #endif
1010 +
1011 + *flash_mode = detect_mode(&recv_ethhdr);
1012 +- recv_arphdr = (struct ether_arp *)(recv_ethhdr + 1);
1013 +-
1014 +- /* Grab MAC adress of device */
1015 +- memmove(dmac, recv_ethhdr->ether_shost, ETH_ALEN);
1016 +- memcpy(ethhdr->ether_dhost, recv_ethhdr->ether_shost, ETH_ALEN);
1017 +- /* Grab IP adress of device */
1018 +- memmove(dip, recv_arphdr->arp_spa, 4);
1019 +- memmove(sip, recv_arphdr->arp_tpa, 4);
1020 ++ extract_ethhdr_info(recv_ethhdr, dip, sip, dmac);
1021 +
1022 + if ((*flash_mode == MODE_REDBOOT) || (*flash_mode == MODE_MAYBE_REDBOOT))
1023 + P(*sip)[3] = 0 == P(*sip)[3] ? 1 : 0;
1024 +--
1025 +1.7.1
1026 +
1027 Index: utils/ap51-flash/patches/0001-add-mr500-support-flash-via-uboot.patch
1028 ===================================================================
1029 --- utils/ap51-flash/patches/0001-add-mr500-support-flash-via-uboot.patch (revision 0)
1030 +++ utils/ap51-flash/patches/0001-add-mr500-support-flash-via-uboot.patch (revision 0)
1031 @@ -0,0 +1,360 @@
1032 +From aa62616897c3ca43b758b4c29c106c7018920ebf Mon Sep 17 00:00:00 2001
1033 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
1034 +Date: Sun, 25 Apr 2010 12:53:43 +0200
1035 +Subject: [PATCH 1/7] add mr500 support (flash via uboot)
1036 +
1037 +from Marek
1038 +---
1039 + Makefile | 13 ++++++--
1040 + ap51-flash-res.h | 1 +
1041 + ap51-flash.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1042 + ap51-flash.h | 9 +++++
1043 + main.c | 18 ++++++++---
1044 + packet.c | 10 +++++-
1045 + 6 files changed, 121 insertions(+), 16 deletions(-)
1046 +
1047 +diff --git a/Makefile b/Makefile
1048 +index ba4d742..e710ab7 100644
1049 +--- a/Makefile
1050 ++++ b/Makefile
1051 +@@ -40,24 +40,28 @@ AP51_RC = ap51-flash-res
1052 + EMBED_KERNEL = openwrt-atheros-vmlinux.lzma
1053 + EMBED_ROOTFS = openwrt-atheros-root.squashfs
1054 + EMBED_UBNT_IMG = openwrt-atheros-ubnt2-squashfs.bin
1055 ++EMBED_UBOOT_IMG = openwrt-ralink-mr500-squashfs.bin
1056 +
1057 + ifneq ($(wildcard $(EMBED_KERNEL)),)
1058 + ifneq ($(wildcard $(EMBED_ROOTFS)),)
1059 + ifneq ($(wildcard $(EMBED_UBNT_IMG)),)
1060 ++ifneq ($(wildcard $(EMBED_UBOOT_IMG)),)
1061 + CFLAGS += -DEMBEDDED_DATA
1062 +-LIN_OBJS = kernel.o rootfs.o ubnt_img.o
1063 ++LIN_OBJS = kernel.o rootfs.o ubnt_img.o uboot_img.o
1064 + WIN_OBJS = $(AP51_RC).o
1065 + OSX_OBJ =
1066 + $(shell echo '#include "ap51-flash-res.h"' > $(AP51_RC))
1067 + $(shell echo 'IDR_KERNEL RCDATA DISCARDABLE "$(EMBED_KERNEL)"' >> $(AP51_RC))
1068 + $(shell echo 'IDR_ROOTFS RCDATA DISCARDABLE "$(EMBED_ROOTFS)"' >> $(AP51_RC))
1069 + $(shell echo 'IDR_UBNT_IMG RCDATA DISCARDABLE "$(EMBED_UBNT_IMG)"' >> $(AP51_RC))
1070 ++$(shell echo 'IDR_UBNT_IMG RCDATA DISCARDABLE "$(EMBED_UBOOT_IMG)"' >> $(AP51_RC))
1071 + ifneq ($(DESC),)
1072 + CFLAGS += -DEMBEDDED_DESC=\"$(DESC)\"
1073 + endif
1074 + endif
1075 + endif
1076 + endif
1077 ++endif
1078 +
1079 + ifeq ($(MAKECMDGOALS),ap51-flash.exe)
1080 + PLATFORM = WIN32
1081 +@@ -128,11 +132,14 @@ rootfs.o: $(EMBED_ROOTFS)
1082 + ubnt_img.o: $(EMBED_UBNT_IMG)
1083 + $(OBJCOPY) -B i386 -I binary $(EMBED_UBNT_IMG) -O elf32-i386 $@
1084 +
1085 +-$(AP51_RC).o: $(EMBED_KERNEL) $(EMBED_ROOTFS) $(EMBED_UBNT_IMG)
1086 ++uboot_img.o: $(EMBED_UBOOT_IMG)
1087 ++ $(OBJCOPY) -B i386 -I binary $(EMBED_UBOOT_IMG) -O elf32-i386 $@
1088 ++
1089 ++$(AP51_RC).o: $(EMBED_KERNEL) $(EMBED_ROOTFS) $(EMBED_UBNT_IMG) $(EMBED_UBOOT_IMG)
1090 + $(WINDRES) -i $(AP51_RC) -I. -o $@
1091 +
1092 + clean:
1093 + rm -rf *.o *~ *.plg *.ncb libap51-flash.a ap51-flash ap51-flash-static ap51-flash.exe ap51-flash-osx $(AP51_RC)
1094 +
1095 + distclean: clean
1096 +- rm -rf $(EMBED_ROOTFS) $(EMBED_KERNEL) $(EMBED_UBNT_IMG)
1097 ++ rm -rf $(EMBED_ROOTFS) $(EMBED_KERNEL) $(EMBED_UBNT_IMG) $(EMBED_UBOOT_IMG)
1098 +diff --git a/ap51-flash-res.h b/ap51-flash-res.h
1099 +index 30b83d6..7d9a36d 100644
1100 +--- a/ap51-flash-res.h
1101 ++++ b/ap51-flash-res.h
1102 +@@ -19,3 +19,4 @@
1103 + #define IDR_KERNEL 101
1104 + #define IDR_ROOTFS 102
1105 + #define IDR_UBNT_IMG 103
1106 ++#define IDR_UBOOT_IMG 104
1107 +diff --git a/ap51-flash.c b/ap51-flash.c
1108 +index 256b010..3244620 100644
1109 +--- a/ap51-flash.c
1110 ++++ b/ap51-flash.c
1111 +@@ -46,6 +46,7 @@ unsigned int remote_ip;
1112 + unsigned int local_ip;
1113 + static unsigned int ubnt_remote_ip = 3232235796UL; /* 192.168.1.20 */
1114 + static unsigned int ubnt_local_ip = 3232235801UL; /* 192.168.1.25 */
1115 ++static unsigned int mr500_local_ip = 3232260872UL; /* 192.168.99.8 */
1116 + unsigned char *tftp_xfer_buff = NULL;
1117 + unsigned long tftp_xfer_size = 0;
1118 +
1119 +@@ -66,6 +67,10 @@ extern unsigned long _binary_openwrt_atheros_root_squashfs_size;
1120 + extern unsigned long _binary_openwrt_atheros_ubnt2_squashfs_bin_start;
1121 + extern unsigned long _binary_openwrt_atheros_ubnt2_squashfs_bin_end;
1122 + extern unsigned long _binary_openwrt_atheros_ubnt2_squashfs_bin_size;
1123 ++
1124 ++extern unsigned long _binary_openwrt_ralink_mr500_squashfs_bin_start;
1125 ++extern unsigned long _binary_openwrt_ralink_mr500_squashfs_bin_end;
1126 ++extern unsigned long _binary_openwrt_ralink_mr500_squashfs_bin_size;
1127 + #endif
1128 +
1129 + static uip_ipaddr_t srcipaddr;
1130 +@@ -178,6 +183,11 @@ read_packet:
1131 + continue;
1132 + }
1133 +
1134 ++ if (*((unsigned int *)recv_arphdr->arp_tpa) == htonl(mr500_local_ip)) {
1135 ++ flash_mode = MODE_TFTP_SERVER;
1136 ++ break;
1137 ++ }
1138 ++
1139 + /* we are waiting for gratuitous requests */
1140 + if (*((unsigned int *)recv_arphdr->arp_spa) != *((unsigned int *)recv_arphdr->arp_tpa))
1141 + continue;
1142 +@@ -660,7 +670,7 @@ int ap51_flash(char *iface, char *rootfs_filename, char *kernel_filename, int nv
1143 + {
1144 + uip_ipaddr_t netmask;
1145 + struct uip_eth_addr srcmac, dstmac, brcmac;
1146 +- int ret, ubnt_img = 0, fd, size = 0;
1147 ++ int ret, img_type = IMG_REDBOOT, fd, size = 0;
1148 + unsigned char *buf = 0;
1149 + char *socket_dev;
1150 +
1151 +@@ -777,9 +787,13 @@ int ap51_flash(char *iface, char *rootfs_filename, char *kernel_filename, int nv
1152 + /* ubnt magic header */
1153 + if ((strncmp((char *)rootfs_buf, "UBNT", 4) == 0) ||
1154 + (strncmp((char *)rootfs_buf, "OPEN", 4) == 0))
1155 +- ubnt_img = 1;
1156 ++ img_type = IMG_UBNT;
1157 ++
1158 ++ /* uboot magic header */
1159 ++ if (*((unsigned int *)rootfs_buf) == htonl(0x27051956))
1160 ++ img_type = IMG_UBOOT;
1161 +
1162 +- if ((FLASH_PAGE_SIZE > kernel_size) && (!ubnt_img)) {
1163 ++ if ((FLASH_PAGE_SIZE > kernel_size) && (img_type == IMG_REDBOOT)) {
1164 + fprintf(stderr, "kernel implausible small: %d bytes\n", kernel_size);
1165 + return 1;
1166 + }
1167 +@@ -838,9 +852,13 @@ init_socket:
1168 + goto sock_close;
1169 + }
1170 + } else {
1171 +- if (ubnt_img) {
1172 ++ switch (img_type) {
1173 ++ case IMG_UBNT:
1174 + fprintf(stderr, "Error - you are trying to flash a redboot device with a ubiquiti image!\n");
1175 + goto sock_close;
1176 ++ case IMG_UBOOT:
1177 ++ fprintf(stderr, "Error - you are trying to flash a redboot device with a uboot image!\n");
1178 ++ goto sock_close;
1179 + }
1180 + }
1181 +
1182 +@@ -884,7 +902,7 @@ init_socket:
1183 + }
1184 + }
1185 +
1186 +- ubnt_img = 1;
1187 ++ img_type = IMG_UBNT;
1188 + }
1189 + #endif /* EMBEDDED_DATA */
1190 + if (flash_from_file) {
1191 +@@ -893,9 +911,13 @@ init_socket:
1192 + goto sock_close;
1193 + }
1194 + } else {
1195 +- if (!ubnt_img) {
1196 ++ switch (img_type) {
1197 ++ case IMG_REDBOOT:
1198 + fprintf(stderr, "Error - you are trying to flash a ubiquiti device with redboot images!\n");
1199 + goto sock_close;
1200 ++ case IMG_UBOOT:
1201 ++ fprintf(stderr, "Error - you are trying to flash a ubiquiti device with a uboot image!\n");
1202 ++ goto sock_close;
1203 + }
1204 + }
1205 +
1206 +@@ -903,6 +925,58 @@ init_socket:
1207 + tftp_xfer_size = (flash_from_file ? fff_data[FFF_UBNT].flash_size : rootfs_size);
1208 + printf("Ubiquiti device detected - using TFTP client to flash\n");
1209 + break;
1210 ++ case MODE_TFTP_SERVER:
1211 ++#if defined(EMBEDDED_DATA)
1212 ++ if ((!rootfs_filename) && (!flash_from_file)) {
1213 ++
1214 ++ /* free the rootfs and replace it by the uboot image */
1215 ++ free(rootfs_buf);
1216 ++
1217 ++#if defined(WIN32)
1218 ++ HRSRC hRsrc;
1219 ++ hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_UBOOT_IMG), RT_RCDATA);
1220 ++ if (NULL != hRsrc) {
1221 ++ HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
1222 ++ buf = LockResource(hGlobal);
1223 ++ size = SizeofResource(NULL, hRsrc);
1224 ++ }
1225 ++#else
1226 ++ buf = (unsigned char*)&_binary_openwrt_ralink_mr500_squashfs_bin_start;
1227 ++ size = (int)&_binary_openwrt_ralink_mr500_squashfs_bin_size;
1228 ++#endif
1229 ++
1230 ++ if (0 != buf) {
1231 ++ rootfs_size = ((size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE) * FLASH_PAGE_SIZE;
1232 ++ if (0 != (rootfs_buf = malloc(rootfs_size))) {
1233 ++ memset(rootfs_buf, 0xff, rootfs_size);
1234 ++ memmove(rootfs_buf, buf, size);
1235 ++ } else {
1236 ++ perror("no mem");
1237 ++ goto sock_close;
1238 ++ }
1239 ++ }
1240 ++
1241 ++ img_type = IMG_UBOOT;
1242 ++ }
1243 ++#endif /* EMBEDDED_DATA */
1244 ++ if (flash_from_file) {
1245 ++ if (!fff_data[FFF_UBOOT].fname) {
1246 ++ fprintf(stderr, "Error - uboot device detected but uboot file not available\n");
1247 ++ goto sock_close;
1248 ++ }
1249 ++ } else {
1250 ++ switch (img_type) {
1251 ++ case IMG_REDBOOT:
1252 ++ fprintf(stderr, "Error - you are trying to flash a uboot device with redboot images!\n");
1253 ++ goto sock_close;
1254 ++ case IMG_UBNT:
1255 ++ fprintf(stderr, "Error - you are trying to flash a uboot device with a ubiquiti image!\n");
1256 ++ goto sock_close;
1257 ++ }
1258 ++ }
1259 ++
1260 ++ printf("Uboot device detected - using TFTP server to flash\n");
1261 ++ break;
1262 + default:
1263 + fprintf(stderr, "Error - could not auto-detect flash mode!\n");
1264 + goto sock_close;
1265 +diff --git a/ap51-flash.h b/ap51-flash.h
1266 +index 1049661..2e59519 100644
1267 +--- a/ap51-flash.h
1268 ++++ b/ap51-flash.h
1269 +@@ -94,6 +94,14 @@ enum {
1270 + MODE_REDBOOT,
1271 + MODE_MAYBE_REDBOOT,
1272 + MODE_TFTP_CLIENT,
1273 ++ MODE_TFTP_SERVER,
1274 ++};
1275 ++
1276 ++/* image type */
1277 ++enum {
1278 ++ IMG_REDBOOT,
1279 ++ IMG_UBNT,
1280 ++ IMG_UBOOT,
1281 + };
1282 +
1283 + /* flash from file data */
1284 +@@ -101,6 +109,7 @@ enum {
1285 + FFF_ROOTFS = 0,
1286 + FFF_KERNEL,
1287 + FFF_UBNT,
1288 ++ FFF_UBOOT,
1289 + FFF_NUM,
1290 + };
1291 +
1292 +diff --git a/main.c b/main.c
1293 +index 9589d00..44f0386 100644
1294 +--- a/main.c
1295 ++++ b/main.c
1296 +@@ -31,11 +31,12 @@ void usage(char *prgname)
1297 + fprintf(stderr, "Usage:\n");
1298 +
1299 + #if defined(EMBEDDED_DATA)
1300 +- fprintf(stderr, "%s [ethdevice] flashes embedded kernel + rootfs or ubquiti image: %s\n", prgname, EMBEDDED_DESC_STR);
1301 ++ fprintf(stderr, "%s [ethdevice] flashes embedded kernel + rootfs or ubquiti or uboot image: %s\n", prgname, EMBEDDED_DESC_STR);
1302 + #endif
1303 +
1304 + fprintf(stderr, "%s [ethdevice] rootfs.bin kernel.lzma flashes your rootfs and kernel\n", prgname);
1305 + fprintf(stderr, "%s [ethdevice] ubnt.bin flashes your ubiquiti image\n", prgname);
1306 ++ fprintf(stderr, "%s [ethdevice] uboot.bin flashes your uboot image\n", prgname);
1307 + fprintf(stderr, "%s -v prints version information\n", prgname);
1308 +
1309 + #if defined(FLASH_FROM_FILE)
1310 +@@ -45,7 +46,8 @@ void usage(char *prgname)
1311 + fprintf(stderr, " --flash-from-file enable 'flash from file' mode\n");
1312 + fprintf(stderr, " --rootfs path to rootfs file\n");
1313 + fprintf(stderr, " --kernel path to kernel file\n");
1314 +- fprintf(stderr, " --ubnt path to ubiquiti image\n");
1315 ++ fprintf(stderr, " --ubnt path to ubiquiti image\n");
1316 ++ fprintf(stderr, " --uboot path to uboot image\n");
1317 + #endif
1318 +
1319 + fprintf(stderr, "\nThe 'ethdevice' has to be one of the devices that are part of the supported device list which follows.\nYou can either specify its name or the interface number.\n");
1320 +@@ -62,6 +64,7 @@ int main(int argc, char* argv[])
1321 + int i, found_args = 1, optchar, option_index;
1322 + struct option long_options[] =
1323 + {
1324 ++ {"uboot", required_argument, 0, 'b'},
1325 + {"flash-from-file", no_argument, 0, 'f'},
1326 + {"rootfs", required_argument, 0, 'r'},
1327 + {"kernel", required_argument, 0, 'k'},
1328 +@@ -115,8 +118,12 @@ int main(int argc, char* argv[])
1329 + for (i = 0; i < FFF_NUM; i++)
1330 + fff_data[i].fname = NULL;
1331 +
1332 +- while ((optchar = getopt_long(argc, argv, "fk:r:u:", long_options, &option_index)) != -1) {
1333 ++ while ((optchar = getopt_long(argc, argv, "fb:k:r:u:", long_options, &option_index)) != -1) {
1334 + switch (optchar) {
1335 ++ case 'b':
1336 ++ fff_data[FFF_UBOOT].fname = optarg;
1337 ++ found_args += 2;
1338 ++ break;
1339 + case 'f':
1340 + flash_from_file = 1;
1341 + found_args++;
1342 +@@ -146,8 +153,9 @@ int main(int argc, char* argv[])
1343 + return 1;
1344 + }
1345 +
1346 +- if (!fff_data[FFF_ROOTFS].fname && !fff_data[FFF_KERNEL].fname && !fff_data[FFF_UBNT].fname) {
1347 +- fprintf(stderr, "Error - you need to specify at least kernel and rootfs or ubiquiti image file\n");
1348 ++ if (!fff_data[FFF_ROOTFS].fname && !fff_data[FFF_KERNEL].fname &&
1349 ++ !fff_data[FFF_UBNT].fname && !fff_data[FFF_UBOOT].fname) {
1350 ++ fprintf(stderr, "Error - you need to specify at least kernel and rootfs or ubiquiti or uboot image file\n");
1351 + return 1;
1352 + }
1353 +
1354 +diff --git a/packet.c b/packet.c
1355 +index 47bb6ad..61ea04b 100644
1356 +--- a/packet.c
1357 ++++ b/packet.c
1358 +@@ -151,7 +151,8 @@ static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_l
1359 + char *file_name;
1360 + int tftp_data_len, ret;
1361 +
1362 +- if ((flash_mode == MODE_REDBOOT) && (rcv_udphdr->dest != htons(IPPORT_TFTP)))
1363 ++ if (((flash_mode == MODE_REDBOOT) || (flash_mode == MODE_TFTP_SERVER)) &&
1364 ++ (rcv_udphdr->dest != htons(IPPORT_TFTP)))
1365 + return 1;
1366 +
1367 + if ((flash_mode == MODE_TFTP_CLIENT) && (rcv_udphdr->source != htons(IPPORT_TFTP)))
1368 +@@ -176,6 +177,11 @@ static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_l
1369 + tftp_xfer_size = (flash_from_file ? fff_data[FFF_ROOTFS].flash_size : rootfs_size);
1370 + printf("Sending rootfs, %ld blocks...\n",
1371 + ((tftp_xfer_size + 511) / 512));
1372 ++ } else if (strcmp(file_name, "mr500.bin") == 0) {
1373 ++ tftp_xfer_buff = (flash_from_file ? (unsigned char *)&fff_data[FFF_UBOOT] : rootfs_buf);
1374 ++ tftp_xfer_size = (flash_from_file ? fff_data[FFF_UBOOT].flash_size : rootfs_size);
1375 ++ printf("Sending uboot image, %ld blocks...\n",
1376 ++ ((tftp_xfer_size + 511) / 512));
1377 + } else {
1378 + fprintf(stderr, "Unknown file name: %s\n", file_name);
1379 + return -1;
1380 +@@ -204,7 +210,7 @@ static int tftp_transfer(const unsigned char *packet_buff, unsigned int packet_l
1381 + block = tftp_ack_block;
1382 + } else {
1383 + if (block * 512 > tftp_xfer_size) {
1384 +- if (flash_mode == MODE_TFTP_CLIENT) {
1385 ++ if ((flash_mode == MODE_TFTP_CLIENT) || (flash_mode == MODE_TFTP_SERVER)) {
1386 + printf("Image successfully transmitted.\n");
1387 + printf("Please give the device a couple of minutes to install the new image into the flash.\n");
1388 + return 0;
1389 +--
1390 +1.7.1
1391 +
1392