This program is for an autonomous robot for the competition at the Hochschule Luzern. http://cruisingcrepe.wordpress.com/ We are one of the 32 teams. http://cruisingcrepe.wordpress.com/ The postition control is based on this Documentation: Control of Wheeled Mobile Robots: An Experimental Overview from Alessandro De Luca, Giuseppe Oriolo, Marilena Vendittelli. For more information see here: http://www.dis.uniroma1.it/~labrob/pub/papers/Ramsete01.pdf

Dependencies:   mbed

Fork of autonomous Robot Android by Christian Burri

Committer:
chrigelburri
Date:
Fri May 03 08:35:29 2013 +0000
Revision:
18:306d362d692b
androidADB successfully linking

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chrigelburri 18:306d362d692b 1 /*
chrigelburri 18:306d362d692b 2 Copyright 2011 Niels Brouwers
chrigelburri 18:306d362d692b 3
chrigelburri 18:306d362d692b 4 Licensed under the Apache License, Version 2.0 (the "License");
chrigelburri 18:306d362d692b 5 you may not use this file except in compliance with the License.
chrigelburri 18:306d362d692b 6 You may obtain a copy of the License at
chrigelburri 18:306d362d692b 7
chrigelburri 18:306d362d692b 8 http://www.apache.org/licenses/LICENSE-2.0
chrigelburri 18:306d362d692b 9
chrigelburri 18:306d362d692b 10 Unless required by applicable law or agreed to in writing, software
chrigelburri 18:306d362d692b 11 distributed under the License is distributed on an "AS IS" BASIS,
chrigelburri 18:306d362d692b 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
chrigelburri 18:306d362d692b 13 See the License for the specific language governing permissions and
chrigelburri 18:306d362d692b 14 limitations under the License.
chrigelburri 18:306d362d692b 15 */
chrigelburri 18:306d362d692b 16
chrigelburri 18:306d362d692b 17 /* Changed by Junichi Katsu */
chrigelburri 18:306d362d692b 18
chrigelburri 18:306d362d692b 19 #include <string.h>
chrigelburri 18:306d362d692b 20 #include <Adb.h>
chrigelburri 18:306d362d692b 21
chrigelburri 18:306d362d692b 22 //#define DEBUG
chrigelburri 18:306d362d692b 23
chrigelburri 18:306d362d692b 24 #define MAX_BUF_SIZE 128
chrigelburri 18:306d362d692b 25
chrigelburri 18:306d362d692b 26 #ifdef DEBUG
chrigelburri 18:306d362d692b 27 #define log(...) printf(__VA_ARGS__)
chrigelburri 18:306d362d692b 28 #else
chrigelburri 18:306d362d692b 29 #define log(...) do {} while(0)
chrigelburri 18:306d362d692b 30 #endif
chrigelburri 18:306d362d692b 31
chrigelburri 18:306d362d692b 32 int input_ep;
chrigelburri 18:306d362d692b 33 int output_ep;
chrigelburri 18:306d362d692b 34 int _device;
chrigelburri 18:306d362d692b 35 int _configuration;
chrigelburri 18:306d362d692b 36 int _interfaceNumber;
chrigelburri 18:306d362d692b 37
chrigelburri 18:306d362d692b 38 static Connection * firstConnection;
chrigelburri 18:306d362d692b 39 static boolean connected;
chrigelburri 18:306d362d692b 40 static int connectionLocalId = 1;
chrigelburri 18:306d362d692b 41 unsigned char readbuff[MAX_BUF_SIZE];
chrigelburri 18:306d362d692b 42
chrigelburri 18:306d362d692b 43 // Event handler callback function.
chrigelburri 18:306d362d692b 44 adb_eventHandler * eventHandler;
chrigelburri 18:306d362d692b 45
chrigelburri 18:306d362d692b 46 ADB* _adb;
chrigelburri 18:306d362d692b 47 PacketBuffer recv_packet_buf(100,MAX_BUF_SIZE);
chrigelburri 18:306d362d692b 48 Ticker timer;
chrigelburri 18:306d362d692b 49
chrigelburri 18:306d362d692b 50 int time_ms = 0;
chrigelburri 18:306d362d692b 51
chrigelburri 18:306d362d692b 52
chrigelburri 18:306d362d692b 53 void attime(void)
chrigelburri 18:306d362d692b 54 {
chrigelburri 18:306d362d692b 55 time_ms++;
chrigelburri 18:306d362d692b 56 }
chrigelburri 18:306d362d692b 57
chrigelburri 18:306d362d692b 58 int millis()
chrigelburri 18:306d362d692b 59 {
chrigelburri 18:306d362d692b 60 return(time_ms);
chrigelburri 18:306d362d692b 61 }
chrigelburri 18:306d362d692b 62
chrigelburri 18:306d362d692b 63 char *strdup(const char *src)
chrigelburri 18:306d362d692b 64 {
chrigelburri 18:306d362d692b 65 char *p;
chrigelburri 18:306d362d692b 66
chrigelburri 18:306d362d692b 67 if(src == NULL){
chrigelburri 18:306d362d692b 68 return NULL;
chrigelburri 18:306d362d692b 69 }
chrigelburri 18:306d362d692b 70
chrigelburri 18:306d362d692b 71 p = (char *)malloc(strlen(src) + 1);
chrigelburri 18:306d362d692b 72 if(p != NULL) strcpy(p, src);
chrigelburri 18:306d362d692b 73 return p;
chrigelburri 18:306d362d692b 74
chrigelburri 18:306d362d692b 75 }
chrigelburri 18:306d362d692b 76
chrigelburri 18:306d362d692b 77 /**
chrigelburri 18:306d362d692b 78 * Initialises the ADB protocol. This function initialises the USB layer underneath so no further setup is required.
chrigelburri 18:306d362d692b 79 */
chrigelburri 18:306d362d692b 80 void ADB::init()
chrigelburri 18:306d362d692b 81 {
chrigelburri 18:306d362d692b 82 recv_packet_buf.clear();
chrigelburri 18:306d362d692b 83
chrigelburri 18:306d362d692b 84 // Signal that we are not connected.
chrigelburri 18:306d362d692b 85 _device = 0;
chrigelburri 18:306d362d692b 86 connected = false;
chrigelburri 18:306d362d692b 87
chrigelburri 18:306d362d692b 88
chrigelburri 18:306d362d692b 89 // Initialise Usb host.
chrigelburri 18:306d362d692b 90 USBInit();
chrigelburri 18:306d362d692b 91
chrigelburri 18:306d362d692b 92 timer.attach_us(&attime, 1000);
chrigelburri 18:306d362d692b 93 }
chrigelburri 18:306d362d692b 94
chrigelburri 18:306d362d692b 95 /**
chrigelburri 18:306d362d692b 96 * Sets the ADB event handler function. This function will be called by the ADB layer
chrigelburri 18:306d362d692b 97 * when interesting events occur, such as ADB connect/disconnect, connection open/close, and
chrigelburri 18:306d362d692b 98 * connection writes from the ADB device.
chrigelburri 18:306d362d692b 99 *
chrigelburri 18:306d362d692b 100 * @param handler event handler function.
chrigelburri 18:306d362d692b 101 */
chrigelburri 18:306d362d692b 102 void ADB::setEventHandler(adb_eventHandler * handler)
chrigelburri 18:306d362d692b 103 {
chrigelburri 18:306d362d692b 104 eventHandler = handler;
chrigelburri 18:306d362d692b 105 }
chrigelburri 18:306d362d692b 106
chrigelburri 18:306d362d692b 107 /**
chrigelburri 18:306d362d692b 108 * Fires an ADB event.
chrigelburri 18:306d362d692b 109 * @param connection ADB connection. May be NULL in case of global connect/disconnect events.
chrigelburri 18:306d362d692b 110 * @param type event type.
chrigelburri 18:306d362d692b 111 * @param length payload length or zero if no payload.
chrigelburri 18:306d362d692b 112 * @param data payload data if relevant or NULL otherwise.
chrigelburri 18:306d362d692b 113 */
chrigelburri 18:306d362d692b 114 void ADB::fireEvent(Connection * connection, adb_eventType type, uint16_t length, uint8_t * data)
chrigelburri 18:306d362d692b 115 {
chrigelburri 18:306d362d692b 116 // Fire the global event handler, if set.
chrigelburri 18:306d362d692b 117 if (eventHandler!=NULL)
chrigelburri 18:306d362d692b 118 eventHandler(connection, type, length, data);
chrigelburri 18:306d362d692b 119
chrigelburri 18:306d362d692b 120 // Fire the event handler of the connection in question, if relevant
chrigelburri 18:306d362d692b 121 if (connection!=NULL && connection->eventHandler!=NULL)
chrigelburri 18:306d362d692b 122 connection->eventHandler(connection, type, length, data);
chrigelburri 18:306d362d692b 123 }
chrigelburri 18:306d362d692b 124
chrigelburri 18:306d362d692b 125 /**
chrigelburri 18:306d362d692b 126 * Adds a new ADB connection. The connection string is per ADB specs, for example "tcp:1234" opens a
chrigelburri 18:306d362d692b 127 * connection to tcp port 1234, and "shell:ls" outputs a listing of the phone root filesystem. Connections
chrigelburri 18:306d362d692b 128 * can be made persistent by setting reconnect to true. Persistent connections will be automatically
chrigelburri 18:306d362d692b 129 * reconnected when the USB cable is re-plugged in. Non-persistent connections will connect only once,
chrigelburri 18:306d362d692b 130 * and should never be used after they are closed.
chrigelburri 18:306d362d692b 131 *
chrigelburri 18:306d362d692b 132 * The connection string is copied into the Connection record and may not exceed ADB_CONNECTIONSTRING_LENGTH-1
chrigelburri 18:306d362d692b 133 * characters.
chrigelburri 18:306d362d692b 134 *
chrigelburri 18:306d362d692b 135 * @param connectionString ADB connectionstring. I.e. "tcp:1234" or "shell:ls".
chrigelburri 18:306d362d692b 136 * @param reconnect true for automatic reconnect (persistent connections).
chrigelburri 18:306d362d692b 137 * @param handler event handler.
chrigelburri 18:306d362d692b 138 * @return an ADB connection record or NULL on failure (not enough slots or connection string too long).
chrigelburri 18:306d362d692b 139 */
chrigelburri 18:306d362d692b 140 Connection * ADB::addConnection(const char * connectionString, boolean reconnect, adb_eventHandler * handler)
chrigelburri 18:306d362d692b 141 {
chrigelburri 18:306d362d692b 142
chrigelburri 18:306d362d692b 143 // Allocate a new ADB connection object
chrigelburri 18:306d362d692b 144 Connection * connection = (Connection*)malloc(sizeof(Connection));
chrigelburri 18:306d362d692b 145 if (connection == NULL) return NULL;
chrigelburri 18:306d362d692b 146
chrigelburri 18:306d362d692b 147 // Allocate memory for the connection string
chrigelburri 18:306d362d692b 148 connection->connectionString = (char*)strdup(connectionString);
chrigelburri 18:306d362d692b 149 if (connection->connectionString==NULL)
chrigelburri 18:306d362d692b 150 {
chrigelburri 18:306d362d692b 151 // Free the connection object and return null
chrigelburri 18:306d362d692b 152 free(connection);
chrigelburri 18:306d362d692b 153 return NULL;
chrigelburri 18:306d362d692b 154 }
chrigelburri 18:306d362d692b 155
chrigelburri 18:306d362d692b 156 // Initialise the newly created object.
chrigelburri 18:306d362d692b 157 connection->localID = connectionLocalId ++;
chrigelburri 18:306d362d692b 158 connection->status = ADB_CLOSED;
chrigelburri 18:306d362d692b 159 connection->lastConnectionAttempt = 0;
chrigelburri 18:306d362d692b 160 connection->reconnect = reconnect;
chrigelburri 18:306d362d692b 161 connection->eventHandler = handler;
chrigelburri 18:306d362d692b 162
chrigelburri 18:306d362d692b 163 // Add the connection to the linked list. Note that it's easier to just insert
chrigelburri 18:306d362d692b 164 // at position 0 because you don't have to traverse the list :)
chrigelburri 18:306d362d692b 165 connection->next = firstConnection;
chrigelburri 18:306d362d692b 166 firstConnection = connection;
chrigelburri 18:306d362d692b 167
chrigelburri 18:306d362d692b 168 // Unable to find an empty spot, all connection slots in use.
chrigelburri 18:306d362d692b 169 return connection;
chrigelburri 18:306d362d692b 170 }
chrigelburri 18:306d362d692b 171
chrigelburri 18:306d362d692b 172 /**
chrigelburri 18:306d362d692b 173 * Prints an ADB_message, for debugging purposes.
chrigelburri 18:306d362d692b 174 * @param message ADB message to print.
chrigelburri 18:306d362d692b 175 */
chrigelburri 18:306d362d692b 176 #ifdef DEBUG
chrigelburri 18:306d362d692b 177 static void adb_printMessage(adb_message * message)
chrigelburri 18:306d362d692b 178 {
chrigelburri 18:306d362d692b 179 switch(message->command)
chrigelburri 18:306d362d692b 180 {
chrigelburri 18:306d362d692b 181 case A_OKAY:
chrigelburri 18:306d362d692b 182 printf("OKAY message [%lx] %ld %ld\r\n", message->command, message->arg0, message->arg1);
chrigelburri 18:306d362d692b 183 break;
chrigelburri 18:306d362d692b 184 case A_CLSE:
chrigelburri 18:306d362d692b 185 printf("CLSE message [%lx] %ld %ld\r\n", message->command, message->arg0, message->arg1);
chrigelburri 18:306d362d692b 186 break;
chrigelburri 18:306d362d692b 187 case A_WRTE:
chrigelburri 18:306d362d692b 188 printf("WRTE message [%lx] %ld %ld, %ld bytes\r\n", message->command, message->arg0, message->arg1, message->data_length);
chrigelburri 18:306d362d692b 189 break;
chrigelburri 18:306d362d692b 190 case A_CNXN:
chrigelburri 18:306d362d692b 191 printf("CNXN message [%lx] %ld %ld\r\n", message->command, message->arg0, message->arg1);
chrigelburri 18:306d362d692b 192 break;
chrigelburri 18:306d362d692b 193 case A_SYNC:
chrigelburri 18:306d362d692b 194 printf("SYNC message [%lx] %ld %ld\r\n", message->command, message->arg0, message->arg1);
chrigelburri 18:306d362d692b 195 break;
chrigelburri 18:306d362d692b 196 case A_OPEN:
chrigelburri 18:306d362d692b 197 printf("OPEN message [%lx] %ld %ld\r\n", message->command, message->arg0, message->arg1);
chrigelburri 18:306d362d692b 198 break;
chrigelburri 18:306d362d692b 199 default:
chrigelburri 18:306d362d692b 200 printf("WTF message [%lx] %ld %ld\r\n", message->command, message->arg0, message->arg1);
chrigelburri 18:306d362d692b 201 break;
chrigelburri 18:306d362d692b 202 }
chrigelburri 18:306d362d692b 203 }
chrigelburri 18:306d362d692b 204 #endif
chrigelburri 18:306d362d692b 205
chrigelburri 18:306d362d692b 206 /**
chrigelburri 18:306d362d692b 207 * Writes an empty message (without payload) to the ADB device.
chrigelburri 18:306d362d692b 208 *
chrigelburri 18:306d362d692b 209 * @param device USB device handle.
chrigelburri 18:306d362d692b 210 * @param command ADB command.
chrigelburri 18:306d362d692b 211 * @param arg0 first ADB argument (command dependent).
chrigelburri 18:306d362d692b 212 * @param arg0 second ADB argument (command dependent).
chrigelburri 18:306d362d692b 213 * @return error code or 0 for success.
chrigelburri 18:306d362d692b 214 */
chrigelburri 18:306d362d692b 215 int ADB::writeEmptyMessage(int device, uint32_t command, uint32_t arg0, uint32_t arg1)
chrigelburri 18:306d362d692b 216 {
chrigelburri 18:306d362d692b 217 adb_message message;
chrigelburri 18:306d362d692b 218
chrigelburri 18:306d362d692b 219 message.command = command;
chrigelburri 18:306d362d692b 220 message.arg0 = arg0;
chrigelburri 18:306d362d692b 221 message.arg1 = arg1;
chrigelburri 18:306d362d692b 222 message.data_length = 0;
chrigelburri 18:306d362d692b 223 message.data_check = 0;
chrigelburri 18:306d362d692b 224 message.magic = command ^ 0xffffffff;
chrigelburri 18:306d362d692b 225
chrigelburri 18:306d362d692b 226 #ifdef DEBUG
chrigelburri 18:306d362d692b 227 printf("OUT << "); adb_printMessage(&message);
chrigelburri 18:306d362d692b 228 #endif
chrigelburri 18:306d362d692b 229
chrigelburri 18:306d362d692b 230 int r = USBBulkTransfer( device , output_ep , (uint8_t*)&message , sizeof(adb_message) );
chrigelburri 18:306d362d692b 231
chrigelburri 18:306d362d692b 232 #ifdef DEBUG
chrigelburri 18:306d362d692b 233 log("[writeMessage1] size:%d\r\n",r);
chrigelburri 18:306d362d692b 234
chrigelburri 18:306d362d692b 235 int ii,jj;
chrigelburri 18:306d362d692b 236 uint8_t* buf = (uint8_t*)&message;
chrigelburri 18:306d362d692b 237 for(ii = 0 ; ii < r ; ii+=16)
chrigelburri 18:306d362d692b 238 {
chrigelburri 18:306d362d692b 239 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 240 {
chrigelburri 18:306d362d692b 241 log("%02X%02X ",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 242 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 243 }
chrigelburri 18:306d362d692b 244 log(" : ");
chrigelburri 18:306d362d692b 245 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 246 {
chrigelburri 18:306d362d692b 247 log("%c%c",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 248 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 249 }
chrigelburri 18:306d362d692b 250 log("\r\n");
chrigelburri 18:306d362d692b 251 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 252 }
chrigelburri 18:306d362d692b 253 #endif
chrigelburri 18:306d362d692b 254
chrigelburri 18:306d362d692b 255 return r;
chrigelburri 18:306d362d692b 256 }
chrigelburri 18:306d362d692b 257
chrigelburri 18:306d362d692b 258 /**
chrigelburri 18:306d362d692b 259 * Writes an ADB message with payload to the ADB device.
chrigelburri 18:306d362d692b 260 *
chrigelburri 18:306d362d692b 261 * @param device USB device handle.
chrigelburri 18:306d362d692b 262 * @param command ADB command.
chrigelburri 18:306d362d692b 263 * @param arg0 first ADB argument (command dependent).
chrigelburri 18:306d362d692b 264 * @param arg0 second ADB argument (command dependent).
chrigelburri 18:306d362d692b 265 * @param length payload length.
chrigelburri 18:306d362d692b 266 * @param data command payload.
chrigelburri 18:306d362d692b 267 * @return error code or 0 for success.
chrigelburri 18:306d362d692b 268 */
chrigelburri 18:306d362d692b 269 int ADB::writeMessage(int device, uint32_t command, uint32_t arg0, uint32_t arg1, uint32_t length, uint8_t * data)
chrigelburri 18:306d362d692b 270 {
chrigelburri 18:306d362d692b 271 adb_message message;
chrigelburri 18:306d362d692b 272 uint8_t msg[256];
chrigelburri 18:306d362d692b 273 uint32_t count, sum = 0;
chrigelburri 18:306d362d692b 274 uint8_t * x;
chrigelburri 18:306d362d692b 275
chrigelburri 18:306d362d692b 276 // Calculate data checksum
chrigelburri 18:306d362d692b 277 count = length;
chrigelburri 18:306d362d692b 278 x = data;
chrigelburri 18:306d362d692b 279 while(count-- > 0) sum += *x++;
chrigelburri 18:306d362d692b 280
chrigelburri 18:306d362d692b 281 // Fill out the message record.
chrigelburri 18:306d362d692b 282 message.command = command;
chrigelburri 18:306d362d692b 283 message.arg0 = arg0;
chrigelburri 18:306d362d692b 284 message.arg1 = arg1;
chrigelburri 18:306d362d692b 285 message.data_length = length;
chrigelburri 18:306d362d692b 286 message.data_check = (sum);
chrigelburri 18:306d362d692b 287 message.magic = command ^ 0xffffffff;
chrigelburri 18:306d362d692b 288
chrigelburri 18:306d362d692b 289 #ifdef DEBUG
chrigelburri 18:306d362d692b 290 printf("OUT << "); adb_printMessage(&message);
chrigelburri 18:306d362d692b 291 #endif
chrigelburri 18:306d362d692b 292
chrigelburri 18:306d362d692b 293 int r = USBBulkTransfer( device , output_ep , (uint8_t*)&message , sizeof(adb_message) );
chrigelburri 18:306d362d692b 294
chrigelburri 18:306d362d692b 295 if (r<0) return r;
chrigelburri 18:306d362d692b 296
chrigelburri 18:306d362d692b 297 #ifdef DEBUG
chrigelburri 18:306d362d692b 298 log("[writeMessage1] size:%d\r\n",r);
chrigelburri 18:306d362d692b 299
chrigelburri 18:306d362d692b 300 int ii,jj;
chrigelburri 18:306d362d692b 301 uint8_t* buf = (uint8_t*)&message;
chrigelburri 18:306d362d692b 302 for(ii = 0 ; ii < r ; ii+=16)
chrigelburri 18:306d362d692b 303 {
chrigelburri 18:306d362d692b 304 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 305 {
chrigelburri 18:306d362d692b 306 log("%02X%02X ",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 307 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 308 }
chrigelburri 18:306d362d692b 309 log(" : ");
chrigelburri 18:306d362d692b 310 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 311 {
chrigelburri 18:306d362d692b 312 log("%c%c",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 313 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 314 }
chrigelburri 18:306d362d692b 315 log("\r\n");
chrigelburri 18:306d362d692b 316 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 317 }
chrigelburri 18:306d362d692b 318 #endif
chrigelburri 18:306d362d692b 319
chrigelburri 18:306d362d692b 320 memcpy( msg , data , length );
chrigelburri 18:306d362d692b 321
chrigelburri 18:306d362d692b 322 r = USBBulkTransfer( device , output_ep , msg , length );
chrigelburri 18:306d362d692b 323 log("USB SEND RET2:%d\r\n",r);
chrigelburri 18:306d362d692b 324
chrigelburri 18:306d362d692b 325 if (r<0) return r;
chrigelburri 18:306d362d692b 326
chrigelburri 18:306d362d692b 327 #ifdef DEBUG
chrigelburri 18:306d362d692b 328 log("[writeMessage2] size:%d\r\n",r);
chrigelburri 18:306d362d692b 329
chrigelburri 18:306d362d692b 330 buf = msg;
chrigelburri 18:306d362d692b 331 for(ii = 0 ; ii < r ; ii+=16)
chrigelburri 18:306d362d692b 332 {
chrigelburri 18:306d362d692b 333 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 334 {
chrigelburri 18:306d362d692b 335 log("%02X%02X ",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 336 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 337 }
chrigelburri 18:306d362d692b 338 log(" : ");
chrigelburri 18:306d362d692b 339 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 340 {
chrigelburri 18:306d362d692b 341 log("%c%c",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 342 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 343 }
chrigelburri 18:306d362d692b 344 log("\r\n");
chrigelburri 18:306d362d692b 345 if((ii+jj) > r) break;
chrigelburri 18:306d362d692b 346 }
chrigelburri 18:306d362d692b 347 #endif
chrigelburri 18:306d362d692b 348
chrigelburri 18:306d362d692b 349 r = 0;
chrigelburri 18:306d362d692b 350
chrigelburri 18:306d362d692b 351 return r;
chrigelburri 18:306d362d692b 352 }
chrigelburri 18:306d362d692b 353
chrigelburri 18:306d362d692b 354 /**
chrigelburri 18:306d362d692b 355 * Writes an ADB command with a string as payload.
chrigelburri 18:306d362d692b 356 *
chrigelburri 18:306d362d692b 357 * @param device USB device handle.
chrigelburri 18:306d362d692b 358 * @param command ADB command.
chrigelburri 18:306d362d692b 359 * @param arg0 first ADB argument (command dependent).
chrigelburri 18:306d362d692b 360 * @param arg0 second ADB argument (command dependent).
chrigelburri 18:306d362d692b 361 * @param str payload string.
chrigelburri 18:306d362d692b 362 * @return error code or 0 for success.
chrigelburri 18:306d362d692b 363 */
chrigelburri 18:306d362d692b 364 int ADB::writeStringMessage(int device, uint32_t command, uint32_t arg0, uint32_t arg1, char * str)
chrigelburri 18:306d362d692b 365 {
chrigelburri 18:306d362d692b 366 return ADB::writeMessage(device, command, arg0, arg1, strlen(str) + 1, (uint8_t*)str);
chrigelburri 18:306d362d692b 367 }
chrigelburri 18:306d362d692b 368
chrigelburri 18:306d362d692b 369 /**
chrigelburri 18:306d362d692b 370 * Poll an ADB message.
chrigelburri 18:306d362d692b 371 * @param message on success, the ADB message will be returned in this struct.
chrigelburri 18:306d362d692b 372 * @param poll true to poll for a packet on the input endpoint, false to wait for a packet. Use false here when a packet is expected (i.e. OKAY in response to WRTE)
chrigelburri 18:306d362d692b 373 * @return true iff a packet was successfully received, false otherwise.
chrigelburri 18:306d362d692b 374 */
chrigelburri 18:306d362d692b 375 boolean ADB::pollMessage(adb_message * message, boolean poll)
chrigelburri 18:306d362d692b 376 {
chrigelburri 18:306d362d692b 377 int bytesRead = 0;
chrigelburri 18:306d362d692b 378 uint8_t buf[ADB_USB_PACKETSIZE];
chrigelburri 18:306d362d692b 379
chrigelburri 18:306d362d692b 380 // Poll a packet from the USB
chrigelburri 18:306d362d692b 381 bytesRead = recv_packet_buf.GetPacket((char*)buf);
chrigelburri 18:306d362d692b 382
chrigelburri 18:306d362d692b 383 // Check if the USB in transfer was successful.
chrigelburri 18:306d362d692b 384 if (bytesRead<=0) return false;
chrigelburri 18:306d362d692b 385
chrigelburri 18:306d362d692b 386 log("[pollMessage] byteRead size:%d\r\n",bytesRead);
chrigelburri 18:306d362d692b 387
chrigelburri 18:306d362d692b 388 // Check if the buffer contains a valid message
chrigelburri 18:306d362d692b 389 memcpy((void*)message, (void*)buf, sizeof(adb_message));
chrigelburri 18:306d362d692b 390
chrigelburri 18:306d362d692b 391 // If the message is corrupt, return.
chrigelburri 18:306d362d692b 392 #if 1
chrigelburri 18:306d362d692b 393 if (message->magic != (message->command ^ 0xffffffff))
chrigelburri 18:306d362d692b 394 {
chrigelburri 18:306d362d692b 395 #ifdef DEBUG
chrigelburri 18:306d362d692b 396 printf("Broken message, magic mismatch, %d bytes\r\n", bytesRead);
chrigelburri 18:306d362d692b 397 return false;
chrigelburri 18:306d362d692b 398 #endif
chrigelburri 18:306d362d692b 399 }
chrigelburri 18:306d362d692b 400 #endif
chrigelburri 18:306d362d692b 401 // Check if the received number of bytes matches our expected 24 bytes of ADB message header.
chrigelburri 18:306d362d692b 402 if (bytesRead != sizeof(adb_message)) return false;
chrigelburri 18:306d362d692b 403
chrigelburri 18:306d362d692b 404 return true;
chrigelburri 18:306d362d692b 405 }
chrigelburri 18:306d362d692b 406
chrigelburri 18:306d362d692b 407 /**
chrigelburri 18:306d362d692b 408 * Sends an ADB OPEN message for any connections that are currently in the CLOSED state.
chrigelburri 18:306d362d692b 409 */
chrigelburri 18:306d362d692b 410 void ADB::openClosedConnections()
chrigelburri 18:306d362d692b 411 {
chrigelburri 18:306d362d692b 412 uint32_t timeSinceLastConnect;
chrigelburri 18:306d362d692b 413 Connection * connection;
chrigelburri 18:306d362d692b 414
chrigelburri 18:306d362d692b 415 // Iterate over the connection list and send "OPEN" for the ones that are currently closed.
chrigelburri 18:306d362d692b 416 for (connection = firstConnection; connection!=NULL; connection = connection->next)
chrigelburri 18:306d362d692b 417 {
chrigelburri 18:306d362d692b 418 timeSinceLastConnect = millis() - connection->lastConnectionAttempt;
chrigelburri 18:306d362d692b 419 if (connection->status==ADB_CLOSED && timeSinceLastConnect>ADB_CONNECTION_RETRY_TIME)
chrigelburri 18:306d362d692b 420 {
chrigelburri 18:306d362d692b 421 // Issue open command.
chrigelburri 18:306d362d692b 422 ADB::writeStringMessage(_device, A_OPEN, connection->localID, 0, connection->connectionString);
chrigelburri 18:306d362d692b 423
chrigelburri 18:306d362d692b 424 // Record the last attempt time
chrigelburri 18:306d362d692b 425 connection->lastConnectionAttempt = millis();
chrigelburri 18:306d362d692b 426 connection->status = ADB_OPENING;
chrigelburri 18:306d362d692b 427
chrigelburri 18:306d362d692b 428 }
chrigelburri 18:306d362d692b 429 }
chrigelburri 18:306d362d692b 430
chrigelburri 18:306d362d692b 431 }
chrigelburri 18:306d362d692b 432
chrigelburri 18:306d362d692b 433 /**
chrigelburri 18:306d362d692b 434 * Handles and ADB OKAY message, which represents a transition in the connection state machine.
chrigelburri 18:306d362d692b 435 *
chrigelburri 18:306d362d692b 436 * @param connection ADB connection
chrigelburri 18:306d362d692b 437 * @param message ADB message struct.
chrigelburri 18:306d362d692b 438 */
chrigelburri 18:306d362d692b 439 void ADB::handleOkay(Connection * connection, adb_message * message)
chrigelburri 18:306d362d692b 440 {
chrigelburri 18:306d362d692b 441 // Check if the OKAY message was a response to a CONNECT message.
chrigelburri 18:306d362d692b 442 if (connection->status==ADB_OPENING)
chrigelburri 18:306d362d692b 443 {
chrigelburri 18:306d362d692b 444 connection->status = ADB_OPEN;
chrigelburri 18:306d362d692b 445 connection->remoteID = message->arg0;
chrigelburri 18:306d362d692b 446
chrigelburri 18:306d362d692b 447 ADB::fireEvent(connection, ADB_CONNECTION_OPEN, 0, NULL);
chrigelburri 18:306d362d692b 448 }
chrigelburri 18:306d362d692b 449
chrigelburri 18:306d362d692b 450 // Check if the OKAY message was a response to a WRITE message.
chrigelburri 18:306d362d692b 451 if (connection->status == ADB_WRITING)
chrigelburri 18:306d362d692b 452 connection->status = ADB_OPEN;
chrigelburri 18:306d362d692b 453
chrigelburri 18:306d362d692b 454 }
chrigelburri 18:306d362d692b 455
chrigelburri 18:306d362d692b 456 /**
chrigelburri 18:306d362d692b 457 * Handles an ADB CLOSE message, and fires an ADB event accordingly.
chrigelburri 18:306d362d692b 458 *
chrigelburri 18:306d362d692b 459 * @param connection ADB connection
chrigelburri 18:306d362d692b 460 */
chrigelburri 18:306d362d692b 461 void ADB::handleClose(Connection * connection)
chrigelburri 18:306d362d692b 462 {
chrigelburri 18:306d362d692b 463 // Check if the CLOSE message was a response to a CONNECT message.
chrigelburri 18:306d362d692b 464 if (connection->status==ADB_OPENING)
chrigelburri 18:306d362d692b 465 ADB::fireEvent(connection, ADB_CONNECTION_FAILED, 0, NULL);
chrigelburri 18:306d362d692b 466 else
chrigelburri 18:306d362d692b 467 ADB::fireEvent(connection, ADB_CONNECTION_CLOSE, 0, NULL);
chrigelburri 18:306d362d692b 468
chrigelburri 18:306d362d692b 469 // Connection failed
chrigelburri 18:306d362d692b 470 if (connection->reconnect)
chrigelburri 18:306d362d692b 471 connection->status = ADB_CLOSED;
chrigelburri 18:306d362d692b 472 else
chrigelburri 18:306d362d692b 473 connection->status = ADB_UNUSED;
chrigelburri 18:306d362d692b 474
chrigelburri 18:306d362d692b 475 }
chrigelburri 18:306d362d692b 476
chrigelburri 18:306d362d692b 477 /**
chrigelburri 18:306d362d692b 478 * Handles an ADB WRITE message.
chrigelburri 18:306d362d692b 479 *
chrigelburri 18:306d362d692b 480 * @param connection ADB connection
chrigelburri 18:306d362d692b 481 * @param message ADB message struct.
chrigelburri 18:306d362d692b 482 */
chrigelburri 18:306d362d692b 483 void ADB::handleWrite(Connection * connection, adb_message * message)
chrigelburri 18:306d362d692b 484 {
chrigelburri 18:306d362d692b 485 uint32_t bytesLeft = message->data_length;
chrigelburri 18:306d362d692b 486 uint8_t buf[ADB_USB_PACKETSIZE];
chrigelburri 18:306d362d692b 487 ConnectionStatus previousStatus;
chrigelburri 18:306d362d692b 488 int bytesRead;
chrigelburri 18:306d362d692b 489
chrigelburri 18:306d362d692b 490 previousStatus = connection->status;
chrigelburri 18:306d362d692b 491
chrigelburri 18:306d362d692b 492 connection->status = ADB_RECEIVING;
chrigelburri 18:306d362d692b 493 connection->dataRead = 0;
chrigelburri 18:306d362d692b 494 connection->dataSize = message->data_length;
chrigelburri 18:306d362d692b 495
chrigelburri 18:306d362d692b 496 while (bytesLeft>0)
chrigelburri 18:306d362d692b 497 {
chrigelburri 18:306d362d692b 498 int len = bytesLeft < ADB_USB_PACKETSIZE ? bytesLeft : ADB_USB_PACKETSIZE;
chrigelburri 18:306d362d692b 499
chrigelburri 18:306d362d692b 500 // Read payload
chrigelburri 18:306d362d692b 501 bytesRead = recv_packet_buf.GetPacket((char*)buf);
chrigelburri 18:306d362d692b 502
chrigelburri 18:306d362d692b 503
chrigelburri 18:306d362d692b 504 // Poll the USB layer.
chrigelburri 18:306d362d692b 505 USBLoop();
chrigelburri 18:306d362d692b 506
chrigelburri 18:306d362d692b 507 log("[handleWrite] byteRead size:%d\r\n",bytesRead);
chrigelburri 18:306d362d692b 508
chrigelburri 18:306d362d692b 509 // if (len != bytesRead)
chrigelburri 18:306d362d692b 510 // printf("bytes read mismatch: %d expected, %d read, %ld left\r\n", len, bytesRead, bytesLeft);
chrigelburri 18:306d362d692b 511
chrigelburri 18:306d362d692b 512 // Break out of the read loop if there's no data to read :(
chrigelburri 18:306d362d692b 513 if (bytesRead==-1) break;
chrigelburri 18:306d362d692b 514 else if(bytesRead!=0)
chrigelburri 18:306d362d692b 515 {
chrigelburri 18:306d362d692b 516 connection->dataRead += len;
chrigelburri 18:306d362d692b 517 ADB::fireEvent(connection, ADB_CONNECTION_RECEIVE, len, buf);
chrigelburri 18:306d362d692b 518
chrigelburri 18:306d362d692b 519 bytesLeft -= bytesRead;
chrigelburri 18:306d362d692b 520 }
chrigelburri 18:306d362d692b 521 }
chrigelburri 18:306d362d692b 522
chrigelburri 18:306d362d692b 523 // Send OKAY message in reply.
chrigelburri 18:306d362d692b 524 bytesRead = ADB::writeEmptyMessage(_device, A_OKAY, message->arg1, message->arg0);
chrigelburri 18:306d362d692b 525
chrigelburri 18:306d362d692b 526 connection->status = previousStatus;
chrigelburri 18:306d362d692b 527
chrigelburri 18:306d362d692b 528 }
chrigelburri 18:306d362d692b 529
chrigelburri 18:306d362d692b 530 /**
chrigelburri 18:306d362d692b 531 * Close all ADB connections.
chrigelburri 18:306d362d692b 532 *
chrigelburri 18:306d362d692b 533 * @param connection ADB connection
chrigelburri 18:306d362d692b 534 * @param message ADB message struct.
chrigelburri 18:306d362d692b 535 */
chrigelburri 18:306d362d692b 536 void ADB::closeAll()
chrigelburri 18:306d362d692b 537 {
chrigelburri 18:306d362d692b 538 Connection * connection;
chrigelburri 18:306d362d692b 539
chrigelburri 18:306d362d692b 540 // Iterate over all connections and close the ones that are currently open.
chrigelburri 18:306d362d692b 541 for (connection = firstConnection; connection != NULL; connection = connection->next)
chrigelburri 18:306d362d692b 542 if (!(connection->status==ADB_UNUSED || connection->status==ADB_CLOSED))
chrigelburri 18:306d362d692b 543 ADB::handleClose(connection);
chrigelburri 18:306d362d692b 544
chrigelburri 18:306d362d692b 545 }
chrigelburri 18:306d362d692b 546
chrigelburri 18:306d362d692b 547 /**
chrigelburri 18:306d362d692b 548 * Handles an ADB connect message. This is a response to a connect message sent from our side.
chrigelburri 18:306d362d692b 549 * @param message ADB message.
chrigelburri 18:306d362d692b 550 */
chrigelburri 18:306d362d692b 551 void ADB::handleConnect(adb_message * message)
chrigelburri 18:306d362d692b 552 {
chrigelburri 18:306d362d692b 553 unsigned int bytesRead;
chrigelburri 18:306d362d692b 554 uint8_t buf[MAX_BUF_SIZE];
chrigelburri 18:306d362d692b 555 uint16_t len;
chrigelburri 18:306d362d692b 556
chrigelburri 18:306d362d692b 557 // Read payload (remote ADB device ID)
chrigelburri 18:306d362d692b 558 len = message->data_length < MAX_BUF_SIZE ? message->data_length : MAX_BUF_SIZE;
chrigelburri 18:306d362d692b 559 bytesRead = recv_packet_buf.GetPacket((char*)buf);
chrigelburri 18:306d362d692b 560
chrigelburri 18:306d362d692b 561 log("[handleConnect] byteRead size:%d\r\n",bytesRead);
chrigelburri 18:306d362d692b 562
chrigelburri 18:306d362d692b 563 // Signal that we are now connected to an Android device (yay!)
chrigelburri 18:306d362d692b 564 connected = true;
chrigelburri 18:306d362d692b 565
chrigelburri 18:306d362d692b 566 // Fire event.
chrigelburri 18:306d362d692b 567 ADB::fireEvent(NULL, ADB_CONNECT, len, buf);
chrigelburri 18:306d362d692b 568
chrigelburri 18:306d362d692b 569 }
chrigelburri 18:306d362d692b 570
chrigelburri 18:306d362d692b 571 /**
chrigelburri 18:306d362d692b 572 * This method is called periodically to check for new messages on the USB bus and process them.
chrigelburri 18:306d362d692b 573 */
chrigelburri 18:306d362d692b 574 void ADB::poll()
chrigelburri 18:306d362d692b 575 {
chrigelburri 18:306d362d692b 576 Connection * connection;
chrigelburri 18:306d362d692b 577 adb_message message;
chrigelburri 18:306d362d692b 578
chrigelburri 18:306d362d692b 579 // Poll the USB layer.
chrigelburri 18:306d362d692b 580 USBLoop();
chrigelburri 18:306d362d692b 581
chrigelburri 18:306d362d692b 582 // If no USB device, there's no work for us to be done, so just return.
chrigelburri 18:306d362d692b 583 if (_device==0) return;
chrigelburri 18:306d362d692b 584
chrigelburri 18:306d362d692b 585 // If not connected, send a connection string to the device.
chrigelburri 18:306d362d692b 586 if (!connected)
chrigelburri 18:306d362d692b 587 {
chrigelburri 18:306d362d692b 588 ADB::writeStringMessage(_device, A_CNXN, 0x01000000, 4096, (char*)"host::microbridge");
chrigelburri 18:306d362d692b 589 for(int ii=0;ii<400;ii++)
chrigelburri 18:306d362d692b 590 {
chrigelburri 18:306d362d692b 591 USBLoop();
chrigelburri 18:306d362d692b 592 wait_ms(1);
chrigelburri 18:306d362d692b 593 }
chrigelburri 18:306d362d692b 594 //wait_ms(500); // Give the device some time to respond.
chrigelburri 18:306d362d692b 595 }
chrigelburri 18:306d362d692b 596
chrigelburri 18:306d362d692b 597 // If we are connected, check if there are connections that need to be opened
chrigelburri 18:306d362d692b 598 if (connected)
chrigelburri 18:306d362d692b 599 ADB::openClosedConnections();
chrigelburri 18:306d362d692b 600
chrigelburri 18:306d362d692b 601 // Check for an incoming ADB message.
chrigelburri 18:306d362d692b 602 if (!ADB::pollMessage(&message, true))
chrigelburri 18:306d362d692b 603 return;
chrigelburri 18:306d362d692b 604
chrigelburri 18:306d362d692b 605 // Handle a response from the ADB device to our CONNECT message.
chrigelburri 18:306d362d692b 606 if (message.command == A_CNXN)
chrigelburri 18:306d362d692b 607 ADB::handleConnect(&message);
chrigelburri 18:306d362d692b 608
chrigelburri 18:306d362d692b 609 // Handle messages for specific connections
chrigelburri 18:306d362d692b 610 for (connection = firstConnection; connection != NULL; connection = connection->next)
chrigelburri 18:306d362d692b 611 {
chrigelburri 18:306d362d692b 612 if(connection->status!=ADB_UNUSED && connection->localID==message.arg1)
chrigelburri 18:306d362d692b 613 {
chrigelburri 18:306d362d692b 614 switch(message.command)
chrigelburri 18:306d362d692b 615 {
chrigelburri 18:306d362d692b 616 case A_OKAY:
chrigelburri 18:306d362d692b 617 //printf("HANDLE OKEY\r\n");
chrigelburri 18:306d362d692b 618 ADB::handleOkay(connection, &message);
chrigelburri 18:306d362d692b 619 break;
chrigelburri 18:306d362d692b 620 case A_CLSE:
chrigelburri 18:306d362d692b 621 printf("HANDLE CLOSE\r\n");
chrigelburri 18:306d362d692b 622 ADB::handleClose(connection);
chrigelburri 18:306d362d692b 623 break;
chrigelburri 18:306d362d692b 624 case A_WRTE:
chrigelburri 18:306d362d692b 625 //printf("HANDLE WRITE\r\n");
chrigelburri 18:306d362d692b 626 ADB::handleWrite(connection, &message);
chrigelburri 18:306d362d692b 627 break;
chrigelburri 18:306d362d692b 628 default:
chrigelburri 18:306d362d692b 629 break;
chrigelburri 18:306d362d692b 630 }
chrigelburri 18:306d362d692b 631 }
chrigelburri 18:306d362d692b 632 }
chrigelburri 18:306d362d692b 633
chrigelburri 18:306d362d692b 634 }
chrigelburri 18:306d362d692b 635
chrigelburri 18:306d362d692b 636 void ADB::AdbreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
chrigelburri 18:306d362d692b 637
chrigelburri 18:306d362d692b 638 recv_packet_buf.PutPacket((char*)buf,len);
chrigelburri 18:306d362d692b 639
chrigelburri 18:306d362d692b 640 #ifdef DEBUG
chrigelburri 18:306d362d692b 641 log("[AdbreadCallback] size:%d\r\n",len);
chrigelburri 18:306d362d692b 642
chrigelburri 18:306d362d692b 643 int ii,jj;
chrigelburri 18:306d362d692b 644 for(ii = 0 ; ii < len ; ii+=16)
chrigelburri 18:306d362d692b 645 {
chrigelburri 18:306d362d692b 646 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 647 {
chrigelburri 18:306d362d692b 648 log("%02X%02X ",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 649 if((ii+jj) > len) break;
chrigelburri 18:306d362d692b 650 }
chrigelburri 18:306d362d692b 651 log(" : ");
chrigelburri 18:306d362d692b 652 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 653 {
chrigelburri 18:306d362d692b 654 log("%c%c",buf[ii+jj],buf[ii+jj+1]);
chrigelburri 18:306d362d692b 655 if((ii+jj) > len) break;
chrigelburri 18:306d362d692b 656 }
chrigelburri 18:306d362d692b 657 log("\r\n");
chrigelburri 18:306d362d692b 658 if((ii+jj) > len) break;
chrigelburri 18:306d362d692b 659 }
chrigelburri 18:306d362d692b 660 #endif
chrigelburri 18:306d362d692b 661 USBBulkTransfer(device, endpoint ,readbuff,sizeof(readbuff), AdbreadCallback, userData);
chrigelburri 18:306d362d692b 662 // wait_ms(4);
chrigelburri 18:306d362d692b 663 }
chrigelburri 18:306d362d692b 664
chrigelburri 18:306d362d692b 665 /**
chrigelburri 18:306d362d692b 666 * Checks whether the a connected USB device is an ADB device and populates a configuration record if it is.
chrigelburri 18:306d362d692b 667 *
chrigelburri 18:306d362d692b 668 * @param device USB device.
chrigelburri 18:306d362d692b 669 * @param handle pointer to a configuration record. The endpoint device address, configuration, and endpoint information will be stored here.
chrigelburri 18:306d362d692b 670 * @return true iff the device is an ADB device.
chrigelburri 18:306d362d692b 671 */
chrigelburri 18:306d362d692b 672 boolean ADB::isAdbDevice(int device, int configuration, int interfaceNumber)
chrigelburri 18:306d362d692b 673 {
chrigelburri 18:306d362d692b 674 boolean ret = false;
chrigelburri 18:306d362d692b 675
chrigelburri 18:306d362d692b 676 log("connecting Android \r\n");
chrigelburri 18:306d362d692b 677
chrigelburri 18:306d362d692b 678 _device = device;
chrigelburri 18:306d362d692b 679 _configuration = configuration;
chrigelburri 18:306d362d692b 680 _interfaceNumber = interfaceNumber;
chrigelburri 18:306d362d692b 681
chrigelburri 18:306d362d692b 682 log("device = %d configuration = %d interfaceNumber = %d\r\n", device, configuration, interfaceNumber);
chrigelburri 18:306d362d692b 683
chrigelburri 18:306d362d692b 684 int err;
chrigelburri 18:306d362d692b 685
chrigelburri 18:306d362d692b 686 u8 buffer[255];
chrigelburri 18:306d362d692b 687 err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,4);
chrigelburri 18:306d362d692b 688
chrigelburri 18:306d362d692b 689 if (err < 0) {
chrigelburri 18:306d362d692b 690 log("Failed to get descriptor\r\n");
chrigelburri 18:306d362d692b 691 return(ret);
chrigelburri 18:306d362d692b 692 }
chrigelburri 18:306d362d692b 693
chrigelburri 18:306d362d692b 694 int len = buffer[2] | (buffer[3] << 8);
chrigelburri 18:306d362d692b 695 if (len > sizeof(buffer)) {
chrigelburri 18:306d362d692b 696 log("config descriptor too large\r\n");
chrigelburri 18:306d362d692b 697 /* might want to truncate here */
chrigelburri 18:306d362d692b 698 return(ret);
chrigelburri 18:306d362d692b 699 }
chrigelburri 18:306d362d692b 700 err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,len);
chrigelburri 18:306d362d692b 701 u8* p = buffer;
chrigelburri 18:306d362d692b 702 input_ep=0;
chrigelburri 18:306d362d692b 703 output_ep=0;
chrigelburri 18:306d362d692b 704 EndpointDescriptor *epDesc;
chrigelburri 18:306d362d692b 705
chrigelburri 18:306d362d692b 706 log("Descriptor size:%d\r\n",len);
chrigelburri 18:306d362d692b 707 int ii,jj;
chrigelburri 18:306d362d692b 708 for(ii = 0 ; ii < len ; ii+=16)
chrigelburri 18:306d362d692b 709 {
chrigelburri 18:306d362d692b 710 for(jj = 0 ; jj < 16 ; jj+=2 )
chrigelburri 18:306d362d692b 711 {
chrigelburri 18:306d362d692b 712 log("%02X%02X ",buffer[ii+jj],buffer[ii+jj+1]);
chrigelburri 18:306d362d692b 713 if((ii+jj) > len) break;
chrigelburri 18:306d362d692b 714 }
chrigelburri 18:306d362d692b 715 log("\r\n");
chrigelburri 18:306d362d692b 716 if((ii+jj) > len) break;
chrigelburri 18:306d362d692b 717 }
chrigelburri 18:306d362d692b 718 u8 interface_num = 0;
chrigelburri 18:306d362d692b 719
chrigelburri 18:306d362d692b 720 while (p<(buffer+len)) {
chrigelburri 18:306d362d692b 721 u8 descLen = p[0];
chrigelburri 18:306d362d692b 722 u8 descType = p[1];
chrigelburri 18:306d362d692b 723 log("descLen=%d,descType=%d\r\n",descLen,descType);
chrigelburri 18:306d362d692b 724 switch (descType) {
chrigelburri 18:306d362d692b 725 case DESCRIPTOR_TYPE_CONFIGURATION:
chrigelburri 18:306d362d692b 726 log("config desc\r\n");
chrigelburri 18:306d362d692b 727 break;
chrigelburri 18:306d362d692b 728 case DESCRIPTOR_TYPE_INTERFACE:
chrigelburri 18:306d362d692b 729 interface_num = p[2];
chrigelburri 18:306d362d692b 730 log("interface desc num[%d]\r\n",interface_num);
chrigelburri 18:306d362d692b 731 break;
chrigelburri 18:306d362d692b 732 case DESCRIPTOR_TYPE_ENDPOINT:
chrigelburri 18:306d362d692b 733 epDesc=(EndpointDescriptor*)p;
chrigelburri 18:306d362d692b 734 if( interface_num == 1 )
chrigelburri 18:306d362d692b 735 {
chrigelburri 18:306d362d692b 736 if (!input_ep && (epDesc->bEndpointAddress& 0x80)) {
chrigelburri 18:306d362d692b 737 input_ep=epDesc->bEndpointAddress& 0x7f;
chrigelburri 18:306d362d692b 738 //PacketSize drop
chrigelburri 18:306d362d692b 739 log("input Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
chrigelburri 18:306d362d692b 740
chrigelburri 18:306d362d692b 741 } else if (!output_ep) {
chrigelburri 18:306d362d692b 742 output_ep=epDesc->bEndpointAddress& 0x7f;
chrigelburri 18:306d362d692b 743 //PacketSize drop
chrigelburri 18:306d362d692b 744 log("output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",output_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
chrigelburri 18:306d362d692b 745 } else {
chrigelburri 18:306d362d692b 746 //other
chrigelburri 18:306d362d692b 747 log("non input,output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
chrigelburri 18:306d362d692b 748 }
chrigelburri 18:306d362d692b 749 }
chrigelburri 18:306d362d692b 750 break;
chrigelburri 18:306d362d692b 751 default:
chrigelburri 18:306d362d692b 752 log("unkown desc type(%d) \r\n",descType);
chrigelburri 18:306d362d692b 753 }
chrigelburri 18:306d362d692b 754 p+=descLen;
chrigelburri 18:306d362d692b 755 }
chrigelburri 18:306d362d692b 756
chrigelburri 18:306d362d692b 757 if (!(input_ep && output_ep)) {
chrigelburri 18:306d362d692b 758 log("can't find accessory endpoints\r\n");
chrigelburri 18:306d362d692b 759 return(false);
chrigelburri 18:306d362d692b 760 }
chrigelburri 18:306d362d692b 761
chrigelburri 18:306d362d692b 762 log("SetConfiguration\r\n");
chrigelburri 18:306d362d692b 763 err = SetConfiguration(device,configuration);
chrigelburri 18:306d362d692b 764 if (err < 0) {
chrigelburri 18:306d362d692b 765 log("SetConfiguration error\r\n");
chrigelburri 18:306d362d692b 766 return(false);
chrigelburri 18:306d362d692b 767 }
chrigelburri 18:306d362d692b 768
chrigelburri 18:306d362d692b 769 log("interrupt setup\r\n");
chrigelburri 18:306d362d692b 770 //interrupt setup
chrigelburri 18:306d362d692b 771 if (IO_PENDING!=USBBulkTransfer(_device,input_ep|0x80,readbuff,sizeof(readbuff),AdbreadCallback,NULL)) return(ret);
chrigelburri 18:306d362d692b 772
chrigelburri 18:306d362d692b 773 log("ADB Standby\r\n");
chrigelburri 18:306d362d692b 774 ret = true;
chrigelburri 18:306d362d692b 775
chrigelburri 18:306d362d692b 776 return(ret);
chrigelburri 18:306d362d692b 777 }
chrigelburri 18:306d362d692b 778
chrigelburri 18:306d362d692b 779
chrigelburri 18:306d362d692b 780 void desconnect(void)
chrigelburri 18:306d362d692b 781 {
chrigelburri 18:306d362d692b 782 ADB::closeAll();
chrigelburri 18:306d362d692b 783 _device = 0;
chrigelburri 18:306d362d692b 784 connected = false;
chrigelburri 18:306d362d692b 785 }
chrigelburri 18:306d362d692b 786
chrigelburri 18:306d362d692b 787 /**
chrigelburri 18:306d362d692b 788 * Write a set of bytes to an open ADB connection.
chrigelburri 18:306d362d692b 789 *
chrigelburri 18:306d362d692b 790 * @param connection ADB connection to write the data to.
chrigelburri 18:306d362d692b 791 * @param length number of bytes to transmit.
chrigelburri 18:306d362d692b 792 * @param data data to send.
chrigelburri 18:306d362d692b 793 * @return number of transmitted bytes, or -1 on failure.
chrigelburri 18:306d362d692b 794 */
chrigelburri 18:306d362d692b 795 int ADB::write(Connection * connection, uint16_t length, uint8_t * data)
chrigelburri 18:306d362d692b 796 {
chrigelburri 18:306d362d692b 797 int ret;
chrigelburri 18:306d362d692b 798
chrigelburri 18:306d362d692b 799 // First check if we have a working ADB connection
chrigelburri 18:306d362d692b 800 if (_device==0 || !connected) return -1;
chrigelburri 18:306d362d692b 801
chrigelburri 18:306d362d692b 802 // Check if the connection is open for writing.
chrigelburri 18:306d362d692b 803 if (connection->status != ADB_OPEN) return -2;
chrigelburri 18:306d362d692b 804
chrigelburri 18:306d362d692b 805 // Write payload
chrigelburri 18:306d362d692b 806 ret = ADB::writeMessage(_device, A_WRTE, connection->localID, connection->remoteID, length, data);
chrigelburri 18:306d362d692b 807 if (ret==0)
chrigelburri 18:306d362d692b 808 connection->status = ADB_WRITING;
chrigelburri 18:306d362d692b 809
chrigelburri 18:306d362d692b 810 return ret;
chrigelburri 18:306d362d692b 811 }
chrigelburri 18:306d362d692b 812
chrigelburri 18:306d362d692b 813 /**
chrigelburri 18:306d362d692b 814 * Write a string to an open ADB connection. The trailing zero is not transmitted.
chrigelburri 18:306d362d692b 815 *
chrigelburri 18:306d362d692b 816 * @param connection ADB connection to write the data to.
chrigelburri 18:306d362d692b 817 * @param length number of bytes to transmit.
chrigelburri 18:306d362d692b 818 * @param data data to send.
chrigelburri 18:306d362d692b 819 * @return number of transmitted bytes, or -1 on failure.
chrigelburri 18:306d362d692b 820 */
chrigelburri 18:306d362d692b 821 int ADB::writeString(Connection * connection, char * str)
chrigelburri 18:306d362d692b 822 {
chrigelburri 18:306d362d692b 823 int ret;
chrigelburri 18:306d362d692b 824
chrigelburri 18:306d362d692b 825 // First check if we have a working ADB connection
chrigelburri 18:306d362d692b 826 if (_device==0 || !connected) return -1;
chrigelburri 18:306d362d692b 827
chrigelburri 18:306d362d692b 828 // Check if the connection is open for writing.
chrigelburri 18:306d362d692b 829 if (connection->status != ADB_OPEN) return -2;
chrigelburri 18:306d362d692b 830
chrigelburri 18:306d362d692b 831 // Write payload
chrigelburri 18:306d362d692b 832 ret = ADB::writeStringMessage(_device, A_WRTE, connection->localID, connection->remoteID, str);
chrigelburri 18:306d362d692b 833 if (ret==0)
chrigelburri 18:306d362d692b 834 connection->status = ADB_WRITING;
chrigelburri 18:306d362d692b 835
chrigelburri 18:306d362d692b 836 return ret;
chrigelburri 18:306d362d692b 837 }
chrigelburri 18:306d362d692b 838
chrigelburri 18:306d362d692b 839 /**
chrigelburri 18:306d362d692b 840 * Write a set of bytes to this ADB connection.
chrigelburri 18:306d362d692b 841 *
chrigelburri 18:306d362d692b 842 * @param length number of bytes to transmit.
chrigelburri 18:306d362d692b 843 * @param data data to send.
chrigelburri 18:306d362d692b 844 * @return number of transmitted bytes, or -1 on failure.
chrigelburri 18:306d362d692b 845 */
chrigelburri 18:306d362d692b 846 int Connection::write(uint16_t length, uint8_t * data)
chrigelburri 18:306d362d692b 847 {
chrigelburri 18:306d362d692b 848 return ADB::write(this, length, data);
chrigelburri 18:306d362d692b 849 }
chrigelburri 18:306d362d692b 850
chrigelburri 18:306d362d692b 851 /**
chrigelburri 18:306d362d692b 852 * Write a string to this connection.
chrigelburri 18:306d362d692b 853 *
chrigelburri 18:306d362d692b 854 * @param length number of bytes to transmit.
chrigelburri 18:306d362d692b 855 * @param data data to send.
chrigelburri 18:306d362d692b 856 * @return number of transmitted bytes, or -1 on failure.
chrigelburri 18:306d362d692b 857 */
chrigelburri 18:306d362d692b 858 int Connection::writeString(char * str)
chrigelburri 18:306d362d692b 859 {
chrigelburri 18:306d362d692b 860 return ADB::writeString(this, str);
chrigelburri 18:306d362d692b 861 }
chrigelburri 18:306d362d692b 862
chrigelburri 18:306d362d692b 863 /**
chrigelburri 18:306d362d692b 864 * Checks if the connection is open for writing.
chrigelburri 18:306d362d692b 865 * @return true iff the connection is open and ready to accept write commands.
chrigelburri 18:306d362d692b 866 */
chrigelburri 18:306d362d692b 867 bool Connection::isOpen()
chrigelburri 18:306d362d692b 868 {
chrigelburri 18:306d362d692b 869 return this->status == ADB_OPEN;
chrigelburri 18:306d362d692b 870 }
chrigelburri 18:306d362d692b 871
chrigelburri 18:306d362d692b 872
chrigelburri 18:306d362d692b 873 /** from USBHost load function. initialize Android device**/
chrigelburri 18:306d362d692b 874 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
chrigelburri 18:306d362d692b 875 char s[128];
chrigelburri 18:306d362d692b 876
chrigelburri 18:306d362d692b 877 log("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
chrigelburri 18:306d362d692b 878
chrigelburri 18:306d362d692b 879 for (int i = 1; i < 4; i++) {
chrigelburri 18:306d362d692b 880 if (GetString(device,i,s,sizeof(s)) < 0)
chrigelburri 18:306d362d692b 881 break;
chrigelburri 18:306d362d692b 882 printf("%d: %s\r\n",i,s);
chrigelburri 18:306d362d692b 883 }
chrigelburri 18:306d362d692b 884
chrigelburri 18:306d362d692b 885 // Adb?
chrigelburri 18:306d362d692b 886 if(1)
chrigelburri 18:306d362d692b 887 {
chrigelburri 18:306d362d692b 888 ADB::isAdbDevice(device,1,2);
chrigelburri 18:306d362d692b 889 }
chrigelburri 18:306d362d692b 890
chrigelburri 18:306d362d692b 891 }