#if SDB_TRACE
-#if !SDB_HOST
/*
* When running inside the emulator, guest's sdbd can connect to 'sdb-debug'
* qemud service that can display sdb trace messages (on condition that emulator
* has been started with '-debug sdb' option).
*/
-
/* Delivers a trace message to the emulator via QEMU pipe. */
void sdb_qemu_trace(const char* fmt, ...);
/* Macro to use to send SDB trace messages to the emulator. */
#define DQ(...) sdb_qemu_trace(__VA_ARGS__)
-#else
-#define DQ(...) ((void)0)
-#endif /* !SDB_HOST */
extern int sdb_trace_mask;
extern unsigned char sdb_trace_output_count;
SDB_MUTEX(dns_lock)
SDB_MUTEX(socket_list_lock)
SDB_MUTEX(transport_lock)
-#if SDB_HOST
-SDB_MUTEX(local_transports_lock)
-#endif
SDB_MUTEX(usb_lock)
// Sadly logging to /data/sdb/sdb-... is not thread safe.
#include "log.h"
#include "sdb.h"
#include "strutils.h"
-#if !SDB_HOST
#include "commandline_sdbd.h"
-#endif
#include "utils.h"
#include "sdktools.h"
#include "plugin.h"
#include "plugin_encrypt.h"
#endif
-#if !SDB_HOST
#include <linux/prctl.h>
#define SDB_PIDPATH "/tmp/.sdbd.pid"
-#endif
#include <system_info.h>
#include <vconf.h>
#include <glib.h>
int is_init_sdk_userinfo = 0;
int is_pwlocked = 0; // 0 if unlocked, 1 otherwise
-#if !SDB_HOST
SdbdCommandlineArgs sdbd_commandline_args;
-#endif
static int is_support_usbproto();
static int is_support_sockproto();
int g_is_emulator = -1;
int is_emulator(void) {
-#if SDB_HOST
- return 0;
-#else
if (g_is_emulator >= 0) {
return g_is_emulator;
} else {
}
return sdbd_commandline_args.emulator.host != NULL;
-#endif
}
int is_appid2pid_supported(void) {
}
}
-#if !SDB_HOST
/*
* Implements SDB tracing inside the emulator.
*/
/* A handle to sdb-debug qemud service in the emulator. */
int sdb_debug_qemu = -1;
-/* Initializes connection with the sdb-debug qemud service in the emulator. */
-#if 0 /* doen't support in Tizen */
-static int sdb_qemu_trace_init(void)
-{
- char con_name[32];
-
- if (sdb_debug_qemu >= 0) {
- return 0;
- }
-
- /* sdb debugging QEMUD service connection request. */
- snprintf(con_name, sizeof(con_name), "qemud:sdb-debug");
- sdb_debug_qemu = qemu_pipe_open(con_name);
- return (sdb_debug_qemu >= 0) ? 0 : -1;
-}
-
-void sdb_qemu_trace(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- char msg[1024];
-
- if (sdb_debug_qemu >= 0) {
- vsnprintf(msg, sizeof(msg), fmt, args);
- sdb_write(sdb_debug_qemu, msg, strlen(msg));
- }
-}
-#endif
-#endif /* !SDB_HOST */
-
apacket *get_apacket(void)
{
apacket *p = malloc(sizeof(apacket));
cp->msg.data_length = strlen((char*) cp->data) + 1;
send_packet(cp, t);
-#if SDB_HOST
- /* XXX why sleep here? */
- // allow the device some time to respond to the connect message
- sdb_sleep_ms(1000);
-#endif
}
void send_device_status()
#endif
}
-#if !SDB_HOST
-
void start_device_log(void)
{
int fd;
return 0;
}
-#endif
-
-#if SDB_HOST
-int launch_server(int server_port)
-{
-#ifdef HAVE_WIN32_PROC
- /* we need to start the server in the background */
- /* we create a PIPE that will be used to wait for the server's "OK" */
- /* message since the pipe handles must be inheritable, we use a */
- /* security attribute */
- HANDLE pipe_read, pipe_write;
- SECURITY_ATTRIBUTES sa;
- STARTUPINFO startup;
- PROCESS_INFORMATION pinfo;
- char program_path[ MAX_PATH ];
- int ret;
-
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
-
- /* create pipe, and ensure its read handle isn't inheritable */
- ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
- if (!ret) {
- fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
- return -1;
- }
-
- SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
-
- ZeroMemory( &startup, sizeof(startup) );
- startup.cb = sizeof(startup);
- startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
- startup.hStdOutput = pipe_write;
- startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
- startup.dwFlags = STARTF_USESTDHANDLES;
-
- ZeroMemory( &pinfo, sizeof(pinfo) );
-
- /* get path of current program */
- GetModuleFileName( NULL, program_path, sizeof(program_path) );
-
- ret = CreateProcess(
- program_path, /* program path */
- "sdb fork-server server",
- /* the fork-server argument will set the
- debug = 2 in the child */
- NULL, /* process handle is not inheritable */
- NULL, /* thread handle is not inheritable */
- TRUE, /* yes, inherit some handles */
- DETACHED_PROCESS, /* the new process doesn't have a console */
- NULL, /* use parent's environment block */
- NULL, /* use parent's starting directory */
- &startup, /* startup info, i.e. std handles */
- &pinfo );
-
- CloseHandle( pipe_write );
-
- if (!ret) {
- fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
- CloseHandle( pipe_read );
- return -1;
- }
-
- CloseHandle( pinfo.hProcess );
- CloseHandle( pinfo.hThread );
-
- /* wait for the "OK\n" message */
- {
- char temp[3];
- DWORD count;
-
- ret = ReadFile( pipe_read, temp, 3, &count, NULL );
- CloseHandle( pipe_read );
- if ( !ret ) {
- fprintf(stderr, "could not read ok from SDB Server, error = %ld\n", GetLastError() );
- return -1;
- }
- if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
- fprintf(stderr, "SDB server didn't ACK\n" );
- return -1;
- }
- }
-#elif defined(HAVE_FORKEXEC)
- char path[PATH_MAX];
- int fd[2];
-
- // set up a pipe so the child can tell us when it is ready.
- // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
- if (pipe(fd)) {
- fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
- return -1;
- }
- get_my_path(path, PATH_MAX);
- pid_t pid = fork();
- if(pid < 0) return -1;
-
- if (pid == 0) {
- // child side of the fork
-
- // redirect stderr to the pipe
- // we use stderr instead of stdout due to stdout's buffering behavior.
- sdb_close(fd[0]);
- dup2(fd[1], STDERR_FILENO);
- sdb_close(fd[1]);
-
- // child process
- int result = execl(path, "sdb", "fork-server", "server", NULL);
- // this should not return
- fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
- } else {
- // parent side of the fork
-
- char temp[3];
-
- temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
- // wait for the "OK\n" message
- sdb_close(fd[1]);
- int ret = sdb_read(fd[0], temp, 3);
- int saved_errno = errno;
- sdb_close(fd[0]);
- if (ret < 0) {
- fprintf(stderr, "could not read ok from SDB Server, errno = %d\n", saved_errno);
- return -1;
- }
- if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
- fprintf(stderr, "SDB server didn't ACK\n" );
- return -1;
- }
-
- setsid();
- }
-#else
-#error "cannot implement background server start on this platform"
-#endif
- return 0;
-}
-#endif
/* Constructs a local name of form tcp:port.
* target_str points to the target string, it's content will be overwritten.
snprintf(target_str, target_size, "tcp:%d", server_port);
}
-#if !SDB_HOST
static void init_drop_privileges() {
#ifdef _DROP_PRIVILEGE
rootshell_mode = 0;
register_bootdone_cb();
}
}
-#endif /* !SDB_HOST */
static void init_capabilities(void) {
int ret = -1;
int sdb_main(int is_daemon, int server_port)
{
-#if !SDB_HOST
check_emulator_or_device();
load_sdbd_plugin();
umask(000);
pthread_atfork(fork_prepare_handler, fork_parent_handler, fork_child_handler);
-#endif
atexit(sdb_cleanup);
#ifdef HAVE_WIN32_PROC
init_transport_registration();
-
-#if SDB_HOST
- HOST = 1;
- usb_init();
- local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
-
- char local_name[30];
- build_local_name(local_name, sizeof(local_name), server_port);
- if(install_listener(local_name, "*smartsocket*", NULL)) {
- exit(1);
- }
-#else
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
init_jdwp();
D("sdb_main(): post init_jdwp()\n");
#endif
-#endif
if (is_daemon)
{
return 0;
}
-#if SDB_HOST
-void connect_device(char* host, char* buffer, int buffer_size)
-{
- int port, fd;
- char* portstr = strchr(host, ':');
- char hostbuf[100];
- char serial[100];
-
- s_strncpy(hostbuf, host, sizeof(hostbuf) - 1);
- if (portstr) {
- if (portstr - host >= sizeof(hostbuf)) {
- snprintf(buffer, buffer_size, "bad host name %s", host);
- return;
- }
- // zero terminate the host at the point we found the colon
- hostbuf[portstr - host] = 0;
- if (sscanf(portstr + 1, "%d", &port) == 0) {
- snprintf(buffer, buffer_size, "bad port number %s", portstr);
- return;
- }
- } else {
- port = DEFAULT_SDB_LOCAL_TRANSPORT_PORT;
- }
-
- snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
- if (find_transport(serial)) {
- snprintf(buffer, buffer_size, "already connected to %s", serial);
- return;
- }
-
- fd = socket_network_client(hostbuf, port, SOCK_STREAM);
- if (fd < 0) {
- snprintf(buffer, buffer_size, "unable to connect to %s", host);
- return;
- }
-
- D("client: connected on remote on fd %d\n", fd);
- close_on_exec(fd);
- disable_tcp_nagle(fd);
- register_socket_transport(fd, serial, port, 0, NULL);
- snprintf(buffer, buffer_size, "connected to %s", serial);
-}
-
-void connect_emulator(char* port_spec, char* buffer, int buffer_size)
-{
- char* port_separator = strchr(port_spec, ',');
- if (!port_separator) {
- snprintf(buffer, buffer_size,
- "unable to parse '%s' as <console port>,<sdb port>",
- port_spec);
- return;
- }
-
- // Zero-terminate console port and make port_separator point to 2nd port.
- *port_separator++ = 0;
- int console_port = strtol(port_spec, NULL, 0);
- int sdb_port = strtol(port_separator, NULL, 0);
- if (!(console_port > 0 && sdb_port > 0)) {
- *(port_separator - 1) = ',';
- snprintf(buffer, buffer_size,
- "Invalid port numbers: Expected positive numbers, got '%s'",
- port_spec);
- return;
- }
-
- /* Check if the emulator is already known.
- * Note: There's a small but harmless race condition here: An emulator not
- * present just yet could be registered by another invocation right
- * after doing this check here. However, local_connect protects
- * against double-registration too. From here, a better error message
- * can be produced. In the case of the race condition, the very specific
- * error message won't be shown, but the data doesn't get corrupted. */
- atransport* known_emulator = find_emulator_transport_by_sdb_port(sdb_port);
- if (known_emulator != NULL) {
- snprintf(buffer, buffer_size,
- "Emulator on port %d already registered.", sdb_port);
- return;
- }
-
- /* Check if more emulators can be registered. Similar unproblematic
- * race condition as above. */
- int candidate_slot = get_available_local_transport_index();
- if (candidate_slot < 0) {
- snprintf(buffer, buffer_size, "Cannot accept more emulators.");
- return;
- }
-
- /* Preconditions met, try to connect to the emulator. */
- if (!local_connect_arbitrary_ports(console_port, sdb_port, NULL)) {
- snprintf(buffer, buffer_size,
- "Connected to emulator on ports %d,%d", console_port, sdb_port);
- } else {
- snprintf(buffer, buffer_size,
- "Could not connect to emulator on ports %d,%d",
- console_port, sdb_port);
- }
-}
-#endif
-
int copy_packet(apacket* dest, apacket* src) {
if(dest == NULL) {
exit(0);
}
-#if SDB_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;
- sdb_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 26101 if no port is specified
- if (!strchr(serial, ':')) {
- snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:26101", 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 SDB_SERVER_VERSION
- if (!strcmp(service, "version")) {
- char version[12];
- snprintf(version, sizeof version, "%04x", SDB_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)) { /* tizen specific */
- char *tmp = strtok(service+9, DEVICEMAP_SEPARATOR);
- int port = 0;
-
- if (tmp == NULL) {
- port = atoi(service+9);
- } else {
- port = atoi(tmp);
- tmp = strtok(NULL, DEVICEMAP_SEPARATOR);
- if (tmp != NULL) {
- local_connect(port, tmp);
- }
- }
- local_connect(port, NULL);
- return 0;
- }
-#endif // SDB_HOST
-
if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
char *local, *remote, *err;
int r;
return -1;
}
-#if !SDB_HOST
int recovery_mode = 0;
-#endif
int main(int argc, char **argv)
{
-#if SDB_HOST
- sdb_sysdeps_init();
- sdb_trace_init();
- return sdb_commandline(argc - 1, argv + 1);
-#else
/* If sdbd runs inside the emulator this will enable sdb tracing via
* sdb-debug qemud service in the emulator. */
#if 0 /* tizen specific */
return EXIT_FAILURE;
}
-#if !SDB_HOST
if (daemonize() < 0)
fatal("daemonize() failed: errno:%d", errno);
-#endif
D("Handling main()\n");
//sdbd will never die on emulator!
signal(SIGTERM, handle_sig_term); /* tizen specific */
return sdb_main(0, DEFAULT_SDB_PORT);
-#endif
}
#include "transport.h" /* readx(), writex() */
#include "fdevent.h"
-#if !SDB_HOST
#include "commandline_sdbd.h"
-#endif
#include <tzplatform_config.h>
#define MAX_PAYLOAD_V1 (4*1024)
void kick_transport( atransport* t );
/* initialize a transport object's func pointers and state */
-#if SDB_HOST
-int get_available_local_transport_index();
-#endif
int init_socket_transport(atransport *t, int s, int port, int local);
void init_usb_transport(atransport *t, usb_handle *usb, int state);
void unregister_usb_transport(usb_handle *usb);
atransport *find_transport(const char *serial);
-#if SDB_HOST
-atransport* find_emulator_transport_by_sdb_port(int sdb_port);
-#endif
int service_to_fd(const char *name);
-#if SDB_HOST
-asocket *host_service_to_socket(const char* name, const char *serial);
-#endif
-#if !SDB_HOST
int init_jdwp(void);
asocket* create_jdwp_service_socket();
asocket* create_jdwp_tracker_service_socket();
int create_jdwp_connection_fd(int jdwp_pid);
-#endif
-#if !SDB_HOST
typedef enum {
BACKUP,
RESTORE
extern char* g_root_home_dir;
extern char* g_root_home_dir_env;
-#endif
-
int should_drop_privileges(void);
void send_device_status();
int set_sdk_user_privileges(int is_drop_capability_after_fork);
int local_connect_arbitrary_ports(int console_port, int sdb_port, const char *device_name);
/* usb host/client interface */
-#if SDB_HOST
-void usb_init();
-void usb_cleanup();
-int usb_write(usb_handle *h, const void *data, int len);
-int usb_read(usb_handle *h, void *data, size_t len);
-int usb_close(usb_handle *h);
-void usb_kick(usb_handle *h);
-#else
-
extern void (*usb_init)();
extern void (*usb_cleanup)();
extern int (*usb_write)(usb_handle *h, const void *data, int len);
int linux_usb_close(usb_handle *h);
void linux_usb_kick(usb_handle *h);
-#endif
-
-/* used for USB device detection */
-#if SDB_HOST
-int is_sdb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
-#endif
-
unsigned host_to_le32(unsigned n);
int sdb_commandline(int argc, char **argv);
extern int HOST;
extern int SHELL_EXIT_NOTIFY_FD;
-#if !SDB_HOST
extern SdbdCommandlineArgs sdbd_commandline_args;
-#endif
#define CHUNK_SIZE (64*1024)
#define SDBD_SHELL_CMD_MAX 4096
int is_emulator(void);
#define DEFAULT_DEVICENAME "unknown"
-#if SDB_HOST /* tizen-specific */
-#define DEVICEMAP_SEPARATOR ":"
-#define DEVICENAME_MAX 256
-#define VMS_PATH OS_PATH_SEPARATOR_STR "vms" OS_PATH_SEPARATOR_STR // should include sysdeps.h above
-
-void register_device_name(const char *device_type, const char *device_name, int port);
-int get_devicename_from_shdmem(int port, char *device_name);
-int read_line(const int fd, char* ptr, const size_t maxlen);
-#endif
-#endif
-
#define USB_FUNCFS_SDB_PATH "/dev/usbgadget/sdb"
#define USB_NODE_FILE "/dev/samsung_sdb"
int create_subprocess(const char *cmd, pid_t *pid, char * const argv[], char * const envp[]);
#define RESERVE_CAPABILITIES_AFTER_FORK 0
#define DROP_CAPABILITIES_AFTER_FORK 1
+#endif
#include "sdb.h"
#include "file_sync_service.h"
-#if SDB_HOST
-# ifndef HAVE_WINSOCK
-# include <netinet/in.h>
-# include <netdb.h>
-# include <sys/ioctl.h>
-# endif
-#else
-# include <sys/inotify.h>
-# include "sdktools.h"
-#endif
+#include <sys/inotify.h>
+#include "sdktools.h"
#include <sys/socket.h>
#include <sys/un.h>
return 0;
}
-#if SDB_HOST
-SDB_MUTEX_DEFINE( dns_lock );
-
-static void dns_service(int fd, void *cookie)
-{
- char *hostname = cookie;
- struct hostent *hp;
- unsigned zero = 0;
-
- sdb_mutex_lock(&dns_lock);
- hp = gethostbyname(hostname);
- free(cookie);
- if(hp == 0) {
- writex(fd, &zero, 4);
- } else {
- writex(fd, hp->h_addr, 4);
- }
- sdb_mutex_unlock(&dns_lock);
- sdb_close(fd);
-}
-#else
-
static int is_support_interactive_shell()
{
return (!strncmp(g_capabilities.intershell_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)));
#endif
}
-#if !SDB_HOST
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
#define CS_PATH tzplatform_getenv(TZ_SYS_CRASH)
sdb_close(fd);
D( "inoti_service end\n");
}
-#endif
-#endif
#if 0
static void echo_service(int fd, void *cookie)
return s[0];
}
-#if !SDB_HOST
-
static void redirect_and_exec(int pts, const char *cmd, char * const argv[], char * const envp[])
{
dup2(pts, 0);
return ptm;
}
}
-#endif /* !SDB_HOST */
#define USER_DAEMON_COMMAND "/usr/sbin/sdbd-user"
#define LOGIN_COMMAND "/bin/login"
#define SUPER_USER "root"
#define LOGIN_CONFIG "/etc/login.defs"
-#if !SDB_HOST
static void subproc_waiter_service(int fd, void *cookie)
{
pid_t pid = (pid_t)cookie;
return ret_fd;
}
-#endif
static void get_platforminfo(int fd, void *cookie) {
pinfo sysinfo;
disable_tcp_nagle(ret);
}
} else {
-#if SDB_HOST
- sdb_mutex_lock(&dns_lock);
- ret = socket_network_client(name + 1, port, SOCK_STREAM);
- sdb_mutex_unlock(&dns_lock);
-#else
return -1;
-#endif
}
#ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */
} else if(!strncmp(name, "local:", 6)) {
ret = socket_local_client(name + 16,
ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
#endif
-#if SDB_HOST
- } else if(!strncmp("dns:", name, 4)){
- char *n = strdup(name + 4);
- if(n == 0) return -1;
- ret = create_service_thread(dns_service, n);
-#else /* !SDB_HOST */
}/* else if(!strncmp("dev:", name, 4)) {// tizen specific
ret = unix_open(name + 4, O_RDWR);
} else if(!strncmp(name, "framebuffer:", 12)) {
ret = create_service_thread(rootshell_service, (void *)(service_name));
} else if(!strncmp(name, "cs:", 5)) {
ret = create_service_thread(inoti_service, NULL);
-#endif
} else if(!strncmp(name, "sysinfo:", 8)){
ret = create_service_thread(get_platforminfo, 0);
} else if(!strncmp(name, "capability:", 11)){
}
return ret;
}
-
-#if SDB_HOST
-struct state_info {
- transport_type transport;
- char* serial;
- int state;
-};
-
-static void wait_for_state(int fd, void* cookie)
-{
- struct state_info* sinfo = cookie;
- char* err = "unknown error";
-
- D("wait_for_state %d\n", sinfo->state);
-
- atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);
- if(t != 0) {
- writex(fd, "OKAY", 4);
- } else {
- sendfailmsg(fd, err);
- }
-
- if (sinfo->serial)
- free(sinfo->serial);
- free(sinfo);
- sdb_close(fd);
- D("wait_for_state is done\n");
-}
-#endif
-
-#if SDB_HOST
-asocket* host_service_to_socket(const char* name, const char *serial)
-{
- if (!strcmp(name,"track-devices")) {
- return create_device_tracker();
- } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
- struct state_info* sinfo = malloc(sizeof(struct state_info));
-
- if (serial)
- sinfo->serial = strdup(serial);
- else
- sinfo->serial = NULL;
-
- name += strlen("wait-for-");
-
- if (!strncmp(name, "local", strlen("local"))) {
- sinfo->transport = kTransportLocal;
- sinfo->state = CS_DEVICE;
- } else if (!strncmp(name, "usb", strlen("usb"))) {
- sinfo->transport = kTransportUsb;
- sinfo->state = CS_DEVICE;
- } else if (!strncmp(name, "any", strlen("any"))) {
- sinfo->transport = kTransportAny;
- sinfo->state = CS_DEVICE;
- } else {
- free(sinfo);
- return NULL;
- }
-
- int fd = create_service_thread(wait_for_state, sinfo);
- return create_local_socket(fd);
- }
- return NULL;
-}
-#endif /* SDB_HOST */
int cnt_max = 30;
/* tizen specific */
-#if !SDB_HOST
// check the loopback interface has been up in 30 sec
while(cnt_max > 0) {
if(get_loopback_status() == LOOPBACK_DOWN) {
break;
}
}
-#endif
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
int fd;
#if 0 /* not support in tizen */
-#if !SDB_HOST
if (!strcmp(name,"jdwp")) {
return create_jdwp_service_socket();
}
return create_jdwp_tracker_service_socket();
}
#endif
-#endif
fd = service_to_fd(name);
if(fd < 0) return 0;
return s;
}
-#if SDB_HOST
-static asocket *create_host_service_socket(const char *name, const char* serial)
-{
- asocket *s;
-
- s = host_service_to_socket(name, serial);
-
- if (s != NULL) {
- D("LS(%d) bound to '%s'\n", s->id, name);
- return s;
- }
-
- return s;
-}
-#endif /* SDB_HOST */
-
/* a Remote socket is used to send/receive data to/from a given transport object
** it needs to be closed when the transport is forcibly destroyed by the user
*/
static int smart_socket_enqueue(asocket *s, apacket *p)
{
unsigned len;
-#if SDB_HOST
- char *service = NULL;
- char* serial = NULL;
- transport_type ttype = kTransportAny;
-#endif
D("SS(%d): enqueue %d\n", s->id, p->len);
D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
-#if SDB_HOST
- service = (char *)p->data + 4;
- if(!strncmp(service, "host-serial:", strlen("host-serial:"))) {
- char* serial_end;
- service += strlen("host-serial:");
-
- // serial number should follow "host:" and could be a host:port string.
- serial_end = skip_host_serial(service);
- if (serial_end) {
- *serial_end = 0; // terminate string
- serial = service;
- service = serial_end + 1;
- }
- } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
- ttype = kTransportUsb;
- service += strlen("host-usb:");
- } else if (!strncmp(service, "host-local:", strlen("host-local:"))) {
- ttype = kTransportLocal;
- service += strlen("host-local:");
- } else if (!strncmp(service, "host:", strlen("host:"))) {
- ttype = kTransportAny;
- service += strlen("host:");
- } else {
- service = NULL;
- }
-
- if (service) {
- asocket *s2;
-
- /* some requests are handled immediately -- in that
- ** case the handle_host_request() routine has sent
- ** the OKAY or FAIL message and all we have to do
- ** is clean up.
- */
- if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) {
- /* XXX fail message? */
- D( "SS(%d): handled host service '%s'\n", s->id, service );
- goto fail;
- }
- if (!strncmp(service, "transport", strlen("transport"))) {
- D( "SS(%d): okay transport\n", s->id );
- p->len = 0;
- return 0;
- }
-
- /* try to find a local service with this name.
- ** if no such service exists, we'll fail out
- ** and tear down here.
- */
- s2 = create_host_service_socket(service, serial);
- if(s2 == 0) {
- D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
- sendfailmsg(s->peer->fd, "unknown host service");
- goto fail;
- }
-
- /* we've connected to a local host service,
- ** so we make our peer back into a regular
- ** local socket and bind it to the new local
- ** service socket, acknowledge the successful
- ** connection, and close this smart socket now
- ** that its work is done.
- */
- sdb_write(s->peer->fd, "OKAY", 4);
-
- s->peer->ready = local_socket_ready;
- s->peer->close = local_socket_close;
- s->peer->peer = s2;
- s2->peer = s->peer;
- s->peer = 0;
- D( "SS(%d): okay\n", s->id );
- s->close(s);
-
- /* initial state is "ready" */
- s2->ready(s2);
- return 0;
- }
-#else /* !SDB_HOST */
if (s->transport == NULL) {
char* error_string = "unknown failure";
s->transport = acquire_one_transport (CS_ANY,
goto fail;
}
}
-#endif
if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
/* if there's no remote we fail the connection
static fdevent transport_registration_fde;
-#if SDB_HOST
-static int list_transports_msg(char* buffer, size_t bufferlen)
-{
- char head[5];
- int len;
-
- len = list_transports(buffer+4, bufferlen-4);
- snprintf(head, sizeof(head), "%04x", len);
- memcpy(buffer, head, 4);
- len += 4;
- return len;
-}
-
-/* this adds support required by the 'track-devices' service.
- * this is used to send the content of "list_transport" to any
- * number of client connections that want it through a single
- * live TCP connection
- */
-typedef struct device_tracker device_tracker;
-struct device_tracker {
- asocket socket;
- int update_needed;
- device_tracker* next;
-};
-
-/* linked list of all device trackers */
-static device_tracker* device_tracker_list;
-
-static void
-device_tracker_remove( device_tracker* tracker )
-{
- device_tracker** pnode = &device_tracker_list;
- device_tracker* node = *pnode;
-
- sdb_mutex_lock( &transport_lock );
- while (node) {
- if (node == tracker) {
- *pnode = node->next;
- break;
- }
- pnode = &node->next;
- node = *pnode;
- }
- sdb_mutex_unlock( &transport_lock );
-}
-
-static void
-device_tracker_close( asocket* socket )
-{
- device_tracker* tracker = (device_tracker*) socket;
- asocket* peer = socket->peer;
-
- D( "device tracker %p removed\n", tracker);
- if (peer) {
- peer->peer = NULL;
- peer->close(peer);
- }
- device_tracker_remove(tracker);
- free(tracker);
-}
-
-static int
-device_tracker_enqueue( asocket* socket, apacket* p )
-{
- /* you can't read from a device tracker, close immediately */
- put_apacket(p);
- device_tracker_close(socket);
- return -1;
-}
-
-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
-device_tracker_ready( asocket* socket )
-{
- device_tracker* tracker = (device_tracker*) socket;
-
- /* we want to send the device list when the tracker connects
- * for the first time, even if no update occured */
- if (tracker->update_needed > 0) {
- char buffer[1024];
- int len;
-
- tracker->update_needed = 0;
-
- len = list_transports_msg(buffer, sizeof(buffer));
- device_tracker_send(tracker, buffer, len);
- }
-}
-
-
-asocket*
-create_device_tracker(void)
-{
- device_tracker* tracker = calloc(1,sizeof(*tracker));
-
- if(tracker == 0) fatal("cannot allocate device tracker");
-
- D( "device tracker %p created\n", tracker);
-
- tracker->socket.enqueue = device_tracker_enqueue;
- tracker->socket.ready = device_tracker_ready;
- tracker->socket.close = device_tracker_close;
- tracker->update_needed = 1;
-
- tracker->next = device_tracker_list;
- device_tracker_list = tracker;
-
- return &tracker->socket;
-}
-
-
-/* call this function each time the transport list has changed */
-void update_transports(void)
-{
- char buffer[1024];
- int len;
- device_tracker* tracker;
-
- len = list_transports_msg(buffer, sizeof(buffer));
-
- tracker = device_tracker_list;
- while (tracker != NULL) {
- device_tracker* next = tracker->next;
- /* note: this may destroy the tracker if the connection is closed */
- device_tracker_send(tracker, buffer, len);
- tracker = next;
- }
-}
-#else
void update_transports(void)
{
// nothing to do on the device side
}
-#endif // SDB_HOST
typedef struct tmsg tmsg;
struct tmsg
return result;
}
-#if SDB_HOST
-int list_transports(char *buf, size_t bufsize)
-{
- char* p = buf;
- char* end = buf + bufsize;
- int len;
- atransport *t;
-
- /* XXX OVERRUN PROBLEMS XXX */
- sdb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- const char* serial = t->serial;
- const char* devicename = (t->device_name == NULL) ? DEFAULT_DEVICENAME : t->device_name; /* tizen specific */
- if (!serial || !serial[0])
- serial = "????????????";
- len = snprintf(p, end - p, "%s\t%s\t%s\n", serial, statename(t), devicename);
-
- if (p + len >= end) {
- /* discard last line if buffer is too short */
- break;
- }
- p += len;
- }
- p[0] = 0;
- sdb_mutex_unlock(&transport_lock);
- return p - buf;
-}
-
-
-/* hack for osx */
-void close_usb_devices()
-{
- atransport *t;
-
- sdb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- if ( !t->kicked ) {
- t->kicked = 1;
- t->kick(t);
- }
- }
- sdb_mutex_unlock(&transport_lock);
-}
-#endif // SDB_HOST
-
void register_socket_transport(int s, const char *serial, int port, int local, const char *device_name)
{
atransport *t = calloc(1, sizeof(atransport));
if ( init_socket_transport(t, s, port, local) < 0 ) {
sdb_close(s);
free(t);
-#if SDB_HOST /* tizen specific */
- atransport *old_t = find_transport(serial);
- if (old_t) {
- unregister_transport(old_t);
- } else {
- D("No such device %s", serial);
- }
-#endif
return;
}
t->serial = strdup(serial);
sdb_mutex_unlock(&transport_lock);
-#if SDB_HOST /* tizen specific */
- if (device_name) {/* tizen specific */
- t->device_name = strdup(device_name);
- } else { // device_name could be null when sdb server was forked before qemu has sent the connect message.
- char device_name[DEVICENAME_MAX];
- if (get_devicename_from_shdmem(port, device_name) == 0) {
- t->device_name = strdup(device_name);
- }
- }
-#endif
register_transport(t);
}
-#if SDB_HOST
-atransport *find_transport(const char *serial)
-{
- atransport *t;
-
- sdb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- if (t->serial && !strcmp(serial, t->serial)) {
- break;
- }
- }
- sdb_mutex_unlock(&transport_lock);
-
- if (t != &transport_list)
- return t;
- else
- return 0;
-}
-
-void unregister_transport(atransport *t)
-{
- sdb_mutex_lock(&transport_lock);
- t->next->prev = t->prev;
- t->prev->next = t->next;
- sdb_mutex_unlock(&transport_lock);
-
- kick_transport(t);
- transport_unref(t);
-}
-
-// unregisters all non-emulator TCP transports
-void unregister_all_tcp_transports()
-{
- atransport *t, *next;
- sdb_mutex_lock(&transport_lock);
- for (t = transport_list.next; t != &transport_list; t = next) {
- next = t->next;
- if (t->type == kTransportLocal && t->sdb_port == 0) {
- t->next->prev = t->prev;
- t->prev->next = next;
- // we cannot call kick_transport when holding transport_lock
- if (!t->kicked)
- {
- t->kicked = 1;
- t->kick(t);
- }
- transport_unref_locked(t);
- }
- }
-
- sdb_mutex_unlock(&transport_lock);
-}
-
-#endif
-
int get_connected_count(transport_type type) /* tizen specific */
{
int cnt = 0;
#include "sdb.h"
#include "strutils.h"
-#if !SDB_HOST
#include "commandline_sdbd.h"
-#endif
#include "utils.h"
#include "sdbd_plugin.h"
#include "plugin.h"
#define fix_endians(p) do {} while (0)
#endif
-#if SDB_HOST
-/* we keep a list of opened transports. The atransport struct knows to which
- * local transport it is connected. The list is used to detect when we're
- * trying to connect twice to a given local transport.
- */
-#define SDB_LOCAL_TRANSPORT_MAX 16
-
-SDB_MUTEX_DEFINE( local_transports_lock );
-
-static atransport* local_transports[ SDB_LOCAL_TRANSPORT_MAX ];
-#endif /* SDB_HOST */
-
SDB_MUTEX_DEFINE( register_noti_lock );
#ifndef _WIN32
static pthread_cond_t noti_cond = PTHREAD_COND_INITIALIZER;
char buf[64];
int fd = -1;
-#if SDB_HOST
- const char *host = getenv("SDBHOST");
- if (host) {
- fd = socket_network_client(host, sdb_port, SOCK_STREAM);
- }
-#endif
if (fd < 0) {
fd = socket_loopback_client(sdb_port, SOCK_STREAM);
}
return -1;
}
-#if SDB_HOST /* tizen specific */
-int get_devicename_from_shdmem(int port, char *device_name)
-{
- char *vms = NULL;
-#ifndef HAVE_WIN32_IPC
- int shm_id;
- void *shared_memory = (void *)0;
-
- shm_id = shmget( (key_t)port-1, 0, 0);
- if (shm_id == -1)
- return -1;
-
- shared_memory = shmat(shm_id, (void *)0, SHM_RDONLY);
-
- if (shared_memory == (void *)-1)
- {
- D("faild to get shdmem key (%d) : %s\n", port, strerror(errno));
- return -1;
- }
-
- vms = strstr((char*)shared_memory, VMS_PATH);
- if (vms != NULL)
- s_strncpy(device_name, vms+strlen(VMS_PATH), DEVICENAME_MAX);
- else
- s_strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX);
-
-#else /* _WIN32*/
- HANDLE hMapFile;
- char s_port[5];
- char* pBuf;
-
- sprintf(s_port, "%d", port-1);
- hMapFile = OpenFileMapping(FILE_MAP_READ, TRUE, s_port);
-
- if(hMapFile == NULL) {
- D("faild to get shdmem key (%ld) : %s\n", port, GetLastError() );
- return -1;
- }
- pBuf = (char*)MapViewOfFile(hMapFile,
- FILE_MAP_READ,
- 0,
- 0,
- 50);
- if (pBuf == NULL) {
- D("Could not map view of file (%ld)\n", GetLastError());
- CloseHandle(hMapFile);
- return -1;
- }
-
- vms = strstr((char*)pBuf, VMS_PATH);
- if (vms != NULL)
- s_strncpy(device_name, vms+strlen(VMS_PATH), DEVICENAME_MAX);
- else
- s_strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX);
- CloseHandle(hMapFile);
-#endif
- D("init device name %s on port %d\n", device_name, port);
-
- return 0;
-}
-
-int read_line(const int fd, char* ptr, size_t maxlen)
-{
- unsigned int n = 0;
- char c[2];
- int rc;
-
- while(n != maxlen) {
- if((rc = sdb_read(fd, c, 1)) != 1)
- return -1; // eof or read err
-
- if(*c == '\n') {
- ptr[n] = 0;
- return n;
- }
- ptr[n++] = *c;
- }
- return -1; // no space
-}
-#endif
-
static void *client_socket_thread(void *x)
{
-#if SDB_HOST
- int port = DEFAULT_SDB_LOCAL_TRANSPORT_PORT;
- int count = SDB_LOCAL_TRANSPORT_MAX;
-
- D("transport: client_socket_thread() starting\n");
-
- /* try to connect to any number of running emulator instances */
- /* this is only done when SDB starts up. later, each new emulator */
- /* will send a message to SDB to indicate that is is starting up */
- for ( ; count > 0; count--, port += 10 ) { /* tizen specific */
- (void) local_connect(port, NULL);
- }
-#endif
return 0;
}
}
/* This is relevant only for SDB daemon running inside the emulator. */
-#if !SDB_HOST
/*
* Redefine open and write for qemu_pipe.h that contains inlined references
* to those routines. We will redifine them back after qemu_pipe.h inclusion.
D("transport: qemu_socket_thread() exiting\n");
return 0;
}
-#endif // !SDB_HOST
#endif
int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen,
if(HOST) {
func = client_socket_thread;
} else {
-#if SDB_HOST
- func = server_socket_thread;
-#else
/* For the sdbd daemon in the system image we need to distinguish
* between the device, and the emulator. */
{
/* Running inside the device: use TCP socket as the transport. */
func = server_socket_thread;
}
-#endif // !SDB_HOST
}
D("transport: local %s init\n", HOST ? "client" : "server");
sdb_shutdown(fd);
sdb_close(fd);
-#if SDB_HOST
- if(HOST) {
- int nn;
- sdb_mutex_lock( &local_transports_lock );
- for (nn = 0; nn < SDB_LOCAL_TRANSPORT_MAX; nn++) {
- if (local_transports[nn] == t) {
- local_transports[nn] = NULL;
- break;
- }
- }
- sdb_mutex_unlock( &local_transports_lock );
- }
-#endif
}
static void remote_close(atransport *t)
sdb_close(t->fd);
}
-
-#if SDB_HOST
-/* Only call this function if you already hold local_transports_lock. */
-atransport* find_emulator_transport_by_sdb_port_locked(int sdb_port)
-{
- int i;
- for (i = 0; i < SDB_LOCAL_TRANSPORT_MAX; i++) {
- if (local_transports[i] && local_transports[i]->sdb_port == sdb_port) {
- return local_transports[i];
- }
- }
- return NULL;
-}
-
-atransport* find_emulator_transport_by_sdb_port(int sdb_port)
-{
- sdb_mutex_lock( &local_transports_lock );
- atransport* result = find_emulator_transport_by_sdb_port_locked(sdb_port);
- sdb_mutex_unlock( &local_transports_lock );
- return result;
-}
-
-/* Only call this function if you already hold local_transports_lock. */
-int get_available_local_transport_index_locked()
-{
- int i;
- for (i = 0; i < SDB_LOCAL_TRANSPORT_MAX; i++) {
- if (local_transports[i] == NULL) {
- return i;
- }
- }
- return -1;
-}
-
-int get_available_local_transport_index()
-{
- sdb_mutex_lock( &local_transports_lock );
- int result = get_available_local_transport_index_locked();
- sdb_mutex_unlock( &local_transports_lock );
- return result;
-}
-#endif
-
int init_socket_transport(atransport *t, int s, int sdb_port, int local)
{
int fail = 0;
t->type = kTransportLocal;
t->sdb_port = 0;
-#if SDB_HOST
- if (HOST && local) {
- sdb_mutex_lock( &local_transports_lock );
- {
- t->sdb_port = sdb_port;
- atransport* existing_transport =
- find_emulator_transport_by_sdb_port_locked(sdb_port);
- int index = get_available_local_transport_index_locked();
- if (existing_transport != NULL) {
- D("local transport for port %d already registered (%p)?\n",
- sdb_port, existing_transport);
- fail = -1;
- } else if (index < 0) {
- // Too many emulators.
- D("cannot register more emulators. Maximum is %d\n",
- SDB_LOCAL_TRANSPORT_MAX);
- fail = -1;
- } else {
- local_transports[index] = t;
- }
- }
- sdb_mutex_unlock( &local_transports_lock );
- }
-#endif
return fail;
}
t->type = kTransportUsb;
t->usb = h;
-#if SDB_HOST
- HOST = 1;
-#else
HOST = 0;
-#endif
-}
-
-#if SDB_HOST
-int is_sdb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol)
-{
- unsigned i;
- for (i = 0; i < vendorIdCount; i++) {
- if (vid == vendorIds[i]) {
- if (usb_class == SDB_CLASS && usb_subclass == SDB_SUBCLASS &&
- usb_protocol == SDB_PROTOCOL) {
- return 1;
- }
-
- return 0;
- }
- }
-
- return 0;
}
-#endif