Separate the fastboot protocol handling from the fastboot UDP code in
preparation for reusing it in the USB code.

Signed-off-by: Alex Kiernan <alex.kier...@gmail.com>
---

Changes in v2: None

 drivers/fastboot/Makefile    |   1 +
 drivers/fastboot/fb_packet.c | 249 +++++++++++++++++++++++++++++++++++++++++++
 include/fastboot.h           |   3 +
 net/fastboot.c               | 234 +---------------------------------------
 4 files changed, 258 insertions(+), 229 deletions(-)
 create mode 100644 drivers/fastboot/fb_packet.c

diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
index 9af4073..c0106a7 100644
--- a/drivers/fastboot/Makefile
+++ b/drivers/fastboot/Makefile
@@ -2,6 +2,7 @@
 
 obj-y += fb_common.o
 obj-y += fb_getvar.o
+obj-y += fb_packet.o
 obj-$(CONFIG_FASTBOOT_FLASH) += image-sparse.o
 
 obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o
diff --git a/drivers/fastboot/fb_packet.c b/drivers/fastboot/fb_packet.c
new file mode 100644
index 0000000..fbe5668
--- /dev/null
+++ b/drivers/fastboot/fb_packet.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <fb_mmc.h>
+#include <part.h>
+#include <stdlib.h>
+#include <version.h>
+
+/* Parsed from first fastboot command packet */
+static char *cmd_string;
+static char *cmd_parameter;
+static int cmd = -1;
+
+/* Fastboot download parameters */
+static unsigned int bytes_received;
+static unsigned int bytes_expected;
+static unsigned int image_size;
+
+static void cb_okay(char *, char *, unsigned int, char *);
+static void cb_getvar(char *, char *, unsigned int, char *);
+static void cb_download(char *, char *, unsigned int, char *);
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void cb_flash(char *, char *, unsigned int, char *);
+static void cb_erase(char *, char *, unsigned int, char *);
+#endif
+static void cb_continue(char *, char *, unsigned int, char *);
+static void cb_reboot_bootloader(char *, char *, unsigned int, char *);
+
+static void (*fb_net_dispatch[])(char *cmd_parameter,
+                                char *fastboot_data,
+                                unsigned int fastboot_data_len,
+                                char *response) = {
+       [FB_CMD_GETVAR] = cb_getvar,
+       [FB_CMD_DOWNLOAD] = cb_download,
+       [FB_CMD_VERIFY] = NULL,
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+       [FB_CMD_FLASH] = cb_flash,
+       [FB_CMD_ERASE] = cb_erase,
+#else
+       [FB_CMD_FLASH] = NULL,
+       [FB_CMD_ERASE] = NULL,
+#endif
+       [FB_CMD_BOOT] = cb_okay,
+       [FB_CMD_CONTINUE] = cb_continue,
+       [FB_CMD_REBOOT] = cb_okay,
+       [FB_CMD_REBOOT_BOOTLOADER] = cb_reboot_bootloader,
+       [FB_CMD_POWERDOWN] = NULL,
+       [FB_CMD_SET_ACTIVE] = cb_okay,
+       [FB_CMD_UPLOAD] = NULL,
+};
+
+static void cleanup_command_data(void);
+
+int fastboot_packet_handle(char *fastboot_data,
+                          unsigned int fastboot_data_len, char *response)
+{
+       if (!cmd_string) {
+               /* Parse command and send ack */
+               cmd_parameter = fastboot_data;
+               cmd_string = strsep(&cmd_parameter, ":");
+               cmd_string = strdup(cmd_string);
+               cmd = fastboot_lookup_command(cmd_string);
+               if (cmd_parameter)
+                       cmd_parameter = strdup(cmd_parameter);
+       } else {
+               if (cmd >= 0) {
+                       void (*fb_call)(char *cmd_parameter,
+                                       char *fastboot_data,
+                                       unsigned int fastboot_data_len,
+                                       char *response);
+                       fb_call = fb_net_dispatch[cmd];
+                       if (fb_call) {
+                               fb_call(cmd_parameter, fastboot_data,
+                                       fastboot_data_len, response);
+                       } else {
+                               pr_err("command %s not implemented.\n",
+                                      cmd_string);
+                               fastboot_fail("unrecognized command",
+                                             response);
+                       }
+               } else {
+                       pr_err("command %s not recognized.\n",
+                              cmd_string);
+                       fastboot_fail("unrecognized command", response);
+               }
+       }
+       return cmd;
+}
+
+void fastboot_after_response(char *response)
+{
+       /* OKAY and FAIL indicate command is complete */
+       if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4))
+               cleanup_command_data();
+}
+
+static void cb_okay(char *cmd_parameter, char *fastboot_data,
+                   unsigned int fastboot_data_len, char *response)
+{
+       fastboot_okay(NULL, response);
+}
+
+static void cb_getvar(char *cmd_parameter, char *fastboot_data,
+                     unsigned int fastboot_data_len, char *response)
+{
+       fb_getvar(cmd_parameter, response);
+}
+
+/**
+ * Copies image data from fastboot_data to CONFIG_FASTBOOT_BUF_ADDR.
+ * Writes to response.
+ *
+ * @param fastboot_data        Pointer to received fastboot data
+ * @param fastboot_data_len    Length of received fastboot data
+ * @param repsonse             Pointer to fastboot response buffer
+ */
+static void cb_download(char *cmd_parameter, char *fastboot_data,
+                       unsigned int fastboot_data_len, char *response)
+{
+       char *tmp;
+
+       if (bytes_expected == 0) {
+               if (!cmd_parameter) {
+                       fastboot_fail("Expected command parameter", response);
+                       return;
+               }
+               bytes_expected = simple_strtoul(cmd_parameter, &tmp, 16);
+               if (bytes_expected == 0) {
+                       fastboot_fail("Expected nonzero image size", response);
+                       return;
+               }
+       }
+       if (fastboot_data_len == 0 && bytes_received == 0) {
+               /* Nothing to download yet. Response is of the form:
+                * [DATA|FAIL]$cmd_parameter
+                *
+                * where cmd_parameter is an 8 digit hexadecimal number
+                */
+               if (bytes_expected > CONFIG_FASTBOOT_BUF_SIZE)
+                       fastboot_fail(cmd_parameter, response);
+               else
+                       fastboot_response("DATA", response, "%s",
+                                         cmd_parameter);
+       } else if (fastboot_data_len == 0 &&
+                  (bytes_received >= bytes_expected)) {
+               /* Download complete. Respond with "OKAY" */
+               fastboot_okay(NULL, response);
+               image_size = bytes_received;
+               bytes_expected = 0;
+               bytes_received = 0;
+       } else {
+               if (fastboot_data_len == 0 ||
+                   (bytes_received + fastboot_data_len) > bytes_expected) {
+                       fastboot_fail("Received invalid data length",
+                                     response);
+                       return;
+               }
+               /* Download data to CONFIG_FASTBOOT_BUF_ADDR */
+               memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + bytes_received,
+                      fastboot_data, fastboot_data_len);
+               bytes_received += fastboot_data_len;
+       }
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+/**
+ * Writes the previously downloaded image to the partition indicated by
+ * cmd_parameter. Writes to response.
+ *
+ * @param repsonse    Pointer to fastboot response buffer
+ */
+static void cb_flash(char *cmd_parameter, char *fastboot_data,
+                    unsigned int fastboot_data_len, char *response)
+{
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+       fb_mmc_flash_write(cmd_parameter, (void *)CONFIG_FASTBOOT_BUF_ADDR,
+                          image_size, response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+       fb_nand_flash_write(cmd_parameter, (void *)CONFIG_FASTBOOT_BUF_ADDR,
+                           image_size, response);
+#endif
+}
+
+/**
+ * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
+ * to response.
+ *
+ * @param repsonse    Pointer to fastboot response buffer
+ */
+static void cb_erase(char *cmd_parameter, char *fastboot_data,
+                    unsigned int fastboot_data_len, char *response)
+{
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+       fb_mmc_erase(cmd_parameter, response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+       fb_nand_erase(cmd_parameter, response);
+#endif
+}
+#endif
+
+/**
+ * Continues normal boot process by exiting fastboot server. Writes
+ * to response.
+ *
+ * @param repsonse    Pointer to fastboot response buffer
+ */
+static void cb_continue(char *cmd_parameter, char *fastboot_data,
+                       unsigned int fastboot_data_len, char *response)
+{
+       net_set_state(NETLOOP_SUCCESS);
+       fastboot_okay(NULL, response);
+}
+
+/**
+ * Sets reboot bootloader flag if requested. Writes to response.
+ *
+ * @param repsonse    Pointer to fastboot response buffer
+ */
+static void cb_reboot_bootloader(char *cmd_parameter, char *fastboot_data,
+                                unsigned int fastboot_data_len, char *response)
+{
+       if (fb_set_reboot_flag())
+               fastboot_fail("Cannot set reboot flag", response);
+       else
+               fastboot_okay(NULL, response);
+}
+
+/**
+ * Frees any resources allocated during current fastboot command.
+ */
+static void cleanup_command_data(void)
+{
+       /* cmd_parameter and cmd_string potentially point to memory allocated by
+        * strdup
+        */
+       if (cmd_parameter)
+               free(cmd_parameter);
+       if (cmd_string)
+               free(cmd_string);
+       cmd_parameter = NULL;
+       cmd_string = NULL;
+       cmd = -1;
+}
diff --git a/include/fastboot.h b/include/fastboot.h
index 64f9939..4a02554 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -77,4 +77,7 @@ int strcmp_l1(const char *s1, const char *s2);
 int fastboot_lookup_command(const char *cmd_string);
 int fb_set_reboot_flag(void);
 void fastboot_boot(void *addr);
+int fastboot_packet_handle(char *fastboot_data,
+                          unsigned int fastboot_data_len, char *response);
+void fastboot_after_response(char *response);
 #endif /* _FASTBOOT_H_ */
diff --git a/net/fastboot.c b/net/fastboot.c
index a07b1ad..97f75a5 100644
--- a/net/fastboot.c
+++ b/net/fastboot.c
@@ -5,12 +5,8 @@
 
 #include <common.h>
 #include <fastboot.h>
-#include <fb_mmc.h>
 #include <net.h>
 #include <net/fastboot.h>
-#include <part.h>
-#include <stdlib.h>
-#include <version.h>
 
 /* Fastboot port # defined in spec */
 #define WELL_KNOWN_PORT 5554
@@ -42,56 +38,13 @@ static const unsigned short fb_udp_version = 1;
 static uchar last_packet[PACKET_SIZE];
 static unsigned int last_packet_len;
 
-/* Parsed from first fastboot command packet */
-static char *cmd_string;
-static char *cmd_parameter;
-
-/* Fastboot download parameters */
-static unsigned int bytes_received;
-static unsigned int bytes_expected;
-static unsigned int image_size;
-
 static struct in_addr fastboot_remote_ip;
 /* The UDP port at their end */
 static int fastboot_remote_port;
 /* The UDP port at our end */
 static int fastboot_our_port;
 
-static void cb_okay(char *, char *, unsigned int, char *);
-static void cb_getvar(char *, char *, unsigned int, char *);
-static void cb_download(char *, char *, unsigned int, char *);
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-static void cb_flash(char *, char *, unsigned int, char *);
-static void cb_erase(char *, char *, unsigned int, char *);
-#endif
-static void cb_continue(char *, char *, unsigned int, char *);
-static void cb_reboot_bootloader(char *, char *, unsigned int, char *);
-
-static void (*fb_net_dispatch[])(char *cmd_parameter,
-                                char *fastboot_data,
-                                unsigned int fastboot_data_len,
-                                char *response) = {
-       [FB_CMD_GETVAR] = cb_getvar,
-       [FB_CMD_DOWNLOAD] = cb_download,
-       [FB_CMD_VERIFY] = NULL,
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-       [FB_CMD_FLASH] = cb_flash,
-       [FB_CMD_ERASE] = cb_erase,
-#else
-       [FB_CMD_FLASH] = NULL,
-       [FB_CMD_ERASE] = NULL,
-#endif
-       [FB_CMD_BOOT] = cb_okay,
-       [FB_CMD_CONTINUE] = cb_continue,
-       [FB_CMD_REBOOT] = cb_okay,
-       [FB_CMD_REBOOT_BOOTLOADER] = cb_reboot_bootloader,
-       [FB_CMD_POWERDOWN] = NULL,
-       [FB_CMD_SET_ACTIVE] = cb_okay,
-       [FB_CMD_UPLOAD] = NULL,
-};
-
 static void boot_downloaded_image(void);
-static void cleanup_command_data(void);
 
 void fastboot_send_info(const char *msg)
 {
@@ -185,36 +138,8 @@ static void fastboot_send(struct fastboot_header 
fb_header, char *fastboot_data,
                packet += strlen(error_msg);
                break;
        case FASTBOOT_FASTBOOT:
-               if (!cmd_string) {
-                       /* Parse command and send ack */
-                       cmd_parameter = fastboot_data;
-                       cmd_string = strsep(&cmd_parameter, ":");
-                       cmd_string = strdup(cmd_string);
-                       if (cmd_parameter)
-                               cmd_parameter = strdup(cmd_parameter);
-               } else {
-                       cmd = fastboot_lookup_command(cmd_string);
-                       if (cmd >= 0) {
-                               void (*fb_call)(char *cmd_parameter,
-                                               char *fastboot_data,
-                                               unsigned int fastboot_data_len,
-                                               char *response);
-                               fb_call = fb_net_dispatch[cmd];
-                               if (fb_call) {
-                                       fb_call(cmd_parameter, fastboot_data,
-                                               fastboot_data_len, response);
-                               } else {
-                                       pr_err("command %s not implemented.\n",
-                                              cmd_string);
-                                       fastboot_fail("unrecognized command",
-                                                     response);
-                               }
-                       } else {
-                               pr_err("command %s not recognized.\n",
-                                      cmd_string);
-                               fastboot_fail("unrecognized command", response);
-                       }
-               }
+               cmd = fastboot_packet_handle(fastboot_data, fastboot_data_len,
+                                            response);
                /* Sent some INFO packets, need to update sequence number in
                 * header
                 */
@@ -245,148 +170,15 @@ static void fastboot_send(struct fastboot_header 
fb_header, char *fastboot_data,
        if (!strncmp("OKAY", response, 4)) {
                if (cmd == FB_CMD_BOOT) {
                        boot_downloaded_image();
+               } else if (cmd == FB_CMD_CONTINUE) {
+                       net_set_state(NETLOOP_SUCCESS);
                } else if (cmd == FB_CMD_REBOOT ||
                           cmd == FB_CMD_REBOOT_BOOTLOADER) {
                        do_reset(NULL, 0, 0, NULL);
                }
        }
 
-       /* OKAY and FAIL indicate command is complete */
-       if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4))
-               cleanup_command_data();
-}
-
-static void cb_okay(char *cmd_parameter, char *fastboot_data,
-                   unsigned int fastboot_data_len, char *response)
-{
-       fastboot_okay(NULL, response);
-}
-
-static void cb_getvar(char *cmd_parameter, char *fastboot_data,
-                     unsigned int fastboot_data_len, char *response)
-{
-       fb_getvar(cmd_parameter, response);
-}
-
-/**
- * Copies image data from fastboot_data to CONFIG_FASTBOOT_BUF_ADDR.
- * Writes to response.
- *
- * @param fastboot_data        Pointer to received fastboot data
- * @param fastboot_data_len    Length of received fastboot data
- * @param repsonse             Pointer to fastboot response buffer
- */
-static void cb_download(char *cmd_parameter, char *fastboot_data,
-                       unsigned int fastboot_data_len, char *response)
-{
-       char *tmp;
-
-       if (bytes_expected == 0) {
-               if (!cmd_parameter) {
-                       fastboot_fail("Expected command parameter", response);
-                       return;
-               }
-               bytes_expected = simple_strtoul(cmd_parameter, &tmp, 16);
-               if (bytes_expected == 0) {
-                       fastboot_fail("Expected nonzero image size", response);
-                       return;
-               }
-       }
-       if (fastboot_data_len == 0 && bytes_received == 0) {
-               /* Nothing to download yet. Response is of the form:
-                * [DATA|FAIL]$cmd_parameter
-                *
-                * where cmd_parameter is an 8 digit hexadecimal number
-                */
-               if (bytes_expected > CONFIG_FASTBOOT_BUF_SIZE)
-                       fastboot_fail(cmd_parameter, response);
-               else
-                       fastboot_response("DATA", response, "%s",
-                                         cmd_parameter);
-       } else if (fastboot_data_len == 0 &&
-                  (bytes_received >= bytes_expected)) {
-               /* Download complete. Respond with "OKAY" */
-               fastboot_okay(NULL, response);
-               image_size = bytes_received;
-               bytes_expected = 0;
-               bytes_received = 0;
-       } else {
-               if (fastboot_data_len == 0 ||
-                   (bytes_received + fastboot_data_len) > bytes_expected) {
-                       fastboot_fail("Received invalid data length",
-                                     response);
-                       return;
-               }
-               /* Download data to CONFIG_FASTBOOT_BUF_ADDR */
-               memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + bytes_received,
-                      fastboot_data, fastboot_data_len);
-               bytes_received += fastboot_data_len;
-       }
-}
-
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-/**
- * Writes the previously downloaded image to the partition indicated by
- * cmd_parameter. Writes to response.
- *
- * @param repsonse    Pointer to fastboot response buffer
- */
-static void cb_flash(char *cmd_parameter, char *fastboot_data,
-                    unsigned int fastboot_data_len, char *response)
-{
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
-       fb_mmc_flash_write(cmd_parameter, (void *)CONFIG_FASTBOOT_BUF_ADDR,
-                          image_size, response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
-       fb_nand_flash_write(cmd_parameter, (void *)CONFIG_FASTBOOT_BUF_ADDR,
-                           image_size, response);
-#endif
-}
-
-/**
- * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
- * to response.
- *
- * @param repsonse    Pointer to fastboot response buffer
- */
-static void cb_erase(char *cmd_parameter, char *fastboot_data,
-                    unsigned int fastboot_data_len, char *response)
-{
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
-       fb_mmc_erase(cmd_parameter, response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
-       fb_nand_erase(cmd_parameter, response);
-#endif
-}
-#endif
-
-/**
- * Continues normal boot process by exiting fastboot server. Writes
- * to response.
- *
- * @param repsonse    Pointer to fastboot response buffer
- */
-static void cb_continue(char *cmd_parameter, char *fastboot_data,
-                       unsigned int fastboot_data_len, char *response)
-{
-       net_set_state(NETLOOP_SUCCESS);
-       fastboot_okay(NULL, response);
-}
-
-/**
- * Sets reboot bootloader flag if requested. Writes to response.
- *
- * @param repsonse    Pointer to fastboot response buffer
- */
-static void cb_reboot_bootloader(char *cmd_parameter, char *fastboot_data,
-                                unsigned int fastboot_data_len, char *response)
-{
-       if (fb_set_reboot_flag())
-               fastboot_fail("Cannot set reboot flag", response);
-       else
-               fastboot_okay(NULL, response);
+       fastboot_after_response(response);
 }
 
 /**
@@ -399,22 +191,6 @@ static void boot_downloaded_image(void)
 }
 
 /**
- * Frees any resources allocated during current fastboot command.
- */
-static void cleanup_command_data(void)
-{
-       /* cmd_parameter and cmd_string potentially point to memory allocated by
-        * strdup
-        */
-       if (cmd_parameter)
-               free(cmd_parameter);
-       if (cmd_string)
-               free(cmd_string);
-       cmd_parameter = NULL;
-       cmd_string = NULL;
-}
-
-/**
  * Incoming UDP packet handler.
  *
  * @param packet  Pointer to incoming UDP packet
-- 
2.7.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to