1d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/*
2d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Copyright (C) 2011 The Android Open Source Project
3d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *
4d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Licensed under the Apache License, Version 2.0 (the "License");
5d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * you may not use this file except in compliance with the License.
6d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * You may obtain a copy of the License at
7d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *
8d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *      http://www.apache.org/licenses/LICENSE-2.0
9d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *
10d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Unless required by applicable law or agreed to in writing, software
11d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * distributed under the License is distributed on an "AS IS" BASIS,
12d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * See the License for the specific language governing permissions and
14d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * limitations under the License.
15d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */
16d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
17d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "qemu-common.h"
18d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/globals.h"  /* for android_hw */
19d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/hw-qemud.h"
20d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/utils/misc.h"
21d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/utils/system.h"
22d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/utils/debug.h"
23d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/adb-server.h"
24d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/adb-qemud.h"
25d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
26d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define  E(...)    derror(__VA_ARGS__)
27d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define  W(...)    dwarning(__VA_ARGS__)
28d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define  D(...)    VERBOSE_PRINT(adbclient,__VA_ARGS__)
29bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine#define  DD(...)   VERBOSE_PRINT(adb,__VA_ARGS__)
30d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define  D_ACTIVE  VERBOSE_CHECK(adbclient)
31bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine#define  DD_ACTIVE VERBOSE_CHECK(adb)
32d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define  QB(b, s)  quote_bytes((const char*)b, (s < 32) ? s : 32)
33d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
34bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine#define SERVICE_NAME        "adb"
35bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine#define DEBUG_SERVICE_NAME  "adb-debug"
3639a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine/* Maximum length of the message that can be received from the guest. */
3739a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine#define ADB_MAX_MSG_LEN     8
38d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Enumerates ADB client state values. */
39d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinetypedef enum AdbClientState {
40d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* Waiting on a connection from ADB host. */
41d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    ADBC_STATE_WAIT_ON_HOST,
42d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* ADB host is connected. Waiting on the transport initialization completion
43d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine     * in the guest. */
44d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    ADBC_STATE_HOST_CONNECTED,
45d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* Connection between ADB host and ADB guest is fully established. */
46d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    ADBC_STATE_CONNECTED,
47d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* ADB host has been disconnected. */
48d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    ADBC_STATE_HOST_DISCONNECTED,
49d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* ADB guest has been disconnected. */
50d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    ADBC_STATE_GUEST_DISCONNECTED,
51d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} AdbClientState;
52d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
53d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* ADB client descriptor. */
54d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinetypedef struct AdbClient AdbClient;
55d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestruct AdbClient {
56d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* Opaque pointer returned from adb_server_register_guest API. */
57d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    void*           opaque;
58d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* QEMUD client pipe for this client. */
59d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    QemudClient*    qemud_client;
60d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* Connection state. */
61d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClientState  state;
6239a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    /* Buffer, collecting accept / stop messages from client. */
6339a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    char            msg_buffer[ADB_MAX_MSG_LEN];
6439a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    /* Current position in message buffer. */
6539a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    int             msg_cur;
66d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine};
67d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
68bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/* ADB debugging client descriptor. */
69bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinetypedef struct AdbDbgClient AdbDbgClient;
70bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinestruct AdbDbgClient {
71bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    /* QEMUD client pipe for this client. */
72bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    QemudClient*    qemud_client;
73bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine};
74bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
75d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/********************************************************************************
76d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *                      ADB host communication.
77d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/
78d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
79d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* A callback that is invoked when the host is connected.
80d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Param:
81d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  opaque - AdbClient instance.
82d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  connection - An opaque pointer that identifies connection with the ADB host.
83d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */
84d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void
85d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_on_host_connected(void* opaque, void* connection)
86d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
87d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* const adb_client = (AdbClient*)opaque;
88d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
89d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (adb_client->state == ADBC_STATE_WAIT_ON_HOST) {
90d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        D("ADB client %p(o=%p) is connected to the host %p",
91d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine          adb_client, adb_client->opaque, connection);
92d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
93d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        /* Bump the state up. */
94d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine         adb_client->state = ADBC_STATE_HOST_CONNECTED;
95d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
96d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        /* Notify the ADB guest that host has been  connected.This will unblock
97d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine         * the guest from a 'read', then guest will register the transport, and
98d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine         * will send 'setart' request, indicating that it is ready to receive
99d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine         * data from the host. */
100d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        qemud_client_send(adb_client->qemud_client, (const uint8_t*)"ok", 2);
101d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    } else {
102d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        D("Unexpected ADB host connection while state is %d", adb_client->state);
103d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
104d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
105d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
106d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* A callback that is invoked when the host gets disconnected.
107d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Param:
108d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  opaque - AdbClient instance.
109d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  connection - An opaque pointer that identifies connection with the ADB host.
110d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */
111d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void
112d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_on_host_disconnect(void* opaque, void* connection)
113d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
114d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* const adb_client = (AdbClient*)opaque;
115d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
116d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    D("ADB client %p(o=%p) is disconnected from the host %p",
117d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine      adb_client, adb_client->opaque, connection);
118d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    adb_client->state = ADBC_STATE_HOST_DISCONNECTED;
119d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
120d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
121d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* A callback that is invoked when the host sends data.
122d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Param:
123d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  opaque - AdbClient instance.
124d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  connection - An opaque pointer that identifies connection with the ADB host.
125d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  buff, size - Buffer containing the host data.
126d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */
127d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void
128d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_on_host_data(void* opaque, void* connection, const void* buff, int size)
129d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
130d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* const adb_client = (AdbClient*)opaque;
131d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    D("ADB client %p(o=%p) received from the host %p %d bytes in %s",
132d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine      adb_client, adb_client->opaque, connection, size, QB(buff, size));
133d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
134d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (adb_client->state == ADBC_STATE_CONNECTED) {
135d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        /* Dispatch data down to the guest. */
136d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        qemud_client_send(adb_client->qemud_client, (const uint8_t*)buff, size);
137d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    } else {
138d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        D("Unexpected data from ADB host %p while client %p(o=%p) is in state %d",
139d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine          connection, adb_client, adb_client->opaque, adb_client->state);
140d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
141d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
142d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
143d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* ADB guest API required for adb_server_register_guest */
144d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic AdbGuestRoutines _adb_client_routines = {
145d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* A callback that is invoked when the host is connected. */
146d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    _adb_on_host_connected,
147d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* A callback that is invoked when the host gets disconnected. */
148d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    _adb_on_host_disconnect,
149d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* A callback that is invoked when the host sends data. */
150d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    _adb_on_host_data,
151d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine};
152d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
153d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/********************************************************************************
154d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *                      ADB guest communication.
155d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/
156d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
157d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Allocates AdbClient instance. */
158d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic AdbClient*
159d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_client_new(void)
160d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
161d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* adb_client;
162d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
163d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    ANEW0(adb_client);
164d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
165d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    return adb_client;
166d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
167d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
168d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Frees AdbClient instance, allocated with _adb_client_new */
169d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void
170d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_client_free(AdbClient* adb_client)
171d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
172d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (adb_client != NULL) {
173d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        free(adb_client);
174d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
175d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
176d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
177d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* A callback that is invoked when ADB guest sends data to the service.
178d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Param:
179d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  opaque - AdbClient instance.
180d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  msg, msglen - Message received from the ADB guest.
181d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *  client - adb QEMUD client.
182d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */
183d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void
184d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
185d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
186d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* const adb_client = (AdbClient*)opaque;
187d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
188d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    D("ADB client %p(o=%p) received from guest %d bytes in %s",
189d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine      adb_client, adb_client->opaque, msglen, QB(msg, msglen));
190d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
19139a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    if (adb_client->state == ADBC_STATE_CONNECTED) {
19239a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine        /* Connection is fully established. Dispatch the message to the host. */
19339a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine        adb_server_on_guest_message(adb_client->opaque, msg, msglen);
19439a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine        return;
19539a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    }
19639a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine
19739a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    /*
19839a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine     * At this point we expect either "accept", or "start" messages. Depending
19939a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine     * on the state of the pipe (although small) these messages could be broken
20039a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine     * into pieces. So, simply checking msg for "accept", or "start" may not
20139a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine     * work. Lets collect them first in internal buffer, and then will see.
20239a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine     */
20339a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine
20439a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    /* Make sure tha message doesn't overflow the buffer. */
20539a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    if ((msglen + adb_client->msg_cur) > sizeof(adb_client->msg_buffer)) {
20639a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine        D("Unexpected message in ADB client.");
20739a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine        adb_client->msg_cur = 0;
20839a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine        return;
20939a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    }
21039a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    /* Append to current message. */
21139a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    memcpy(adb_client->msg_buffer + adb_client->msg_cur, msg, msglen);
21239a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine    adb_client->msg_cur += msglen;
21339a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine
214d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* Properly dispatch the message, depending on the client state. */
215d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    switch (adb_client->state) {
216d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        case ADBC_STATE_WAIT_ON_HOST:
217d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            /* At this state the only message that is allowed is 'accept' */
21839a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine            if (adb_client->msg_cur == 6 &&
21939a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine                !memcmp(adb_client->msg_buffer, "accept", 6)) {
22039a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine                adb_client->msg_cur = 0;
221d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                /* Register ADB guest connection with the ADB server. */
222d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                adb_client->opaque =
223d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    adb_server_register_guest(adb_client, &_adb_client_routines);
224d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                if (adb_client->opaque == NULL) {
225d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    D("Unable to register ADB guest with the ADB server.");
226d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    /* KO the guest. */
227d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    qemud_client_send(adb_client->qemud_client,
228d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                                      (const uint8_t*)"ko", 2);
229d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                }
230d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            } else {
231d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                D("Unexpected guest request while waiting on ADB host to connect.");
232d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            }
233d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            break;
234d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
235d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        case ADBC_STATE_HOST_CONNECTED:
236d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            /* At this state the only message that is allowed is 'start' */
23739a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine            if (adb_client->msg_cur &&
23839a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine                !memcmp(adb_client->msg_buffer, "start", 5)) {
23939a1158197072f846301a8263e2851e892962e64Vladimir Chtchetkine                adb_client->msg_cur = 0;
240d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                adb_client->state = ADBC_STATE_CONNECTED;
241d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                adb_server_complete_connection(adb_client->opaque);
242d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            } else {
243d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                D("Unexpected request while waiting on connection to start.");
244d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            }
245d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            break;
246d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
247d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        default:
248d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            D("Unexpected ADB guest request '%s' while client state is %d.",
249d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine              QB(msg, msglen), adb_client->state);
250d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            break;
251d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
252d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
253d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
254d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* A callback that is invoked when ADB guest disconnects from the service. */
255d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void
256d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_client_close(void* opaque)
257d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
258d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* const adb_client = (AdbClient*)opaque;
259d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
260d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    D("ADB client %p(o=%p) is disconnected from the guest.",
261d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine      adb_client, adb_client->opaque);
262d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    adb_client->state = ADBC_STATE_GUEST_DISCONNECTED;
263d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (adb_client->opaque != NULL) {
264d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        /* Close connection with the host. */
265d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        adb_server_on_guest_closed(adb_client->opaque);
266d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
267d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    _adb_client_free(adb_client);
268d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
269d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
270d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* A callback that is invoked when ADB daemon running inside the guest connects
271d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * to the service.
272d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Client parameters are ignored here. Typically they contain the ADB port number
273d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * which is always 5555 for the device / emulated system.
274d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */
275d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic QemudClient*
276d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_service_connect(void*          opaque,
277d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                     QemudService*  serv,
278d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                     int            channel,
279d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                     const char*    client_param)
280d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
281d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    /* Create new QEMUD client for the connection with ADB daemon. */
282d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    AdbClient* const adb_client = _adb_client_new();
283d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
284d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    D("Connecting ADB guest: '%s'", client_param ? client_param : "<null>");
285d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    adb_client->qemud_client =
286d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        qemud_client_new(serv, channel, client_param, adb_client,
287d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                         _adb_client_recv, _adb_client_close, NULL, NULL);
288d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (adb_client->qemud_client == NULL) {
289d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        D("Unable to create QEMUD client for ADB guest.");
290d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        _adb_client_free(adb_client);
291d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        return NULL;
292d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
293d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
294d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    return adb_client->qemud_client;
295d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
296d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
297d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/********************************************************************************
298bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine *                      Debugging ADB guest communication.
299bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine *******************************************************************************/
300bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
301bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/* Allocates AdbDbgClient instance. */
302bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinestatic AdbDbgClient*
303bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine_adb_dbg_client_new(void)
304bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine{
305bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    AdbDbgClient* adb_dbg_client;
306bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
307bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    ANEW0(adb_dbg_client);
308bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
309bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    return adb_dbg_client;
310bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine}
311bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
312bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/* Frees AdbDbgClient instance, allocated with _adb_dbg_client_new */
313bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinestatic void
314bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine_adb_dbg_client_free(AdbDbgClient* adb_dbg_client)
315bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine{
316bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    if (adb_dbg_client != NULL) {
317bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        free(adb_dbg_client);
318bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    }
319bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine}
320bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
321bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/* A callback that is invoked when ADB debugging guest sends data to the service.
322bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine * Param:
323bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine *  opaque - AdbDbgClient instance.
324bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine *  msg, msglen - Message received from the ADB guest.
325bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine *  client - adb-debug QEMUD client.
326bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine */
327bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinestatic void
328bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine_adb_dbg_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
329bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine{
330bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    if (DD_ACTIVE) {
331bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        fprintf(stderr, "ADB: %s", (const char*)msg);
332bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    }
333bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine}
334bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
335bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/* A callback that is invoked when ADB debugging guest disconnects from the
336bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine * service. */
337bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinestatic void
338bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine_adb_dbg_client_close(void* opaque)
339bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine{
340bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    AdbDbgClient* const adb_dbg_client = (AdbDbgClient*)opaque;
341bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
342bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    DD("ADB debugging client %p is disconnected from the guest.", adb_dbg_client);
343bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    _adb_dbg_client_free(adb_dbg_client);
344bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine}
345bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
346bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/* A callback that is invoked when ADB daemon running inside the guest connects
347bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine * to the debugging service.
348bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine * Client parameters are ignored here.
349bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine */
350bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkinestatic QemudClient*
351bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine_adb_debug_service_connect(void*          opaque,
352bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine                           QemudService*  serv,
353bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine                           int            channel,
354bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine                           const char*    client_param)
355bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine{
356bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    /* Create new QEMUD client for the connection with ADB debugger. */
357bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    AdbDbgClient* const adb_dbg_client = _adb_dbg_client_new();
358bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
359bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    DD("Connecting ADB debugging guest: '%s'",
360bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine       client_param ? client_param : "<null>");
361bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    adb_dbg_client->qemud_client =
362bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        qemud_client_new(serv, channel, client_param, adb_dbg_client,
363bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine                         _adb_dbg_client_recv, _adb_dbg_client_close, NULL, NULL);
364bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    if (adb_dbg_client->qemud_client == NULL) {
365bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        DD("Unable to create QEMUD client for ADB debugging guest.");
366bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        _adb_dbg_client_free(adb_dbg_client);
367bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        return NULL;
368bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    }
369bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
370bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine    return adb_dbg_client->qemud_client;
371bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine}
372bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
373bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine/********************************************************************************
374d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *                      ADB service API.
375d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/
376d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
377d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinevoid
378d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineandroid_adb_service_init(void)
379d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
380d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic int _inited = 0;
381d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
382d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (!adb_server_is_initialized()) {
383d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        return;
384d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
385d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
386d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (!_inited) {
387bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        /* Register main ADB service. */
388d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        QemudService*  serv = qemud_service_register(SERVICE_NAME, 0, NULL,
389d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                                                     _adb_service_connect,
390d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                                                     NULL, NULL);
391d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        if (serv == NULL) {
392d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            derror("%s: Could not register '%s' service",
393d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                   __FUNCTION__, SERVICE_NAME);
394d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            return;
395d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        }
396d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        D("%s: Registered '%s' qemud service", __FUNCTION__, SERVICE_NAME);
397bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine
398bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        /* Register debugging ADB service. */
399bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        serv = qemud_service_register(DEBUG_SERVICE_NAME, 0, NULL,
400bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine                                      _adb_debug_service_connect, NULL, NULL);
401bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        if (serv != NULL) {
402bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine            DD("Registered '%s' qemud service", DEBUG_SERVICE_NAME);
403bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        } else {
404bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine            dwarning("%s: Could not register '%s' service",
405bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine                   __FUNCTION__, DEBUG_SERVICE_NAME);
406bf45fc2a26358b7ec52cb17bb9d6ed67d6483b01Vladimir Chtchetkine        }
407d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
408d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
409