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