int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) { D("service=%s, ttype=%d, serial=%s, reply_fd=%d, asocket=?\n", service, ttype, serial, reply_fd); atransport *transport = NULL; char buf[4096]; if(!strcmp(service, "kill")) { fprintf(stderr,"adb server killed by remote request\n"); fflush(stdout); adb_write(reply_fd, "OKAY", 4); usb_cleanup(); exit(0); } #if ADB_HOST // "transport:" is used for switching transport with a specified serial number // "transport-usb:" is used for switching transport to the only USB transport // "transport-local:" is used for switching transport to the only local transport // "transport-any:" is used for switching transport to the only transport if (!strncmp(service, "transport", strlen("transport"))) { char* error_string = "unknown failure"; transport_type type = kTransportAny; if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { type = kTransportAny; } else if (!strncmp(service, "transport:", strlen("transport:"))) { service += strlen("transport:"); serial = service; } transport = acquire_one_transport(CS_ANY, type, serial, &error_string); if (transport) { s->transport = transport; adb_write(reply_fd, "OKAY", 4); } else { sendfailmsg(reply_fd, error_string); } return 1; } // return a list of all connected devices if (!strncmp(service, "devices", 7)) { char buffer[4096]; int use_long = !strcmp(service+7, "-l"); if (use_long || service[7] == 0) { memset(buf, 0, sizeof(buf)); memset(buffer, 0, sizeof(buffer)); D("Getting device list \n"); list_transports(buffer, sizeof(buffer), use_long); snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); D("Wrote device list \n"); writex(reply_fd, buf, strlen(buf)); return 0; } } // add a new TCP transport, device or emulator if (!strncmp(service, "connect:", 8)) { char buffer[4096]; char* host = service + 8; if (!strncmp(host, "emu:", 4)) { connect_emulator(host + 4, buffer, sizeof(buffer)); } else { connect_device(host, buffer, sizeof(buffer)); } // Send response for emulator and device snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); writex(reply_fd, buf, strlen(buf)); return 0; } // remove TCP transport // Disable the disconnect service to prevent complexity with Windows // // returns our value for ADB_SERVER_VERSION if (!strcmp(service, "version")) { printf("the version service is disabled.\n"); return -1; } if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { char *out = "unknown"; transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); if (transport && transport->serial) { out = transport->serial; } snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); writex(reply_fd, buf, strlen(buf)); return 0; } if(!strncmp(service,"get-devpath",strlen("get-devpath"))) { char *out = "unknown"; transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); if (transport && transport->devpath) { out = transport->devpath; } snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); writex(reply_fd, buf, strlen(buf)); return 0; } // indicates a new emulator instance has started if (!strncmp(service,"emulator:",9)) { int port = atoi(service+9); local_connect(port); /* we don't even need to send a reply */ return 0; } #endif // ADB_HOST if(!strcmp(service,"list-forward")) { // Create the list of forward redirections. char header[9]; int buffer_size = format_listeners(NULL, 0); // Add one byte for the trailing zero. char* buffer = (char*)malloc(buffer_size+1); (void) format_listeners(buffer, buffer_size+1); snprintf(header, sizeof header, "OKAY%04x", buffer_size); writex(reply_fd, header, 8); writex(reply_fd, buffer, buffer_size); free(buffer); return 0; } if (!strcmp(service,"killforward-all")) { remove_all_listeners(); adb_write(reply_fd, "OKAYOKAY", 8); return 0; } if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) { char *local, *remote, *err; int r; atransport *transport; int createForward = strncmp(service,"kill",4); int no_rebind = 0; local = strchr(service, ':') + 1; // Handle forward:norebind:<local>... here if (createForward && !strncmp(local, "norebind:", 9)) { no_rebind = 1; local = strchr(local, ':') + 1; } remote = strchr(local,';'); if (createForward) { // Check forward: parameter format: '<local>;<remote>' if(remote == 0) { sendfailmsg(reply_fd, "malformed forward spec"); return 0; } *remote++ = 0; if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){ sendfailmsg(reply_fd, "malformed forward spec"); return 0; } } else { // Check killforward: parameter format: '<local>' if (local[0] == 0) { sendfailmsg(reply_fd, "malformed forward spec"); return 0; } } transport = acquire_one_transport(CS_ANY, ttype, serial, &err); if (!transport) { sendfailmsg(reply_fd, err); return 0; } if (createForward) { r = install_listener(local, remote, transport, no_rebind); } else { r = remove_listener(local, transport); } if(r == 0) { /* 1st OKAY is connect, 2nd OKAY is status */ writex(reply_fd, "OKAYOKAY", 8); return 0; } if (createForward) { const char* message; switch (r) { case INSTALL_STATUS_CANNOT_BIND: message = "cannot bind to socket"; break; case INSTALL_STATUS_CANNOT_REBIND: message = "cannot rebind existing socket"; break; default: message = "internal error"; } sendfailmsg(reply_fd, message); } else { sendfailmsg(reply_fd, "cannot remove listener"); } return 0; } if(!strncmp(service,"get-state",strlen("get-state"))) { transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); char *state = connection_state_name(transport); snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state); writex(reply_fd, buf, strlen(buf)); return 0; } return -1; }
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) { atransport *transport = NULL; char buf[4096]; if(!strcmp(service, "kill")) { fprintf(stderr,"adb server killed by remote request\n"); fflush(stdout); adb_write(reply_fd, "OKAY", 4); usb_cleanup(); exit(0); } #if ADB_HOST // "transport:" is used for switching transport with a specified serial number // "transport-usb:" is used for switching transport to the only USB transport // "transport-local:" is used for switching transport to the only local transport // "transport-any:" is used for switching transport to the only transport if (!strncmp(service, "transport", strlen("transport"))) { char* error_string = "unknown failure"; transport_type type = kTransportAny; if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { type = kTransportAny; } else if (!strncmp(service, "transport:", strlen("transport:"))) { service += strlen("transport:"); serial = strdup(service); } transport = acquire_one_transport(CS_ANY, type, serial, &error_string); if (transport) { s->transport = transport; adb_write(reply_fd, "OKAY", 4); } else { sendfailmsg(reply_fd, error_string); } return 1; } // return a list of all connected devices if (!strcmp(service, "devices")) { char buffer[4096]; memset(buf, 0, sizeof(buf)); memset(buffer, 0, sizeof(buffer)); D("Getting device list \n"); list_transports(buffer, sizeof(buffer)); snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); D("Wrote device list \n"); writex(reply_fd, buf, strlen(buf)); return 0; } // add a new TCP transport, device or emulator if (!strncmp(service, "connect:", 8)) { char buffer[4096]; char* host = service + 8; if (!strncmp(host, "emu:", 4)) { connect_emulator(host + 4, buffer, sizeof(buffer)); } else { connect_device(host, buffer, sizeof(buffer)); } // Send response for emulator and device snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); writex(reply_fd, buf, strlen(buf)); return 0; } // remove TCP transport if (!strncmp(service, "disconnect:", 11)) { char buffer[4096]; memset(buffer, 0, sizeof(buffer)); char* serial = service + 11; if (serial[0] == 0) { // disconnect from all TCP devices unregister_all_tcp_transports(); } else { char hostbuf[100]; // assume port 5555 if no port is specified if (!strchr(serial, ':')) { snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); serial = hostbuf; } atransport *t = find_transport(serial); if (t) { unregister_transport(t); } else { snprintf(buffer, sizeof(buffer), "No such device %s", serial); } } snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); writex(reply_fd, buf, strlen(buf)); return 0; } // returns our value for ADB_SERVER_VERSION if (!strcmp(service, "version")) { char version[12]; snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version); writex(reply_fd, buf, strlen(buf)); return 0; } if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { char *out = "unknown"; transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); if (transport && transport->serial) { out = transport->serial; } snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); writex(reply_fd, buf, strlen(buf)); return 0; } // indicates a new emulator instance has started if (!strncmp(service,"emulator:",9)) { int port = atoi(service+9); local_connect(port); /* we don't even need to send a reply */ return 0; } #endif // ADB_HOST if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) { char *local, *remote, *err; int r; atransport *transport; int createForward = strncmp(service,"kill",4); local = service + (createForward ? 8 : 12); remote = strchr(local,';'); if(remote == 0) { sendfailmsg(reply_fd, "malformed forward spec"); return 0; } *remote++ = 0; if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){ sendfailmsg(reply_fd, "malformed forward spec"); return 0; } transport = acquire_one_transport(CS_ANY, ttype, serial, &err); if (!transport) { sendfailmsg(reply_fd, err); return 0; } if (createForward) { r = install_listener(local, remote, transport); } else { r = remove_listener(local, remote, transport); } if(r == 0) { /* 1st OKAY is connect, 2nd OKAY is status */ writex(reply_fd, "OKAYOKAY", 8); return 0; } if (createForward) { sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket"); } else { sendfailmsg(reply_fd, "cannot remove listener"); } return 0; } if(!strncmp(service,"get-state",strlen("get-state"))) { transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); char *state = connection_state_name(transport); snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state); writex(reply_fd, buf, strlen(buf)); return 0; } return -1; }
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) { atransport *transport = NULL; if(!strcmp(service, "kill")) { fprintf(stderr,"adb server killed by remote request\n"); fflush(stdout); adb_write(reply_fd, "OKAY", 4); usb_cleanup(); exit(0); } #if ADB_HOST // "transport:" is used for switching transport with a specified serial number // "transport-usb:" is used for switching transport to the only USB transport // "transport-local:" is used for switching transport to the only local transport // "transport-any:" is used for switching transport to the only transport if (!strncmp(service, "transport", strlen("transport"))) { char* error_string = "unknown failure"; transport_type type = kTransportAny; if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { type = kTransportAny; } else if (!strncmp(service, "transport:", strlen("transport:"))) { service += strlen("transport:"); serial = service; } transport = acquire_one_transport(CS_ANY, type, serial, &error_string); if (transport) { s->transport = transport; adb_write(reply_fd, "OKAY", 4); } else { sendfailmsg(reply_fd, error_string); } return 1; } // return a list of all connected devices if (!strncmp(service, "devices", 7)) { char buffer[4096]; int use_long = !strcmp(service+7, "-l"); if (use_long || service[7] == 0) { memset(buffer, 0, sizeof(buffer)); D("Getting device list \n"); list_transports(buffer, sizeof(buffer), use_long); D("Wrote device list \n"); send_msg_with_okay(reply_fd, buffer, strlen(buffer)); return 0; } } // remove TCP transport if (!strncmp(service, "disconnect:", 11)) { char buffer[4096]; memset(buffer, 0, sizeof(buffer)); char* serial = service + 11; if (serial[0] == 0) { // disconnect from all TCP devices unregister_all_tcp_transports(); } else { char hostbuf[100]; // assume port 5555 if no port is specified if (!strchr(serial, ':')) { snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); serial = hostbuf; } atransport *t = find_transport(serial); if (t) { unregister_transport(t); } else { snprintf(buffer, sizeof(buffer), "No such device %s", serial); } } send_msg_with_okay(reply_fd, buffer, strlen(buffer)); return 0; } // returns our value for ADB_SERVER_VERSION if (!strcmp(service, "version")) { char version[12]; snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); send_msg_with_okay(reply_fd, version, strlen(version)); return 0; } if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { char *out = "unknown"; transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); if (transport && transport->serial) { out = transport->serial; } send_msg_with_okay(reply_fd, out, strlen(out)); return 0; } if(!strncmp(service,"get-devpath",strlen("get-devpath"))) { char *out = "unknown"; transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); if (transport && transport->devpath) { out = transport->devpath; } send_msg_with_okay(reply_fd, out, strlen(out)); return 0; } // indicates a new emulator instance has started if (!strncmp(service,"emulator:",9)) { int port = atoi(service+9); local_connect(port); /* we don't even need to send a reply */ return 0; } #endif // ADB_HOST int ret = handle_forward_request(service, ttype, serial, reply_fd); if (ret >= 0) return ret - 1; if(!strncmp(service,"get-state",strlen("get-state"))) { transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); char *state = connection_state_name(transport); send_msg_with_okay(reply_fd, state, strlen(state)); return 0; } return -1; }