1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * All rights reserved. 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met: 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * * Redistributions of source code must retain the above copyright 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer. 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer in 125ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau * the documentation and/or other materials provided with the 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distribution. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 225ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE. 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#include "fastboot.h" 30e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg#include "fs.h" 31c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 3281c632e4dacb14c4afa8a1f166faa1bbacce4d8fColin Cross#include <errno.h> 333ab8b859c24fcdee49a48ded183e42690775eeddElliott Hughes#include <stdarg.h> 345957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <stdio.h> 355957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn#include <stdlib.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 37c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#include <sys/stat.h> 38c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#include <sys/types.h> 39c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#include <unistd.h> 40230d160a718333651f7ca1557404f96682795b37Anatol Pomazau 41c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_DOWNLOAD 1 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_COMMAND 2 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_QUERY 3 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_NOTICE 4 47e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg#define OP_DOWNLOAD_SPARSE 5 48e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg#define OP_WAIT_FOR_DISCONNECT 6 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct Action Action; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#define CMD_SIZE 64 53c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 54fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughesstruct Action { 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned op; 56fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes Action* next; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau char cmd[CMD_SIZE]; 59fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes const char* prod; 60fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes void* data; 61fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes 62fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes // The protocol only supports 32-bit sizes, so you'll have to break 63fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes // anything larger into chunks. 64fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes uint32_t size; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *msg; 67b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes int (*func)(Action* a, int status, const char* resp); 68cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 69cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double start; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic Action *action_list = 0; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic Action *action_last = 0; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 76c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 77c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 780b156638307db890e5539b52521fd24beb3440cbDavid Pursellbool fb_getvar(Transport* transport, const std::string& key, std::string* value) { 792fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes std::string cmd = "getvar:"; 802fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes cmd += key; 812fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes 822fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes char buf[FB_RESPONSE_SZ + 1]; 832fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes memset(buf, 0, sizeof(buf)); 840b156638307db890e5539b52521fd24beb3440cbDavid Pursell if (fb_command_response(transport, cmd.c_str(), buf)) { 852fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes return false; 862fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes } 872fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes *value = buf; 882fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes return true; 8980f2d036a9dff894df27961c4aed300f1a5ebbc4Colin Cross} 9080f2d036a9dff894df27961c4aed300f1a5ebbc4Colin Cross 91b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_default(Action* a, int status, const char* resp) { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) { 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FAILED (%s)\n", resp); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 95cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double split = now(); 96cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler fprintf(stderr,"OKAY [%7.3fs]\n", (split - a->start)); 97cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = split; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic Action *queue_action(unsigned op, const char *fmt, ...) 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 10550b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare size_t cmdsize; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 107b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes Action* a = reinterpret_cast<Action*>(calloc(1, sizeof(Action))); 108b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes if (a == nullptr) die("out of memory"); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 11150b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare cmdsize = vsnprintf(a->cmd, sizeof(a->cmd), fmt, ap); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11450b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare if (cmdsize >= sizeof(a->cmd)) { 11550b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare free(a); 11650b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare die("Command length (%d) exceeds maximum size (%d)", cmdsize, sizeof(a->cmd)); 11750b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare } 11850b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (action_last) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_last->next = a; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_list = a; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_last = a; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->op = op; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = cb_default; 127cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 128cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = -1; 129cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return a; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenbergvoid fb_set_active(const char *slot) 134b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg{ 135b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg Action *a; 136b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg a = queue_action(OP_COMMAND, "set_active:%s", slot); 137b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg a->msg = mkmsg("Setting current slot to '%s'", slot); 138b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg} 139b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_erase(const char *ptn) 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_COMMAND, "erase:%s", ptn); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("erasing '%s'", ptn); 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1478d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiyvoid fb_queue_flash(const char *ptn, void *data, unsigned sz) 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_DOWNLOAD, ""); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = data; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->size = sz; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("sending '%s' (%d KB)", ptn, sz / 1024); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_COMMAND, "flash:%s", ptn); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("writing '%s'", ptn); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1609da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gaovoid fb_queue_flash_sparse(const char* ptn, struct sparse_file* s, unsigned sz, size_t current, 1619da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gao size_t total) { 162f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross Action *a; 163f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 164f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a = queue_action(OP_DOWNLOAD_SPARSE, ""); 165f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a->data = s; 166f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a->size = 0; 1679da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gao a->msg = mkmsg("sending sparse '%s' %zu/%zu (%d KB)", ptn, current, total, sz / 1024); 168f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 169f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a = queue_action(OP_COMMAND, "flash:%s", ptn); 1709da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gao a->msg = mkmsg("writing '%s' %zu/%zu", ptn, current, total); 171f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 172f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 173b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int match(const char* str, const char** value, unsigned count) { 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n; 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < count; n++) { 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *val = value[n]; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(val); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int match; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((len > 1) && (val[len-1] == '*')) { 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len--; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project match = !strncmp(val, str, len); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project match = !strcmp(val, str); 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (match) return 1; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 196b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_check(Action* a, int status, const char* resp, int invert) 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 198b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes const char** value = reinterpret_cast<const char**>(a->data); 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count = a->size; 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int yes; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) { 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FAILED (%s)\n", resp); 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 208b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (a->prod) { 209b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (strcmp(a->prod, cur_product) != 0) { 210b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville double split = now(); 211b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fprintf(stderr,"IGNORE, product is %s required only for %s [%7.3fs]\n", 212b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville cur_product, a->prod, (split - a->start)); 213b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->start = split; 214b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return 0; 215b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 216b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 217b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project yes = match(resp, value, count); 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (invert) yes = !yes; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (yes) { 222cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double split = now(); 223cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler fprintf(stderr,"OKAY [%7.3fs]\n", (split - a->start)); 224cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = split; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FAILED\n\n"); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Device %s is '%s'.\n", a->cmd + 7, resp); 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Update %s '%s'", 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project invert ? "rejects" : "requires", value[0]); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 1; n < count; n++) { 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr," or '%s'", value[n]); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,".\n\n"); 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 239b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_require(Action*a, int status, const char* resp) { 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return cb_check(a, status, resp, 0); 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 243b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_reject(Action* a, int status, const char* resp) { 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return cb_check(a, status, resp, 1); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 247b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savillevoid fb_queue_require(const char *prod, const char *var, 248fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes bool invert, size_t nvalues, const char **value) 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_QUERY, "getvar:%s", var); 252b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->prod = prod; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = value; 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->size = nvalues; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("checking %s", var); 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = invert ? cb_reject : cb_require; 257b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes if (a->data == nullptr) die("out of memory"); 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 260b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_display(Action* a, int status, const char* resp) { 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) { 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s: %s\n", (char*) a->data, resp); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_display(const char *var, const char *prettyname) 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_QUERY, "getvar:%s", var); 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = strdup(prettyname); 274b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes if (a->data == nullptr) die("out of memory"); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = cb_display; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 278b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_save(Action* a, int status, const char* resp) { 279b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (status) { 280b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); 281b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return status; 282b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 283b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes strncpy(reinterpret_cast<char*>(a->data), resp, a->size); 284b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return 0; 285b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville} 286b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 287b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savillevoid fb_queue_query_save(const char *var, char *dest, unsigned dest_size) 288b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville{ 289b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville Action *a; 290b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a = queue_action(OP_QUERY, "getvar:%s", var); 291b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->data = (void *)dest; 292b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->size = dest_size; 293b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->func = cb_save; 294b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville} 295b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 296b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_do_nothing(Action*, int , const char*) { 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"\n"); 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_reboot(void) 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_COMMAND, "reboot"); 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = cb_do_nothing; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = "rebooting"; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_command(const char *cmd, const char *msg) 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_COMMAND, cmd); 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = msg; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_download(const char *name, void *data, unsigned size) 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_DOWNLOAD, ""); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = data; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->size = size; 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("downloading '%s'", name); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_notice(const char *notice) 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_NOTICE, ""); 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = (void*) notice; 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 328157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachslervoid fb_queue_wait_for_disconnect(void) 329157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler{ 330157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler queue_action(OP_WAIT_FOR_DISCONNECT, ""); 331157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler} 332157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler 3330b156638307db890e5539b52521fd24beb3440cbDavid Pursellint fb_execute_queue(Transport* transport) 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char resp[FB_RESPONSE_SZ+1]; 337eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom int status = 0; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = action_list; 34013081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson if (!a) 34113081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson return status; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project resp[FB_RESPONSE_SZ] = 0; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 344cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double start = -1; 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (a = action_list; a; a = a->next) { 346cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = now(); 347cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler if (start < 0) start = a->start; 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (a->msg) { 34963e5205cd2f693bbfa54411f2dd20354bd30ffd8Brian Swetland // fprintf(stderr,"%30s... ",a->msg); 35063e5205cd2f693bbfa54411f2dd20354bd30ffd8Brian Swetland fprintf(stderr,"%s...\n",a->msg); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (a->op == OP_DOWNLOAD) { 3530b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_download_data(transport, a->data, a->size); 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = a->func(a, status, status ? fb_get_error() : ""); 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) break; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (a->op == OP_COMMAND) { 3570b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_command(transport, a->cmd); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = a->func(a, status, status ? fb_get_error() : ""); 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) break; 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (a->op == OP_QUERY) { 3610b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_command_response(transport, a->cmd, resp); 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = a->func(a, status, status ? fb_get_error() : resp); 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) break; 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (a->op == OP_NOTICE) { 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"%s\n",(char*)a->data); 366f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else if (a->op == OP_DOWNLOAD_SPARSE) { 3670b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_download_data_sparse(transport, reinterpret_cast<sparse_file*>(a->data)); 368f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross status = a->func(a, status, status ? fb_get_error() : ""); 369f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (status) break; 370157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler } else if (a->op == OP_WAIT_FOR_DISCONNECT) { 3710b156638307db890e5539b52521fd24beb3440cbDavid Pursell transport->WaitForDisconnect(); 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("bogus action"); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 376cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 377cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); 378eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom return status; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 380