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 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_DOWNLOAD 1 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_COMMAND 2 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_QUERY 3 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OP_NOTICE 4 45e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg#define OP_DOWNLOAD_SPARSE 5 46e6f3e9bd2656fe132f829ed035fdea0cb111369dDmitry Grinberg#define OP_WAIT_FOR_DISCONNECT 6 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct Action Action; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau#define CMD_SIZE 64 51c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 52fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughesstruct Action { 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned op; 54fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes Action* next; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau char cmd[CMD_SIZE]; 57fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes const char* prod; 58fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes void* data; 59fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes 60fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes // The protocol only supports 32-bit sizes, so you'll have to break 61fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes // anything larger into chunks. 62fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes uint32_t size; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *msg; 65b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes int (*func)(Action* a, int status, const char* resp); 66cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 67cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double start; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic Action *action_list = 0; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic Action *action_last = 0; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 73c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 74c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 75c8ba5366da7e23ebf1cd76bcf49449b878563102Anatol Pomazau 760b156638307db890e5539b52521fd24beb3440cbDavid Pursellbool fb_getvar(Transport* transport, const std::string& key, std::string* value) { 772fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes std::string cmd = "getvar:"; 782fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes cmd += key; 792fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes 802fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes char buf[FB_RESPONSE_SZ + 1]; 812fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes memset(buf, 0, sizeof(buf)); 820b156638307db890e5539b52521fd24beb3440cbDavid Pursell if (fb_command_response(transport, cmd.c_str(), buf)) { 832fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes return false; 842fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes } 852fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes *value = buf; 862fd45a9cea9d31375a44ba36b065c2f8a2999993Elliott Hughes return true; 8780f2d036a9dff894df27961c4aed300f1a5ebbc4Colin Cross} 8880f2d036a9dff894df27961c4aed300f1a5ebbc4Colin Cross 89b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_default(Action* a, int status, const char* resp) { 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FAILED (%s)\n", resp); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 93cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double split = now(); 94cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler fprintf(stderr,"OKAY [%7.3fs]\n", (split - a->start)); 95cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = split; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic Action *queue_action(unsigned op, const char *fmt, ...) 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 10350b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare size_t cmdsize; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 105b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes Action* a = reinterpret_cast<Action*>(calloc(1, sizeof(Action))); 106b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes if (a == nullptr) die("out of memory"); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 10950b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare cmdsize = vsnprintf(a->cmd, sizeof(a->cmd), fmt, ap); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11250b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare if (cmdsize >= sizeof(a->cmd)) { 11350b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare free(a); 11450b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare die("Command length (%d) exceeds maximum size (%d)", cmdsize, sizeof(a->cmd)); 11550b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare } 11650b3995d027b53f24bbba099b3b6884d5845b614Bruce Beare 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (action_last) { 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_last->next = a; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_list = a; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_last = a; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->op = op; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = cb_default; 125cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 126cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = -1; 127cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return a; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 131b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenbergvoid fb_set_active(const char *slot) 132b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg{ 133b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg Action *a; 134b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg a = queue_action(OP_COMMAND, "set_active:%s", slot); 135b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg a->msg = mkmsg("Setting current slot to '%s'", slot); 136b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg} 137b7bd4ae529148e7f4d830d98ea0a75bdc5d1ac17Daniel Rosenberg 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_erase(const char *ptn) 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_COMMAND, "erase:%s", ptn); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("erasing '%s'", ptn); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1458d7ddb35d510824e50833a9b31ae6486393b1436Alexander Levitskiyvoid fb_queue_flash(const char *ptn, void *data, unsigned sz) 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_DOWNLOAD, ""); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = data; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->size = sz; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("sending '%s' (%d KB)", ptn, sz / 1024); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_COMMAND, "flash:%s", ptn); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("writing '%s'", ptn); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1589da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gaovoid fb_queue_flash_sparse(const char* ptn, struct sparse_file* s, unsigned sz, size_t current, 1599da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gao size_t total) { 160f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross Action *a; 161f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 162f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a = queue_action(OP_DOWNLOAD_SPARSE, ""); 163f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a->data = s; 164f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a->size = 0; 1659da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gao a->msg = mkmsg("sending sparse '%s' %zu/%zu (%d KB)", ptn, current, total, sz / 1024); 166f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 167f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross a = queue_action(OP_COMMAND, "flash:%s", ptn); 1689da9ac5b2a109fa61826bc2609011ea84f175c28Josh Gao a->msg = mkmsg("writing '%s' %zu/%zu", ptn, current, total); 169f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross} 170f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross 171b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int match(const char* str, const char** value, unsigned count) { 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < count; n++) { 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *val = value[n]; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(val); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int match; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((len > 1) && (val[len-1] == '*')) { 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len--; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project match = !strncmp(val, str, len); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project match = !strcmp(val, str); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (match) return 1; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 194b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_check(Action* a, int status, const char* resp, int invert) 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 196b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes const char** value = reinterpret_cast<const char**>(a->data); 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count = a->size; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int yes; 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FAILED (%s)\n", resp); 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (a->prod) { 207b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (strcmp(a->prod, cur_product) != 0) { 208b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville double split = now(); 209b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fprintf(stderr,"IGNORE, product is %s required only for %s [%7.3fs]\n", 210b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville cur_product, a->prod, (split - a->start)); 211b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->start = split; 212b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return 0; 213b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 214b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 215b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project yes = match(resp, value, count); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (invert) yes = !yes; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (yes) { 220cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double split = now(); 221cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler fprintf(stderr,"OKAY [%7.3fs]\n", (split - a->start)); 222cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = split; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"FAILED\n\n"); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Device %s is '%s'.\n", a->cmd + 7, resp); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Update %s '%s'", 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project invert ? "rejects" : "requires", value[0]); 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 1; n < count; n++) { 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr," or '%s'", value[n]); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,".\n\n"); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 237b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_require(Action*a, int status, const char* resp) { 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return cb_check(a, status, resp, 0); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_reject(Action* a, int status, const char* resp) { 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return cb_check(a, status, resp, 1); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 245b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savillevoid fb_queue_require(const char *prod, const char *var, 246fc79767fc26d8782403e7b1afa7b93d518a86b19Elliott Hughes bool invert, size_t nvalues, const char **value) 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_QUERY, "getvar:%s", var); 250b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->prod = prod; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = value; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->size = nvalues; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("checking %s", var); 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = invert ? cb_reject : cb_require; 255b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes if (a->data == nullptr) die("out of memory"); 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 258b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_display(Action* a, int status, const char* resp) { 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) { 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s: %s\n", (char*) a->data, resp); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_display(const char *var, const char *prettyname) 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = queue_action(OP_QUERY, "getvar:%s", var); 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = strdup(prettyname); 272b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes if (a->data == nullptr) die("out of memory"); 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = cb_display; 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 276b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_save(Action* a, int status, const char* resp) { 277b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (status) { 278b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); 279b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return status; 280b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 281b3748de33f651597259f52e4645571a1da2e32ddElliott Hughes strncpy(reinterpret_cast<char*>(a->data), resp, a->size); 282b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return 0; 283b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville} 284b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 285b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savillevoid fb_queue_query_save(const char *var, char *dest, unsigned dest_size) 286b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville{ 287b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville Action *a; 288b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a = queue_action(OP_QUERY, "getvar:%s", var); 289b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->data = (void *)dest; 290b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->size = dest_size; 291b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville a->func = cb_save; 292b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville} 293b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville 294b3748de33f651597259f52e4645571a1da2e32ddElliott Hughesstatic int cb_do_nothing(Action*, int , const char*) { 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"\n"); 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_reboot(void) 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_COMMAND, "reboot"); 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->func = cb_do_nothing; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = "rebooting"; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_command(const char *cmd, const char *msg) 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_COMMAND, cmd); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = msg; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_download(const char *name, void *data, unsigned size) 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_DOWNLOAD, ""); 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = data; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->size = size; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->msg = mkmsg("downloading '%s'", name); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fb_queue_notice(const char *notice) 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a = queue_action(OP_NOTICE, ""); 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a->data = (void*) notice; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachslervoid fb_queue_wait_for_disconnect(void) 327157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler{ 328157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler queue_action(OP_WAIT_FOR_DISCONNECT, ""); 329157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler} 330157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler 3310b156638307db890e5539b52521fd24beb3440cbDavid Pursellint fb_execute_queue(Transport* transport) 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Action *a; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char resp[FB_RESPONSE_SZ+1]; 335eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom int status = 0; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project a = action_list; 33813081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson if (!a) 33913081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson return status; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project resp[FB_RESPONSE_SZ] = 0; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 342cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler double start = -1; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (a = action_list; a; a = a->next) { 344cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler a->start = now(); 345cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler if (start < 0) start = a->start; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (a->msg) { 34763e5205cd2f693bbfa54411f2dd20354bd30ffd8Brian Swetland // fprintf(stderr,"%30s... ",a->msg); 34863e5205cd2f693bbfa54411f2dd20354bd30ffd8Brian Swetland fprintf(stderr,"%s...\n",a->msg); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (a->op == OP_DOWNLOAD) { 3510b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_download_data(transport, a->data, a->size); 3522810d00dd95ed78fdd93f2ed68f06ee32bd8e1acElliott Hughes status = a->func(a, status, status ? fb_get_error().c_str() : ""); 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) break; 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (a->op == OP_COMMAND) { 3550b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_command(transport, a->cmd); 3562810d00dd95ed78fdd93f2ed68f06ee32bd8e1acElliott Hughes status = a->func(a, status, status ? fb_get_error().c_str() : ""); 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) break; 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (a->op == OP_QUERY) { 3590b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_command_response(transport, a->cmd, resp); 3602810d00dd95ed78fdd93f2ed68f06ee32bd8e1acElliott Hughes status = a->func(a, status, status ? fb_get_error().c_str() : resp); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status) break; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (a->op == OP_NOTICE) { 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"%s\n",(char*)a->data); 364f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross } else if (a->op == OP_DOWNLOAD_SPARSE) { 3650b156638307db890e5539b52521fd24beb3440cbDavid Pursell status = fb_download_data_sparse(transport, reinterpret_cast<sparse_file*>(a->data)); 3662810d00dd95ed78fdd93f2ed68f06ee32bd8e1acElliott Hughes status = a->func(a, status, status ? fb_get_error().c_str() : ""); 367f838788e6a4d57634a53eb597ee76a597feffcb5Colin Cross if (status) break; 368157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler } else if (a->op == OP_WAIT_FOR_DISCONNECT) { 3690b156638307db890e5539b52521fd24beb3440cbDavid Pursell transport->WaitForDisconnect(); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project die("bogus action"); 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 374cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler 375cb6e22b687eee5a47c642620d2e995b60f60f3e7Daniel Sandler fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); 376eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom return status; 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 378