| xj | 123f7cc | 2022-06-06 11:35:21 +0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2007 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <stdio.h> | 
|  | 18 | #include <stdlib.h> | 
|  | 19 | #include <string.h> | 
|  | 20 |  | 
|  | 21 | #include <sysdeps.h> | 
|  | 22 |  | 
|  | 23 | #define  TRACE_TAG  TRACE_TRANSPORT | 
|  | 24 | #include "adb.h" | 
|  | 25 |  | 
|  | 26 | #ifdef HAVE_BIG_ENDIAN | 
|  | 27 | #define H4(x)	(((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) | 
|  | 28 | static inline void fix_endians(apacket *p) | 
|  | 29 | { | 
|  | 30 | p->msg.command     = H4(p->msg.command); | 
|  | 31 | p->msg.arg0        = H4(p->msg.arg0); | 
|  | 32 | p->msg.arg1        = H4(p->msg.arg1); | 
|  | 33 | p->msg.data_length = H4(p->msg.data_length); | 
|  | 34 | p->msg.data_check  = H4(p->msg.data_check); | 
|  | 35 | p->msg.magic       = H4(p->msg.magic); | 
|  | 36 | } | 
|  | 37 | unsigned host_to_le32(unsigned n) | 
|  | 38 | { | 
|  | 39 | return H4(n); | 
|  | 40 | } | 
|  | 41 | #else | 
|  | 42 | #define fix_endians(p) do {} while (0) | 
|  | 43 | unsigned host_to_le32(unsigned n) | 
|  | 44 | { | 
|  | 45 | return n; | 
|  | 46 | } | 
|  | 47 | #endif | 
|  | 48 |  | 
|  | 49 | static int remote_read(apacket *p, atransport *t) | 
|  | 50 | { | 
|  | 51 | if(usb_read(t->usb, &p->msg, sizeof(amessage))){ | 
|  | 52 | D("remote usb: read terminated (message)\n"); | 
|  | 53 | return -1; | 
|  | 54 | } | 
|  | 55 |  | 
|  | 56 | fix_endians(p); | 
|  | 57 |  | 
|  | 58 | if(check_header(p)) { | 
|  | 59 | D("remote usb: check_header failed\n"); | 
|  | 60 | return -1; | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | if(p->msg.data_length) { | 
|  | 64 | if(usb_read(t->usb, p->data, p->msg.data_length)){ | 
|  | 65 | D("remote usb: terminated (data)\n"); | 
|  | 66 | return -1; | 
|  | 67 | } | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | if(check_data(p)) { | 
|  | 71 | D("remote usb: check_data failed\n"); | 
|  | 72 | return -1; | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | return 0; | 
|  | 76 | } | 
|  | 77 |  | 
|  | 78 | static int remote_write(apacket *p, atransport *t) | 
|  | 79 | { | 
|  | 80 | unsigned size = p->msg.data_length; | 
|  | 81 |  | 
|  | 82 | fix_endians(p); | 
|  | 83 |  | 
|  | 84 | if(usb_write(t->usb, &p->msg, sizeof(amessage))) { | 
|  | 85 | D("remote usb: 1 - write terminated\n"); | 
|  | 86 | return -1; | 
|  | 87 | } | 
|  | 88 | if(p->msg.data_length == 0) return 0; | 
|  | 89 | if(usb_write(t->usb, &p->data, size)) { | 
|  | 90 | D("remote usb: 2 - write terminated\n"); | 
|  | 91 | return -1; | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | return 0; | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | static void remote_close(atransport *t) | 
|  | 98 | { | 
|  | 99 | usb_close(t->usb); | 
|  | 100 | t->usb = 0; | 
|  | 101 | } | 
|  | 102 |  | 
|  | 103 | static void remote_kick(atransport *t) | 
|  | 104 | { | 
|  | 105 | usb_kick(t->usb); | 
|  | 106 | } | 
|  | 107 |  | 
|  | 108 | void init_usb_transport(atransport *t, usb_handle *h, int state) | 
|  | 109 | { | 
|  | 110 | D("transport: usb\n"); | 
|  | 111 | t->close = remote_close; | 
|  | 112 | t->kick = remote_kick; | 
|  | 113 | t->read_from_remote = remote_read; | 
|  | 114 | t->write_to_remote = remote_write; | 
|  | 115 | t->sync_token = 1; | 
|  | 116 | t->connection_state = state; | 
|  | 117 | t->type = kTransportUsb; | 
|  | 118 | t->usb = h; | 
|  | 119 |  | 
|  | 120 | #if ADB_HOST | 
|  | 121 | HOST = 1; | 
|  | 122 | #else | 
|  | 123 | HOST = 0; | 
|  | 124 | #endif | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | #if ADB_HOST | 
|  | 128 | int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol) | 
|  | 129 | { | 
|  | 130 | return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL); | 
|  | 131 | } | 
|  | 132 | #endif |