static void *output_thread(void *_t) { atransport *t = reinterpret_cast<atransport*>(_t); apacket *p; ADB_LOGD(ADB_TSPT, "%s: starting transport output thread on fd %d, SYNC online (%d)", t->serial, t->fd, t->sync_token + 1); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 1; p->msg.arg1 = ++(t->sync_token); p->msg.magic = A_SYNC ^ 0xffffffff; if (write_packet(t->fd, t->serial, &p)) { put_apacket(p); ADB_LOGE(ADB_TSPT, "%s: failed to write SYNC packet", t->serial); goto oops; } ADB_LOGD(ADB_TSPT, "%s: data pump started", t->serial); for (;;) { p = get_apacket(); if (t->read_from_remote(p, t) == 0) { ADB_LOGD(ADB_TSPT, "%s: received remote packet, sending to transport", t->serial); if (write_packet(t->fd, t->serial, &p)) { put_apacket(p); ADB_LOGE(ADB_TSPT, "%s: failed to write apacket to transport", t->serial); goto oops; } } else { ADB_LOGE(ADB_TSPT, "%s: remote read failed for transport", t->serial); put_apacket(p); break; } } ADB_LOGD(ADB_TSPT, "%s: SYNC offline for transport", t->serial); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 0; p->msg.arg1 = 0; p->msg.magic = A_SYNC ^ 0xffffffff; if (write_packet(t->fd, t->serial, &p)) { put_apacket(p); ADB_LOGW(ADB_TSPT, "%s: failed to write SYNC apacket to transport", t->serial); } oops: ADB_LOGD(ADB_TSPT, "%s: transport output thread is exiting", t->serial); kick_transport(t); transport_unref(t); return 0; }
// The transport is opened by transport_register_func before // the read_transport and write_transport threads are started. // // The read_transport thread issues a SYNC(1, token) message to let // the write_transport thread know to start things up. In the event // of transport IO failure, the read_transport thread will post a // SYNC(0,0) message to ensure shutdown. // // The transport will not actually be closed until both threads exit, but the threads // will kick the transport on their way out to disconnect the underlying device. // // read_transport thread reads data from a transport (representing a usb/tcp connection), // and makes the main thread call handle_packet(). static void *read_transport_thread(void *_t) { atransport *t = reinterpret_cast<atransport*>(_t); apacket *p; adb_thread_setname(android::base::StringPrintf("<-%s", (t->serial != nullptr ? t->serial : "transport"))); D("%s: starting read_transport thread on fd %d, SYNC online (%d)", t->serial, t->fd, t->sync_token + 1); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 1; p->msg.arg1 = ++(t->sync_token); p->msg.magic = A_SYNC ^ 0xffffffff; if(write_packet(t->fd, t->serial, &p)) { put_apacket(p); D("%s: failed to write SYNC packet", t->serial); goto oops; } D("%s: data pump started", t->serial); for(;;) { p = get_apacket(); if(t->read_from_remote(p, t) == 0){ D("%s: received remote packet, sending to transport", t->serial); if(write_packet(t->fd, t->serial, &p)){ put_apacket(p); D("%s: failed to write apacket to transport", t->serial); goto oops; } } else { D("%s: remote read failed for transport", t->serial); put_apacket(p); break; } } D("%s: SYNC offline for transport", t->serial); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 0; p->msg.arg1 = 0; p->msg.magic = A_SYNC ^ 0xffffffff; if(write_packet(t->fd, t->serial, &p)) { put_apacket(p); D("%s: failed to write SYNC apacket to transport", t->serial); } oops: D("%s: read_transport thread is exiting", t->serial); kick_transport(t); transport_unref(t); return 0; }
static void *output_thread(void *_t) { atransport *t = _t; apacket *p; D("from_remote: starting thread for transport %p, on fd %d\n", t, t->fd ); D("from_remote: transport %p SYNC online (%d)\n", t, t->sync_token + 1); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 1; p->msg.arg1 = ++(t->sync_token); p->msg.magic = A_SYNC ^ 0xffffffff; if(write_packet(t->fd, &p)) { put_apacket(p); D("from_remote: failed to write SYNC apacket to transport %p", t); goto oops; } D("from_remote: data pump for transport %p\n", t); for(;;) { p = get_apacket(); if(t->read_from_remote(p, t) == 0){ D("from_remote: received remote packet, sending to transport %p\n", t); if(write_packet(t->fd, &p)){ put_apacket(p); D("from_remote: failed to write apacket to transport %p", t); goto oops; } } else { D("from_remote: remote read failed for transport %p\n", p); put_apacket(p); break; } } D("from_remote: SYNC offline for transport %p\n", t); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 0; p->msg.arg1 = 0; p->msg.magic = A_SYNC ^ 0xffffffff; if(write_packet(t->fd, &p)) { put_apacket(p); D("from_remote: failed to write SYNC apacket to transport %p", t); } oops: D("from_remote: thread is exiting for transport %p\n", t); kick_transport(t); transport_unref(t); return 0; }
/* The transport is opened by transport_register_func before ** the input and output threads are started. ** ** The output thread issues a SYNC(1, token) message to let ** the input thread know to start things up. In the event ** of transport IO failure, the output thread will post a ** SYNC(0,0) message to ensure shutdown. ** ** The transport will not actually be closed until both ** threads exit, but the input thread will kick the transport ** on its way out to disconnect the underlying device. */ void *output_thread(void *_t, struct dll_io_bridge * _io_bridge) { o_bridge = _io_bridge; atransport *t = (atransport *)_t; apacket *p; D("%s: starting transport output thread on fd %d, SYNC online (%d)\n", t->serial, t->fd, t->sync_token + 1); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 1; p->msg.arg1 = ++(t->sync_token); p->msg.magic = A_SYNC ^ 0xffffffff; if(write_packet(t->fd, t->serial, &p)) { put_apacket(p); D("%s: failed to write SYNC packet\n", t->serial); goto oops; } D("%s: data pump started\n", t->serial); for(;;) { p = get_apacket(); if(t->read_from_remote(p, t) == 0){ D("%s: received remote packet, sending to transport\n", t->serial); if(write_packet(t->fd, t->serial, &p)){ put_apacket(p); D("%s: failed to write apacket to transport\n", t->serial); goto oops; } } else { D("%s: remote read failed for transport\n", t->serial); put_apacket(p); break; } } handle_output_offline(t); oops: #ifdef WIN32 handle_output_oops(t, o_bridge->AdbCloseHandle); #else handle_output_oops(t, NULL); #endif return NULL; }
static void remote_socket_ready(asocket* s) { D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd); apacket* p = get_apacket(); p->msg.command = A_OKAY; p->msg.arg0 = s->peer->id; p->msg.arg1 = s->id; send_packet(p, s->transport); }
static int device_tracker_send(device_tracker* tracker, const std::string& string) { apacket* p = get_apacket(); asocket* peer = tracker->socket.peer; snprintf(reinterpret_cast<char*>(p->data), 5, "%04x", static_cast<int>(string.size())); memcpy(&p->data[4], string.data(), string.size()); p->len = 4 + string.size(); return peer->enqueue(peer, p); }
static void send_ready(unsigned local, unsigned remote, atransport *t) { D("Calling send_ready"); apacket *p = get_apacket(); p->msg.command = A_OKAY; p->msg.arg0 = local; p->msg.arg1 = remote; send_packet(p, t); }
static void send_close(unsigned local, unsigned remote, atransport *t) { D("Calling send_close \n"); apacket *p = get_apacket(); p->msg.command = A_CLSE; p->msg.arg0 = local; p->msg.arg1 = remote; send_packet(p, t); }
void send_close(atransport *t) { apacket *p = get_apacket(); p->msg.command = A_CLSE; p->msg.arg0 = id; p->msg.arg1 = remote_id; p->msg.data_length = 0; send_packet(p, t); }
void send_ready(atransport *t) { apacket *p = get_apacket(); p->msg.command = A_OKAY; p->msg.arg0 = id; p->msg.arg1 = remote_id; p->msg.data_length = 0; send_packet(p, t); }
void send_connect(atransport *t) { D("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = A_VERSION; cp->msg.arg1 = MAX_PAYLOAD; cp->msg.data_length = fill_connect_data((char *)cp->data, sizeof(cp->data)); send_packet(cp, t); }
static void remote_socket_shutdown(asocket* s) { D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd, s->peer ? s->peer->fd : -1); apacket* p = get_apacket(); p->msg.command = A_CLSE; if (s->peer) { p->msg.arg0 = s->peer->id; } p->msg.arg1 = s->id; send_packet(p, s->transport); }
void send_connect(atransport *t) { D("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = t->get_protocol_version(); cp->msg.arg1 = t->get_max_payload(); cp->msg.data_length = fill_connect_data((char *)cp->data, MAX_PAYLOAD_V1); send_packet(cp, t); }
static void jdwp_tracker_ready( asocket* s ) { JdwpTracker* t = (JdwpTracker*) s; if (t->need_update) { apacket* p = get_apacket(); t->need_update = 0; p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data)); s->peer->enqueue(s->peer, p); } }
static int device_tracker_send( device_tracker* tracker, const char* buffer, int len ) { apacket* p = get_apacket(); asocket* peer = tracker->socket.peer; memcpy(p->data, buffer, len); p->len = len; return peer->enqueue( peer, p ); }
static void send_connect(atransport *t) { D("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = A_VERSION; cp->msg.arg1 = MAX_PAYLOAD; snprintf((char*) cp->data, sizeof cp->data, "%s::", HOST ? "host" : adb_device_banner); cp->msg.data_length = strlen((char*) cp->data) + 1; send_packet(cp, t); }
void send_open(atransport *t, const char* msg) { apacket *p = get_apacket(); p->msg.command = A_OPEN; p->msg.arg0 = ++seed; p->msg.arg1 = 0; snprintf((char*)p->data, sizeof p->data, "%s", msg); p->msg.data_length = strlen((char*)p->data); send_packet(p, t); id = -1; remote_id = -1; }
// adb.c void send_connect(atransport *t) { D("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = A_VERSION; cp->msg.arg1 = MAX_PAYLOAD; snprintf((char*) cp->data, sizeof cp->data, "host::zadb"); cp->msg.data_length = strlen((char*) cp->data) + 1; send_packet(cp, t); /* XXX why sleep here? */ // allow the device some time to respond to the connect message adb_sleep_ms(1000); }
static void handle_output_offline(atransport * t) { apacket *p; D("%s: SYNC offline for transport\n", t->serial); p = get_apacket(); p->msg.command = A_SYNC; p->msg.arg0 = 0; p->msg.arg1 = 0; p->msg.magic = A_SYNC ^ 0xffffffff; if(write_packet(t->fd, t->serial, &p)) { put_apacket(p); D("%s: failed to write SYNC apacket to transport", t->serial); } }
void send_write(atransport *t, const char* msg) { if (remote_id==-1) { return; } apacket *p = get_apacket(); p->msg.command = A_WRTE; p->msg.arg0 = 0; p->msg.arg1 = remote_id; snprintf((char*)p->data, sizeof p->data, "%s", msg); p->msg.data_length = strlen((char*)p->data); send_packet(p, t); }
void send_auth_request(atransport* t) { LOG(INFO) << "Calling send_auth_request..."; if (!adbd_auth_generate_token(t->token, sizeof(t->token))) { PLOG(ERROR) << "Error generating token"; return; } apacket* p = get_apacket(); p->msg.command = A_AUTH; p->msg.arg0 = ADB_AUTH_TOKEN; p->msg.data_length = sizeof(t->token); p->payload.assign(t->token, t->token + sizeof(t->token)); send_packet(p, t); }
void connect_to_remote(asocket* s, const char* destination) { D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd); apacket* p = get_apacket(); size_t len = strlen(destination) + 1; if (len > (s->get_max_payload() - 1)) { fatal("destination oversized"); } D("LS(%d): connect('%s')", s->id, destination); p->msg.command = A_OPEN; p->msg.arg0 = s->id; p->msg.data_length = len; strcpy((char*)p->data, destination); send_packet(p, s->transport); }
static void jdwp_process_list_updated(void) { char buffer[1024]; int len; JdwpTracker* t = _jdwp_trackers_list.next; len = jdwp_process_list_msg(buffer, sizeof(buffer)); for ( ; t != &_jdwp_trackers_list; t = t->next ) { apacket* p = get_apacket(); asocket* peer = t->socket.peer; memcpy(p->data, buffer, len); p->len = len; peer->enqueue( peer, p ); } }
static void send_connect(atransport *t) { D("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = A_VERSION; cp->msg.arg1 = MAX_PAYLOAD; _snprintf((char*) cp->data, sizeof cp->data, "%s::", HOST ? "host" : adb_device_banner); cp->msg.data_length = strlen((char*) cp->data) + 1; send_packet(cp, t); #if ADB_HOST /* XXX why sleep here? */ // allow the device some time to respond to the connect message adb_sleep_ms(1000); #endif }
static void send_connect(atransport *t) { D("Calling send_connect \n"); XLOGD("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = A_VERSION; cp->msg.arg1 = MAX_PAYLOAD; cp->msg.data_length = fill_connect_data((char *)cp->data, sizeof(cp->data)); send_packet(cp, t); #if ADB_HOST /* XXX why sleep here? */ // allow the device some time to respond to the connect message adb_sleep_ms(1000); #endif }
static void send_auth_response(uint8_t *token, size_t token_size, atransport *t) { D("Calling send_auth_response\n"); apacket *p = get_apacket(); int ret; ret = adb_auth_sign(t->key, token, token_size, p->data); if (!ret) { D("Error signing the token\n"); put_apacket(p); return; } p->msg.command = A_AUTH; p->msg.arg0 = ADB_AUTH_SIGNATURE; p->msg.data_length = ret; send_packet(p, t); }
static void send_auth_publickey(atransport *t) { D("Calling send_auth_publickey\n"); apacket *p = get_apacket(); int ret; ret = adb_auth_get_userkey(p->data, sizeof(p->data)); if (!ret) { D("Failed to get user public key\n"); put_apacket(p); return; } p->msg.command = A_AUTH; p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY; p->msg.data_length = ret; send_packet(p, t); }
static void remote_socket_close(asocket *s) { D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d\n", s->id, s->fd, s->peer?s->peer->fd:-1); apacket *p = get_apacket(); p->msg.command = A_CLSE; if(s->peer) { p->msg.arg0 = s->peer->id; s->peer->peer = 0; D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d\n", s->id, s->peer->id, s->peer->fd); s->peer->close(s->peer); } p->msg.arg1 = s->id; send_packet(p, s->transport); D("RS(%d): closed\n", s->id); remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); free(s); }
static void jdwp_socket_ready( asocket* s ) { JdwpSocket* jdwp = (JdwpSocket*)s; asocket* peer = jdwp->socket.peer; /* on the first call, send the list of pids, * on the second one, close the connection */ if (jdwp->pass == 0) { apacket* p = get_apacket(); p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD); peer->enqueue(peer, p); jdwp->pass = 1; } else { peer->close(peer); } }
void send_auth_request(atransport *t) { D("Calling send_auth_request\n"); apacket *p; int ret; ret = adb_auth_generate_token(t->token, sizeof(t->token)); if (ret != sizeof(t->token)) { D("Error generating token ret=%d\n", ret); return; } p = get_apacket(); memcpy(p->data, t->token, ret); p->msg.command = A_AUTH; p->msg.arg0 = ADB_AUTH_TOKEN; p->msg.data_length = ret; send_packet(p, t); }