10f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines/* 20f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Copyright (C) 2009 The Android Open Source Project 30f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * 40f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 50f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * you may not use this file except in compliance with the License. 60f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * You may obtain a copy of the License at 70f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * 80f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 90f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * 100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Unless required by applicable law or agreed to in writing, software 110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * See the License for the specific language governing permissions and 140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * limitations under the License. 150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines */ 160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsContext.h" 180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsThreadIO.h" 190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsgApiStructs.h" 200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <unistd.h> 220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <sys/types.h> 230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <sys/socket.h> 240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <fcntl.h> 260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <poll.h> 270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesusing namespace android; 300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesusing namespace android::renderscript; 310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen HinesThreadIO::ThreadIO() { 330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mRunning = true; 340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mPureFifo = false; 350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mMaxInlineSize = 1024; 360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen HinesThreadIO::~ThreadIO() { 390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 400f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 410f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::init() { 420f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToClient.init(); 430f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.init(); 440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::shutdown() { 470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mRunning = false; 480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.shutdown(); 490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) { 520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("coreHeader %i %i", cmdID, dataLen); 530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0]; 540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines hdr->bytes = dataLen; 550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines hdr->cmdID = cmdID; 560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mSendLen = dataLen + sizeof(CoreCmdHeader); 570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //mToCoreSocket.writeAsync(&hdr, sizeof(hdr)); 580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("coreHeader ret "); 590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines return &mSendBuffer[sizeof(CoreCmdHeader)]; 600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::coreCommit() { 630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.writeAsync(&mSendBuffer, mSendLen); 640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::clientShutdown() { 670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToClient.shutdown(); 680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::coreWrite(const void *data, size_t len) { 710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGV("core write %p %i", data, (int)len); 720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.writeAsync(data, len, true); 730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::coreRead(void *data, size_t len) { 760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGV("core read %p %i", data, (int)len); 770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.read(data, len); 780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::coreSetReturn(const void *data, size_t dataLen) { 810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines uint32_t buf; 820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (data == NULL) { 830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines data = &buf; 840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines dataLen = sizeof(buf); 850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.readReturn(data, dataLen); 880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 900f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::coreGetReturn(void *data, size_t dataLen) { 910f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines uint32_t buf; 920f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (data == NULL) { 930f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines data = &buf; 940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines dataLen = sizeof(buf); 950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 970f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.writeWaitReturn(data, dataLen); 980f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 990f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) { 1010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //mToCore.setTimeoutCallback(cb, dat, timeout); 1020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 1030f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1040f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ThreadIO::playCoreCommands(Context *con, int waitFd) { 1050f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines bool ret = false; 1060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines const bool isLocal = !isPureFifo(); 1070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1080f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines uint8_t buf[2 * 1024]; 1090f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0]; 1100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines const void * data = (const void *)&buf[sizeof(CoreCmdHeader)]; 1110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines struct pollfd p[2]; 1130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines p[0].fd = mToCore.getReadFd(); 1140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines p[0].events = POLLIN; 1150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines p[0].revents = 0; 1160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines p[1].fd = waitFd; 1170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines p[1].events = POLLIN; 1180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines p[1].revents = 0; 1190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines int pollCount = 1; 1200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (waitFd >= 0) { 1210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines pollCount = 2; 1220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (con->props.mLogTimes) { 1250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines con->timerSet(Context::RS_TIMER_IDLE); 1260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines int waitTime = -1; 1290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines while (mRunning) { 1300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines int pr = poll(p, pollCount, waitTime); 1310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (pr <= 0) { 1320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines break; 1330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (p[0].revents) { 1360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines size_t r = 0; 1370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (isLocal) { 1380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); 1390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); 1400f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (r != sizeof(CoreCmdHeader)) { 1410f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines // exception or timeout occurred. 1420f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines break; 1430f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } else { 1450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines r = mToCore.read((void *)&cmd->cmdID, sizeof(cmd->cmdID)); 1460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines ret = true; 1500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (con->props.mLogTimes) { 1510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines con->timerSet(Context::RS_TIMER_INTERNAL); 1520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes); 1540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { 1560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); 1570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID); 1580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (isLocal) { 1610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); 1620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } else { 1630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines gPlaybackRemoteFuncs[cmd->cmdID](con, this); 1640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (con->props.mLogTimes) { 1670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines con->timerSet(Context::RS_TIMER_IDLE); 1680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (waitFd < 0) { 1710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines // If we don't have a secondary wait object we should stop blocking now 1720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines // that at least one command has been processed. 1730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines waitTime = 0; 1740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (p[1].revents && !p[0].revents) { 1780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines // We want to finish processing fifo events before processing the vsync. 1790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines // Otherwise we can end up falling behind and having tremendous lag. 1800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines break; 1810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 1830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines return ret; 1840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 1850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen HinesRsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) { 1870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("getClientHeader"); 1880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader)); 1890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1900f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines receiveLen[0] = mLastClientHeader.bytes; 1910f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines usrID[0] = mLastClientHeader.userID; 1920f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]); 1930f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines return (RsMessageToClientType)mLastClientHeader.cmdID; 1940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 1950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 1960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen HinesRsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen, 1970f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines uint32_t *usrID, size_t bufferLen) { 1980f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("getClientPayload"); 1990f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines receiveLen[0] = mLastClientHeader.bytes; 2000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines usrID[0] = mLastClientHeader.userID; 2010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (bufferLen < mLastClientHeader.bytes) { 2020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines return RS_MESSAGE_TO_CLIENT_RESIZE; 2030f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 2040f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (receiveLen[0]) { 2050f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToClient.read(data, receiveLen[0]); 2060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 2070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("getClientPayload x"); 2080f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines return (RsMessageToClientType)mLastClientHeader.cmdID; 2090f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 2100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 2110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesbool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data, 2120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines size_t dataLen, bool waitForSpace) { 2130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 2140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen); 2150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines ClientCmdHeader hdr; 2160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines hdr.bytes = dataLen; 2170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines hdr.cmdID = cmdID; 2180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines hdr.userID = usrID; 2190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 2200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToClient.writeAsync(&hdr, sizeof(hdr)); 2210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines if (dataLen) { 2220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines mToClient.writeAsync(data, dataLen); 2230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines } 2240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 2250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines //ALOGE("sendToClient x"); 2260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines return true; 2270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines} 2280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines 229