Merge commit '260bf01' into tizen-arm
[sdk/emulator/qemu.git] / tizen / src / sdb.c
index e6322d5..b8cdab2 100644 (file)
-/* Copyright (C) 2006-2010 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-*/
-
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else /* !_WIN32 */
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif /* !_WIN32 */
-
-#include "emulator.h"
-#include "net/slirp.h"
-#include "qemu_socket.h"
-#include "sdb.h"
-#include "nbd.h"
-#include "tizen/src/debug_ch.h"
-
-//DEFAULT_DEBUG_CHANNEL(qemu);
-MULTI_DEBUG_CHANNEL(qemu, sdb);
-
-/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
- * easily in QEMU since we use SIGALRM to implement periodic timers
- */
-
-#ifdef _WIN32
-#  define  QSOCKET_CALL(_ret,_cmd)   \
-       do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
-#else
-#  define  QSOCKET_CALL(_ret,_cmd)   \
-       do { \
-               errno = 0; \
-               do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
-       } while (0);
-#endif
-
-#ifdef _WIN32
-
-#include <errno.h>
-
-static int  winsock_error;
-
-#define  WINSOCK_ERRORS_LIST \
-       EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
-EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
-EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
-EE(WSAEINTR,EINTR,"interrupted function call") \
-EE(WSAEALREADY,EALREADY,"operation already in progress") \
-EE(WSAEBADF,EBADF,"bad file descriptor") \
-EE(WSAEACCES,EACCES,"permission denied") \
-EE(WSAEFAULT,EFAULT,"bad address") \
-EE(WSAEINVAL,EINVAL,"invalid argument") \
-EE(WSAEMFILE,EMFILE,"too many opened files") \
-EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
-EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
-EE(WSAEALREADY,EAGAIN,"operation already in progress") \
-EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
-EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
-EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
-EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
-EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
-EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
-EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
-EE(WSAENETDOWN,ENETDOWN,"network is down") \
-EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
-EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
-EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
-EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
-EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
-EE(WSAEISCONN,EISCONN,"socket is already connected") \
-EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
-EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
-EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
-EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
-EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
-EE(WSAELOOP,ELOOP,"cannot translate name") \
-EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
-EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
-EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
-
-typedef struct {
-       int          winsock;
-       int          unix;
-       const char*  string;
-} WinsockError;
-
-static const WinsockError  _winsock_errors[] = {
-#define  EE(w,u,s)   { w, u, s },
-       WINSOCK_ERRORS_LIST
-#undef   EE
-       { -1, -1, NULL }
-};
-
-/* this function reads the latest winsock error code and updates
- * errno to a matching value. It also returns the new value of
- * errno.
- */
-static int _fix_errno( void )
-{
-       const WinsockError*  werr = _winsock_errors;
-       int                  unix = EINVAL;  /* generic error code */
-
-       winsock_error = WSAGetLastError();
-
-       for ( ; werr->string != NULL; werr++ ) {
-               if (werr->winsock == winsock_error) {
-                       unix = werr->unix;
-                       break;
-               }
-       }
-       errno = unix;
-       return -1;
-}
-
-#else
-static int _fix_errno( void )
-{
-       return -1;
-}
-
-#endif
-
-#define  SOCKET_CALL(cmd)  \
-       int  ret; \
-QSOCKET_CALL(ret, (cmd)); \
-if (ret < 0) \
-return _fix_errno(); \
-return ret; \
-
-int socket_send(int  fd, const void*  buf, int  buflen)
-{
-       SOCKET_CALL(send(fd, buf, buflen, 0))
-}
-
-#ifdef _WIN32
-
-       static void
-socket_close_handler( void*  _fd )
-{
-       int   fd = (int)_fd;
-       int   ret;
-       char  buff[64];
-
-       /* we want to drain the read side of the socket before closing it */
-       do {
-               ret = recv( fd, buff, sizeof(buff), 0 );
-       } while (ret < 0 && WSAGetLastError() == WSAEINTR);
-
-       if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
-               return;
-
-       qemu_set_fd_handler( fd, NULL, NULL, NULL );
-       closesocket( fd );
-}
-
-       void
-socket_close( int  fd )
-{
-       int  old_errno = errno;
-
-       shutdown( fd, SD_BOTH );
-       /* we want to drain the socket before closing it */
-       qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
-
-       errno = old_errno;
-}
-
-#else /* !_WIN32 */
-
-#include <unistd.h>
-
-       void
-socket_close( int  fd )
-{
-       int  old_errno = errno;
-
-       shutdown( fd, SHUT_RDWR );
-       close( fd );
-
-       errno = old_errno;
-}
-
-#endif /* !_WIN32 */
-
-int inet_strtoip(const char*  str, uint32_t  *ip)
-{
-       int  comp[4];
-
-       if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
-               return -1;
-
-       if ((unsigned)comp[0] >= 256 ||
-                       (unsigned)comp[1] >= 256 ||
-                       (unsigned)comp[2] >= 256 ||
-                       (unsigned)comp[3] >= 256)
-               return -1;
-
-       *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
-                       (comp[2] << 8)  |  comp[3]);
-       return 0;
-}
-
-int check_port_bind_listen(uint32_t port)
-{
-       struct sockaddr_in addr;
-       int s, opt = 1;
-       int ret = -1;
-       socklen_t addrlen = sizeof(addr);
-       memset(&addr, 0, addrlen);
-
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = INADDR_ANY;
-       addr.sin_port = htons(port);
-
-       if (((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||
-#ifndef _WIN32
-                       (setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&opt, sizeof(int)) < 0) ||
-#endif
-                       (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||
-                       (listen(s, 1) < 0)) {
-
-               /* fail */
-               ret = -1;
-               ERR( "port(%d) listen  fail \n", port);
-       }else{
-               /*fsucess*/
-               ret = 1;
-               INFO( "port(%d) listen  ok \n", port);
-       }
-
-#ifdef _WIN32
-       closesocket(s);
-#else
-       close(s);
-#endif
-
-       return ret;
-}
-
-int get_sdb_base_port(void)
-{
-       int   tries     = 10;
-       int   success   = 0;
-       uint32_t port = 26100;
-
-       if(tizen_base_port == 0){
-
-               for ( ; tries > 0; tries--, port += 10 ) {
-                       if(check_port_bind_listen(port + 1) < 0 )
-                               continue;
-
-                       success = 1;
-                       break;
-               }
-
-               if (!success) {
-                       ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );
-                       exit(1);
-               }
-
-               tizen_base_port = port;
-               INFO( "sdb port is %d \n", tizen_base_port);
-       }
-
-       return tizen_base_port;
-}
-
-void sdb_setup(void)
-{
-       int   tries     = 10;
-       int   success   = 0;
-       uint32_t  guest_ip;
-       char buf[64] = {0,};
-
-       inet_strtoip("10.0.2.16", &guest_ip);
-
-       for ( ; tries > 0; tries--, tizen_base_port += 10 ) {
-               // redir form [tcp:26101:10.0.2.16:26101]
-               sprintf(buf, "tcp:%d:10.0.2.16:26101", tizen_base_port + 1);
-               if(net_slirp_redir((char*)buf) < 0)
-                       continue;
-
-               INFO( "SDBD established on port %d\n", tizen_base_port + 1);
-               success = 1;
-               break;
-       }
-
-       INFO("redirect [%s] success\n", buf);
-       if (!success) {
-               ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );
-               exit(1);
-       }
-
-       INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1);
-
-       /* for sensort */
-       sprintf(buf, "tcp:%d:10.0.2.16:3577", tizen_base_port + SDB_TCP_EMULD_INDEX );
-       if(net_slirp_redir((char*)buf) < 0){
-               ERR( "redirect [%s] fail \n", buf);
-       }else{
-               INFO("redirect [%s] success\n", buf);
-       }
-}
-
-int sdb_loopback_client(int port, int type)
-{
-    struct sockaddr_in addr;
-    int s;
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-    s = socket(AF_INET, type, 0);
-    if(s < 0) return -1;
-
-    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-        close(s);
-        return -1;
-    }
-
-    return s;
-
-}
-
-void notify_sdb_daemon_start(void) {
-    
-    int s;
-    /* 
-     * send a simple message to the SDB host server to tell it we just started.
-     * it should be listening on port 26099.
-     */
-    char *targetname = g_path_get_basename(tizen_target_path);
-    char tmp[MAXPACKETLEN] = { 0 };
-    // when connecting to loopback:26099, do not use tcp_socket_outgoing function
-    // tcp_socket_outgoing may occur "dns name service not known" in case of network unavaliable status.
-    s = sdb_loopback_client(SDB_HOST_PORT, SOCK_STREAM);
-    if (s < 0) {
-        INFO("can not create socket to talk to the SDB server.\n");
-        INFO("SDB server might not be started yet.\n");
-        free(targetname);
-        return;
-    }
-
-    /* length is hex host:emulator:port: -> 0x13 = 20 */
-    sprintf(tmp, "00%2xhost:emulator:%d:%s", 20 + strlen(targetname), tizen_base_port + 1, targetname);
-    INFO("message to send to SDB server: %s\n", tmp);
-    if (socket_send(s, tmp, MAXPACKETLEN) < 0) {
-        ERR( "message sending to SDB server error!\n");
-    }
-
-    if (s >= 0)
-        socket_close(s);
-   
-    free(targetname);
-}
+/* Copyright (C) 2006-2010 The Android Open Source Project\r
+**\r
+** This software is licensed under the terms of the GNU General Public\r
+** License version 2, as published by the Free Software Foundation, and\r
+** may be copied, distributed, and modified under those terms.\r
+**\r
+** This program is distributed in the hope that it will be useful,\r
+** but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+** GNU General Public License for more details.\r
+*/\r
+\r
+\r
+#ifdef _WIN32\r
+#include <windows.h>\r
+#include <winsock2.h>\r
+#include <ws2tcpip.h>\r
+#else /* !_WIN32 */\r
+#include <sys/ioctl.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <netinet/tcp.h>\r
+#include <netdb.h>\r
+#endif /* !_WIN32 */\r
+\r
+#include "emulator.h"\r
+#include "net/slirp.h"\r
+#include "qemu_socket.h"\r
+#include "sdb.h"\r
+#include "nbd.h"\r
+#include "tizen/src/debug_ch.h"\r
+\r
+//DEFAULT_DEBUG_CHANNEL(qemu);\r
+MULTI_DEBUG_CHANNEL(qemu, sdb);\r
+\r
+/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty\r
+ * easily in QEMU since we use SIGALRM to implement periodic timers\r
+ */\r
+\r
+#ifdef _WIN32\r
+#  define  QSOCKET_CALL(_ret,_cmd)   \\r
+       do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )\r
+#else\r
+#  define  QSOCKET_CALL(_ret,_cmd)   \\r
+       do { \\r
+               errno = 0; \\r
+               do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \\r
+       } while (0);\r
+#endif\r
+\r
+#ifdef _WIN32\r
+\r
+#include <errno.h>\r
+\r
+static int  winsock_error;\r
+\r
+#define  WINSOCK_ERRORS_LIST \\r
+       EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \\r
+EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \\r
+EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \\r
+EE(WSAEINTR,EINTR,"interrupted function call") \\r
+EE(WSAEALREADY,EALREADY,"operation already in progress") \\r
+EE(WSAEBADF,EBADF,"bad file descriptor") \\r
+EE(WSAEACCES,EACCES,"permission denied") \\r
+EE(WSAEFAULT,EFAULT,"bad address") \\r
+EE(WSAEINVAL,EINVAL,"invalid argument") \\r
+EE(WSAEMFILE,EMFILE,"too many opened files") \\r
+EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \\r
+EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \\r
+EE(WSAEALREADY,EAGAIN,"operation already in progress") \\r
+EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \\r
+EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \\r
+EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \\r
+EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \\r
+EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \\r
+EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \\r
+EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \\r
+EE(WSAENETDOWN,ENETDOWN,"network is down") \\r
+EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \\r
+EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \\r
+EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \\r
+EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \\r
+EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \\r
+EE(WSAEISCONN,EISCONN,"socket is already connected") \\r
+EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \\r
+EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \\r
+EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \\r
+EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \\r
+EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \\r
+EE(WSAELOOP,ELOOP,"cannot translate name") \\r
+EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \\r
+EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \\r
+EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \\r
+\r
+typedef struct {\r
+       int          winsock;\r
+       int          unix;\r
+       const char*  string;\r
+} WinsockError;\r
+\r
+static const WinsockError  _winsock_errors[] = {\r
+#define  EE(w,u,s)   { w, u, s },\r
+       WINSOCK_ERRORS_LIST\r
+#undef   EE\r
+       { -1, -1, NULL }\r
+};\r
+\r
+/* this function reads the latest winsock error code and updates\r
+ * errno to a matching value. It also returns the new value of\r
+ * errno.\r
+ */\r
+static int _fix_errno( void )\r
+{\r
+       const WinsockError*  werr = _winsock_errors;\r
+       int                  unix = EINVAL;  /* generic error code */\r
+\r
+       winsock_error = WSAGetLastError();\r
+\r
+       for ( ; werr->string != NULL; werr++ ) {\r
+               if (werr->winsock == winsock_error) {\r
+                       unix = werr->unix;\r
+                       break;\r
+               }\r
+       }\r
+       errno = unix;\r
+       return -1;\r
+}\r
+\r
+#else\r
+static int _fix_errno( void )\r
+{\r
+       return -1;\r
+}\r
+\r
+#endif\r
+\r
+#define  SOCKET_CALL(cmd)  \\r
+       int  ret; \\r
+QSOCKET_CALL(ret, (cmd)); \\r
+if (ret < 0) \\r
+return _fix_errno(); \\r
+return ret; \\r
+\r
+int socket_send(int  fd, const void*  buf, int  buflen)\r
+{\r
+       SOCKET_CALL(send(fd, buf, buflen, 0))\r
+}\r
+\r
+#ifdef _WIN32\r
+\r
+       static void\r
+socket_close_handler( void*  _fd )\r
+{\r
+       int   fd = (int)_fd;\r
+       int   ret;\r
+       char  buff[64];\r
+\r
+       /* we want to drain the read side of the socket before closing it */\r
+       do {\r
+               ret = recv( fd, buff, sizeof(buff), 0 );\r
+       } while (ret < 0 && WSAGetLastError() == WSAEINTR);\r
+\r
+       if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)\r
+               return;\r
+\r
+       qemu_set_fd_handler( fd, NULL, NULL, NULL );\r
+       closesocket( fd );\r
+}\r
+\r
+       void\r
+socket_close( int  fd )\r
+{\r
+       int  old_errno = errno;\r
+\r
+       shutdown( fd, SD_BOTH );\r
+       /* we want to drain the socket before closing it */\r
+       qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );\r
+\r
+       errno = old_errno;\r
+}\r
+\r
+#else /* !_WIN32 */\r
+\r
+#include <unistd.h>\r
+\r
+       void\r
+socket_close( int  fd )\r
+{\r
+       int  old_errno = errno;\r
+\r
+       shutdown( fd, SHUT_RDWR );\r
+       close( fd );\r
+\r
+       errno = old_errno;\r
+}\r
+\r
+#endif /* !_WIN32 */\r
+\r
+int inet_strtoip(const char*  str, uint32_t  *ip)\r
+{\r
+       int  comp[4];\r
+\r
+       if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)\r
+               return -1;\r
+\r
+       if ((unsigned)comp[0] >= 256 ||\r
+                       (unsigned)comp[1] >= 256 ||\r
+                       (unsigned)comp[2] >= 256 ||\r
+                       (unsigned)comp[3] >= 256)\r
+               return -1;\r
+\r
+       *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |\r
+                       (comp[2] << 8)  |  comp[3]);\r
+       return 0;\r
+}\r
+\r
+int check_port_bind_listen(uint32_t port)\r
+{\r
+       struct sockaddr_in addr;\r
+       int s, opt = 1;\r
+       int ret = -1;\r
+       socklen_t addrlen = sizeof(addr);\r
+       memset(&addr, 0, addrlen);\r
+\r
+       addr.sin_family = AF_INET;\r
+       addr.sin_addr.s_addr = INADDR_ANY;\r
+       addr.sin_port = htons(port);\r
+\r
+       if (((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||\r
+#ifndef _WIN32\r
+                       (setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&opt, sizeof(int)) < 0) ||\r
+#endif\r
+                       (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||\r
+                       (listen(s, 1) < 0)) {\r
+\r
+               /* fail */\r
+               ret = -1;\r
+               ERR( "port(%d) listen  fail \n", port);\r
+       }else{\r
+               /*fsucess*/\r
+               ret = 1;\r
+               INFO( "port(%d) listen  ok \n", port);\r
+       }\r
+\r
+#ifdef _WIN32\r
+       closesocket(s);\r
+#else\r
+       close(s);\r
+#endif\r
+\r
+       return ret;\r
+}\r
+\r
+int get_sdb_base_port(void)\r
+{\r
+       int   tries     = 10;\r
+       int   success   = 0;\r
+       uint32_t port = 26100;\r
+\r
+       if(tizen_base_port == 0){\r
+\r
+               for ( ; tries > 0; tries--, port += 10 ) {\r
+                       if(check_port_bind_listen(port + 1) < 0 )\r
+                               continue;\r
+\r
+                       success = 1;\r
+                       break;\r
+               }\r
+\r
+               if (!success) {\r
+                       ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );\r
+                       exit(1);\r
+               }\r
+\r
+               tizen_base_port = port;\r
+               INFO( "sdb port is %d \n", tizen_base_port);\r
+       }\r
+\r
+       return tizen_base_port;\r
+}\r
+\r
+void sdb_setup(void)\r
+{\r
+       int   tries     = 10;\r
+       int   success   = 0;\r
+       uint32_t  guest_ip;\r
+       char buf[64] = {0,};\r
+\r
+       inet_strtoip("10.0.2.16", &guest_ip);\r
+\r
+       for ( ; tries > 0; tries--, tizen_base_port += 10 ) {\r
+               // redir form [tcp:26101:10.0.2.16:26101]\r
+               sprintf(buf, "tcp:%d:10.0.2.16:26101", tizen_base_port + 1);\r
+               if(net_slirp_redir((char*)buf) < 0)\r
+                       continue;\r
+\r
+               INFO( "SDBD established on port %d\n", tizen_base_port + 1);\r
+               success = 1;\r
+               break;\r
+       }\r
+\r
+       INFO("redirect [%s] success\n", buf);\r
+       if (!success) {\r
+               ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );\r
+               exit(1);\r
+       }\r
+\r
+       INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1);\r
+\r
+       /* for sensort */\r
+       sprintf(buf, "tcp:%d:10.0.2.16:3577", tizen_base_port + SDB_TCP_EMULD_INDEX );\r
+       if(net_slirp_redir((char*)buf) < 0){\r
+               ERR( "redirect [%s] fail \n", buf);\r
+       }else{\r
+               INFO("redirect [%s] success\n", buf);\r
+       }\r
+}\r
+\r
+int sdb_loopback_client(int port, int type)\r
+{\r
+    struct sockaddr_in addr;\r
+    int s;\r
+\r
+    memset(&addr, 0, sizeof(addr));\r
+    addr.sin_family = AF_INET;\r
+    addr.sin_port = htons(port);\r
+    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\r
+\r
+    s = socket(AF_INET, type, 0);\r
+    if(s < 0) return -1;\r
+\r
+    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\r
+        close(s);\r
+        return -1;\r
+    }\r
+\r
+    return s;\r
+\r
+}\r
+\r
+void notify_sdb_daemon_start(void) {\r
+    \r
+    int s;\r
+    /* \r
+     * send a simple message to the SDB host server to tell it we just started.\r
+     * it should be listening on port 26099.\r
+     */\r
+    char *targetname = g_path_get_basename(tizen_target_path);\r
+    char tmp[MAXPACKETLEN] = { 0 };\r
+    // when connecting to loopback:26099, do not use tcp_socket_outgoing function\r
+    // tcp_socket_outgoing may occur "dns name service not known" in case of network unavaliable status.\r
+    s = sdb_loopback_client(SDB_HOST_PORT, SOCK_STREAM);\r
+    if (s < 0) {\r
+        INFO("can not create socket to talk to the SDB server.\n");\r
+        INFO("SDB server might not be started yet.\n");\r
+        free(targetname);\r
+        return;\r
+    }\r
+\r
+    /* length is hex host:emulator:port: -> 0x13 = 20 */\r
+    sprintf(tmp, "00%2xhost:emulator:%d:%s", 20 + strlen(targetname), tizen_base_port + 1, targetname);\r
+    INFO("message to send to SDB server: %s\n", tmp);\r
+    if (socket_send(s, tmp, MAXPACKETLEN) < 0) {\r
+        ERR( "message sending to SDB server error!\n");\r
+    }\r
+\r
+    if (s >= 0)\r
+        socket_close(s);\r
+   \r
+    free(targetname);\r
+}\r