Merge "Prepare for switching to libziparchive."
This commit is contained in:
commit
57bf3109db
7 changed files with 123 additions and 79 deletions
|
|
@ -19,10 +19,11 @@ include $(CLEAR_VARS)
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
|
||||||
$(LOCAL_PATH)/../../extras/ext4_utils \
|
$(LOCAL_PATH)/../../extras/ext4_utils \
|
||||||
$(LOCAL_PATH)/../../extras/f2fs_utils
|
$(LOCAL_PATH)/../../extras/f2fs_utils
|
||||||
LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c util.c fs.c
|
LOCAL_SRC_FILES := protocol.c engine.c bootimg_utils.cpp fastboot.cpp util.c fs.c
|
||||||
LOCAL_MODULE := fastboot
|
LOCAL_MODULE := fastboot
|
||||||
LOCAL_MODULE_TAGS := debug
|
LOCAL_MODULE_TAGS := debug
|
||||||
LOCAL_CFLAGS += -std=gnu99 -Werror
|
LOCAL_CONLYFLAGS += -std=gnu99
|
||||||
|
LOCAL_CFLAGS += -Wall -Werror
|
||||||
|
|
||||||
ifeq ($(HOST_OS),linux)
|
ifeq ($(HOST_OS),linux)
|
||||||
LOCAL_SRC_FILES += usb_linux.c util_linux.c
|
LOCAL_SRC_FILES += usb_linux.c util_linux.c
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,12 @@
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "bootimg_utils.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <bootimg.h>
|
|
||||||
|
|
||||||
void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline)
|
void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline)
|
||||||
{
|
{
|
||||||
strcpy((char*) h->cmdline, cmdline);
|
strcpy((char*) h->cmdline, cmdline);
|
||||||
|
|
@ -47,7 +47,6 @@ boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offs
|
||||||
unsigned ramdisk_actual;
|
unsigned ramdisk_actual;
|
||||||
unsigned second_actual;
|
unsigned second_actual;
|
||||||
unsigned page_mask;
|
unsigned page_mask;
|
||||||
boot_img_hdr *hdr;
|
|
||||||
|
|
||||||
page_mask = page_size - 1;
|
page_mask = page_size - 1;
|
||||||
|
|
||||||
|
|
@ -57,9 +56,8 @@ boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offs
|
||||||
|
|
||||||
*bootimg_size = page_size + kernel_actual + ramdisk_actual + second_actual;
|
*bootimg_size = page_size + kernel_actual + ramdisk_actual + second_actual;
|
||||||
|
|
||||||
hdr = calloc(*bootimg_size, 1);
|
boot_img_hdr* hdr = reinterpret_cast<boot_img_hdr*>(calloc(*bootimg_size, 1));
|
||||||
|
if (hdr == 0) {
|
||||||
if(hdr == 0) {
|
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
49
fastboot/bootimg_utils.h
Normal file
49
fastboot/bootimg_utils.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FASTBOOT_BOOTIMG_UTILS_H_
|
||||||
|
#define _FASTBOOT_BOOTIMG_UTILS_H_
|
||||||
|
|
||||||
|
#include <bootimg.h>
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline);
|
||||||
|
boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset,
|
||||||
|
void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset,
|
||||||
|
void *second, unsigned second_size, unsigned second_offset,
|
||||||
|
unsigned page_size, unsigned base, unsigned tags_offset,
|
||||||
|
unsigned *bootimg_size);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -44,10 +44,10 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <bootimg.h>
|
|
||||||
#include <sparse/sparse.h>
|
#include <sparse/sparse.h>
|
||||||
#include <zipfile/zipfile.h>
|
#include <zipfile/zipfile.h>
|
||||||
|
|
||||||
|
#include "bootimg_utils.h"
|
||||||
#include "fastboot.h"
|
#include "fastboot.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
|
|
@ -59,14 +59,6 @@
|
||||||
|
|
||||||
char cur_product[FB_RESPONSE_SZ + 1];
|
char cur_product[FB_RESPONSE_SZ + 1];
|
||||||
|
|
||||||
void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline);
|
|
||||||
|
|
||||||
boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset,
|
|
||||||
void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset,
|
|
||||||
void *second, unsigned second_size, unsigned second_offset,
|
|
||||||
unsigned page_size, unsigned base, unsigned tags_offset,
|
|
||||||
unsigned *bootimg_size);
|
|
||||||
|
|
||||||
static usb_handle *usb = 0;
|
static usb_handle *usb = 0;
|
||||||
static const char *serial = 0;
|
static const char *serial = 0;
|
||||||
static const char *product = 0;
|
static const char *product = 0;
|
||||||
|
|
@ -106,12 +98,10 @@ static struct {
|
||||||
{"vendor.img", "vendor.sig", "vendor", true},
|
{"vendor.img", "vendor.sig", "vendor", true},
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_my_path(char *path);
|
|
||||||
|
|
||||||
char *find_item(const char *item, const char *product)
|
char *find_item(const char *item, const char *product)
|
||||||
{
|
{
|
||||||
char *dir;
|
char *dir;
|
||||||
char *fn;
|
const char *fn;
|
||||||
char path[PATH_MAX + 128];
|
char path[PATH_MAX + 128];
|
||||||
|
|
||||||
if(!strcmp(item,"boot")) {
|
if(!strcmp(item,"boot")) {
|
||||||
|
|
@ -234,7 +224,7 @@ int match_fastboot(usb_ifc_info *info)
|
||||||
int list_devices_callback(usb_ifc_info *info)
|
int list_devices_callback(usb_ifc_info *info)
|
||||||
{
|
{
|
||||||
if (match_fastboot_with_serial(info, NULL) == 0) {
|
if (match_fastboot_with_serial(info, NULL) == 0) {
|
||||||
char* serial = info->serial_number;
|
const char* serial = info->serial_number;
|
||||||
if (!info->writable) {
|
if (!info->writable) {
|
||||||
serial = "no permissions"; // like "adb devices"
|
serial = "no permissions"; // like "adb devices"
|
||||||
}
|
}
|
||||||
|
|
@ -389,7 +379,7 @@ void *load_bootable_image(const char *kernel, const char *ramdisk,
|
||||||
return bdata;
|
return bdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *unzip_file(zipfile_t zip, const char *name, unsigned *sz)
|
static void *unzip_file(zipfile_t zip, const char *name, unsigned *sz)
|
||||||
{
|
{
|
||||||
void *data;
|
void *data;
|
||||||
zipentry_t entry;
|
zipentry_t entry;
|
||||||
|
|
@ -422,16 +412,13 @@ void *unzip_file(zipfile_t zip, const char *name, unsigned *sz)
|
||||||
|
|
||||||
static int unzip_to_file(zipfile_t zip, char *name)
|
static int unzip_to_file(zipfile_t zip, char *name)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd = fileno(tmpfile());
|
||||||
char *data;
|
|
||||||
unsigned sz;
|
|
||||||
|
|
||||||
fd = fileno(tmpfile());
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = unzip_file(zip, name, &sz);
|
unsigned sz;
|
||||||
|
void* data = unzip_file(zip, name, &sz);
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -461,7 +448,6 @@ static char *strip(char *s)
|
||||||
static int setup_requirement_line(char *name)
|
static int setup_requirement_line(char *name)
|
||||||
{
|
{
|
||||||
char *val[MAX_OPTIONS];
|
char *val[MAX_OPTIONS];
|
||||||
const char **out;
|
|
||||||
char *prod = NULL;
|
char *prod = NULL;
|
||||||
unsigned n, count;
|
unsigned n, count;
|
||||||
char *x;
|
char *x;
|
||||||
|
|
@ -501,10 +487,11 @@ static int setup_requirement_line(char *name)
|
||||||
name = strip(name);
|
name = strip(name);
|
||||||
if (name == 0) return -1;
|
if (name == 0) return -1;
|
||||||
|
|
||||||
/* work around an unfortunate name mismatch */
|
const char* var = name;
|
||||||
if (!strcmp(name,"board")) name = "product";
|
// Work around an unfortunate name mismatch.
|
||||||
|
if (!strcmp(name,"board")) var = "product";
|
||||||
|
|
||||||
out = malloc(sizeof(char*) * count);
|
const char** out = reinterpret_cast<const char**>(malloc(sizeof(char*) * count));
|
||||||
if (out == 0) return -1;
|
if (out == 0) return -1;
|
||||||
|
|
||||||
for(n = 0; n < count; n++) {
|
for(n = 0; n < count; n++) {
|
||||||
|
|
@ -518,7 +505,7 @@ static int setup_requirement_line(char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_queue_require(prod, name, invert, n, out);
|
fb_queue_require(prod, var, invert, n, out);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -551,21 +538,17 @@ void queue_info_dump(void)
|
||||||
|
|
||||||
static struct sparse_file **load_sparse_files(int fd, int max_size)
|
static struct sparse_file **load_sparse_files(int fd, int max_size)
|
||||||
{
|
{
|
||||||
struct sparse_file *s;
|
struct sparse_file* s = sparse_file_import_auto(fd, false);
|
||||||
int files;
|
|
||||||
struct sparse_file **out_s;
|
|
||||||
|
|
||||||
s = sparse_file_import_auto(fd, false);
|
|
||||||
if (!s) {
|
if (!s) {
|
||||||
die("cannot sparse read file\n");
|
die("cannot sparse read file\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
files = sparse_file_resparse(s, max_size, NULL, 0);
|
int files = sparse_file_resparse(s, max_size, NULL, 0);
|
||||||
if (files < 0) {
|
if (files < 0) {
|
||||||
die("Failed to resparse\n");
|
die("Failed to resparse\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
out_s = calloc(sizeof(struct sparse_file *), files + 1);
|
sparse_file** out_s = reinterpret_cast<sparse_file**>(calloc(sizeof(struct sparse_file *), files + 1));
|
||||||
if (!out_s) {
|
if (!out_s) {
|
||||||
die("Failed to allocate sparse file array\n");
|
die("Failed to allocate sparse file array\n");
|
||||||
}
|
}
|
||||||
|
|
@ -682,11 +665,11 @@ static int load_buf(usb_handle *usb, const char *fname,
|
||||||
|
|
||||||
static void flash_buf(const char *pname, struct fastboot_buffer *buf)
|
static void flash_buf(const char *pname, struct fastboot_buffer *buf)
|
||||||
{
|
{
|
||||||
struct sparse_file **s;
|
sparse_file** s;
|
||||||
|
|
||||||
switch (buf->type) {
|
switch (buf->type) {
|
||||||
case FB_BUFFER_SPARSE:
|
case FB_BUFFER_SPARSE:
|
||||||
s = buf->data;
|
s = reinterpret_cast<sparse_file**>(buf->data);
|
||||||
while (*s) {
|
while (*s) {
|
||||||
int64_t sz64 = sparse_file_len(*s, true, false);
|
int64_t sz64 = sparse_file_len(*s, true, false);
|
||||||
fb_queue_flash_sparse(pname, *s++, sz64);
|
fb_queue_flash_sparse(pname, *s++, sz64);
|
||||||
|
|
@ -720,53 +703,42 @@ void do_update_signature(zipfile_t zip, char *fn)
|
||||||
fb_queue_command("signature", "installing signature");
|
fb_queue_command("signature", "installing signature");
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_update(usb_handle *usb, char *fn, int erase_first)
|
void do_update(usb_handle *usb, const char *filename, int erase_first)
|
||||||
{
|
{
|
||||||
void *zdata;
|
|
||||||
unsigned zsize;
|
|
||||||
void *data;
|
|
||||||
unsigned sz;
|
|
||||||
zipfile_t zip;
|
|
||||||
int fd;
|
|
||||||
int rc;
|
|
||||||
struct fastboot_buffer buf;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
queue_info_dump();
|
queue_info_dump();
|
||||||
|
|
||||||
fb_queue_query_save("product", cur_product, sizeof(cur_product));
|
fb_queue_query_save("product", cur_product, sizeof(cur_product));
|
||||||
|
|
||||||
zdata = load_file(fn, &zsize);
|
unsigned zsize;
|
||||||
if (zdata == 0) die("failed to load '%s': %s", fn, strerror(errno));
|
void* zdata = load_file(filename, &zsize);
|
||||||
|
if (zdata == 0) die("failed to load '%s': %s", filename, strerror(errno));
|
||||||
|
|
||||||
zip = init_zipfile(zdata, zsize);
|
zipfile_t zip = init_zipfile(zdata, zsize);
|
||||||
if(zip == 0) die("failed to access zipdata in '%s'");
|
if (zip == 0) die("failed to access zipdata in '%s'");
|
||||||
|
|
||||||
data = unzip_file(zip, "android-info.txt", &sz);
|
unsigned sz;
|
||||||
|
void* data = unzip_file(zip, "android-info.txt", &sz);
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
char *tmp;
|
|
||||||
/* fallback for older zipfiles */
|
/* fallback for older zipfiles */
|
||||||
data = unzip_file(zip, "android-product.txt", &sz);
|
data = unzip_file(zip, "android-product.txt", &sz);
|
||||||
if ((data == 0) || (sz < 1)) {
|
if ((data == 0) || (sz < 1)) {
|
||||||
die("update package has no android-info.txt or android-product.txt");
|
die("update package has no android-info.txt or android-product.txt");
|
||||||
}
|
}
|
||||||
tmp = malloc(sz + 128);
|
data = mkmsg("board=%sversion-baseband=0.66.04.19\n", reinterpret_cast<char*>(data));
|
||||||
if (tmp == 0) die("out of memory");
|
sz = strlen(reinterpret_cast<char*>(data));
|
||||||
sprintf(tmp,"board=%sversion-baseband=0.66.04.19\n",(char*)data);
|
|
||||||
data = tmp;
|
|
||||||
sz = strlen(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_requirements(data, sz);
|
setup_requirements(reinterpret_cast<char*>(data), sz);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(images); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
|
||||||
fd = unzip_to_file(zip, images[i].img_name);
|
int fd = unzip_to_file(zip, images[i].img_name);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
if (images[i].is_optional)
|
if (images[i].is_optional)
|
||||||
continue;
|
continue;
|
||||||
die("update package missing %s", images[i].img_name);
|
die("update package missing %s", images[i].img_name);
|
||||||
}
|
}
|
||||||
rc = load_buf_fd(usb, fd, &buf);
|
fastboot_buffer buf;
|
||||||
|
int rc = load_buf_fd(usb, fd, &buf);
|
||||||
if (rc) die("cannot load %s from flash", images[i].img_name);
|
if (rc) die("cannot load %s from flash", images[i].img_name);
|
||||||
do_update_signature(zip, images[i].sig_name);
|
do_update_signature(zip, images[i].sig_name);
|
||||||
if (erase_first && needs_erase(images[i].part_name)) {
|
if (erase_first && needs_erase(images[i].part_name)) {
|
||||||
|
|
@ -800,24 +772,22 @@ void do_send_signature(char *fn)
|
||||||
|
|
||||||
void do_flashall(usb_handle *usb, int erase_first)
|
void do_flashall(usb_handle *usb, int erase_first)
|
||||||
{
|
{
|
||||||
char *fname;
|
|
||||||
void *data;
|
|
||||||
unsigned sz;
|
|
||||||
struct fastboot_buffer buf;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
queue_info_dump();
|
queue_info_dump();
|
||||||
|
|
||||||
fb_queue_query_save("product", cur_product, sizeof(cur_product));
|
fb_queue_query_save("product", cur_product, sizeof(cur_product));
|
||||||
|
|
||||||
fname = find_item("info", product);
|
char* fname = find_item("info", product);
|
||||||
if (fname == 0) die("cannot find android-info.txt");
|
if (fname == 0) die("cannot find android-info.txt");
|
||||||
data = load_file(fname, &sz);
|
|
||||||
if (data == 0) die("could not load android-info.txt: %s", strerror(errno));
|
|
||||||
setup_requirements(data, sz);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(images); i++) {
|
unsigned sz;
|
||||||
|
void* data = load_file(fname, &sz);
|
||||||
|
if (data == 0) die("could not load android-info.txt: %s", strerror(errno));
|
||||||
|
|
||||||
|
setup_requirements(reinterpret_cast<char*>(data), sz);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
|
||||||
fname = find_item(images[i].part_name, product);
|
fname = find_item(images[i].part_name, product);
|
||||||
|
fastboot_buffer buf;
|
||||||
if (load_buf(usb, fname, &buf)) {
|
if (load_buf(usb, fname, &buf)) {
|
||||||
if (images[i].is_optional)
|
if (images[i].is_optional)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -31,6 +31,10 @@
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sparse_file;
|
struct sparse_file;
|
||||||
|
|
||||||
/* protocol.c - fastboot protocol */
|
/* protocol.c - fastboot protocol */
|
||||||
|
|
@ -67,7 +71,13 @@ double now();
|
||||||
char *mkmsg(const char *fmt, ...);
|
char *mkmsg(const char *fmt, ...);
|
||||||
void die(const char *fmt, ...);
|
void die(const char *fmt, ...);
|
||||||
|
|
||||||
|
void get_my_path(char *path);
|
||||||
|
|
||||||
/* Current product */
|
/* Current product */
|
||||||
extern char cur_product[FB_RESPONSE_SZ + 1];
|
extern char cur_product[FB_RESPONSE_SZ + 1];
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,18 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
struct fs_generator;
|
struct fs_generator;
|
||||||
|
|
||||||
const struct fs_generator* fs_get_generator(const char *fs_type);
|
const struct fs_generator* fs_get_generator(const char *fs_type);
|
||||||
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize);
|
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@
|
||||||
#ifndef _USB_H_
|
#ifndef _USB_H_
|
||||||
#define _USB_H_
|
#define _USB_H_
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct usb_handle usb_handle;
|
typedef struct usb_handle usb_handle;
|
||||||
|
|
||||||
typedef struct usb_ifc_info usb_ifc_info;
|
typedef struct usb_ifc_info usb_ifc_info;
|
||||||
|
|
@ -64,4 +68,8 @@ int usb_read(usb_handle *h, void *_data, int len);
|
||||||
int usb_write(usb_handle *h, const void *_data, int len);
|
int usb_write(usb_handle *h, const void *_data, int len);
|
||||||
int usb_wait_for_disconnect(usb_handle *h);
|
int usb_wait_for_disconnect(usb_handle *h);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue