gltrace_transport.cpp revision 93a826f78f6313db791e6fc880439189897651b3
10469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/*
20469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Copyright 2011, The Android Open Source Project
30469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
40469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Licensed under the Apache License, Version 2.0 (the "License");
50469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * you may not use this file except in compliance with the License.
60469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * You may obtain a copy of the License at
70469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
80469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *     http://www.apache.org/licenses/LICENSE-2.0
90469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Unless required by applicable law or agreed to in writing, software
110469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * distributed under the License is distributed on an "AS IS" BASIS,
120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * See the License for the specific language governing permissions and
140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * limitations under the License.
150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy */
160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <stdlib.h>
180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <unistd.h>
190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <sys/socket.h>
210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <netinet/in.h>
220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <arpa/inet.h>
230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <cutils/log.h>
250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_transport.h"
270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android {
290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace gltrace {
300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
3193a826f78f6313db791e6fc880439189897651b3Siva Velusamyint acceptClientConnection(int serverPort) {
3293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    int serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
3393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (serverSocket < 0) {
340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        LOGE("Error (%d) while creating socket. Check if app has network permissions.",
3593a826f78f6313db791e6fc880439189897651b3Siva Velusamy                                                                            serverSocket);
3693a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return -1;
370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    struct sockaddr_in server, client;
400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    server.sin_family = AF_INET;
420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    server.sin_addr.s_addr = htonl(INADDR_ANY);
4393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    server.sin_port = htons(serverPort);
440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    socklen_t sockaddr_len = sizeof(sockaddr_in);
4693a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (bind(serverSocket, (struct sockaddr *) &server, sizeof(server)) < 0) {
4793a826f78f6313db791e6fc880439189897651b3Siva Velusamy        close(serverSocket);
480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        LOGE("Failed to bind the server socket");
4993a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return -1;
500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
5293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (listen(serverSocket, 1) < 0) {
5393a826f78f6313db791e6fc880439189897651b3Siva Velusamy        close(serverSocket);
540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        LOGE("Failed to listen on server socket");
5593a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return -1;
560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
5893a826f78f6313db791e6fc880439189897651b3Siva Velusamy    ALOGD("gltrace::waitForClientConnection: server listening @ port %d", serverPort);
590469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
6093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    int clientSocket = accept(serverSocket, (struct sockaddr *)&client, &sockaddr_len);
6193a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (clientSocket < 0) {
6293a826f78f6313db791e6fc880439189897651b3Siva Velusamy        close(serverSocket);
630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        LOGE("Failed to accept client connection");
6493a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return -1;
650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
6793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    ALOGD("gltrace::waitForClientConnection: client connected: %s", inet_ntoa(client.sin_addr));
6893a826f78f6313db791e6fc880439189897651b3Siva Velusamy
6993a826f78f6313db791e6fc880439189897651b3Siva Velusamy    // do not accept any more incoming connections
7093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    close(serverSocket);
7193a826f78f6313db791e6fc880439189897651b3Siva Velusamy
7293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return clientSocket;
7393a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
7493a826f78f6313db791e6fc880439189897651b3Siva Velusamy
7593a826f78f6313db791e6fc880439189897651b3Siva VelusamyTCPStream::TCPStream(int socket) {
7693a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mSocket = socket;
7793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    pthread_mutex_init(&mSocketWriteMutex, NULL);
780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
8093a826f78f6313db791e6fc880439189897651b3Siva VelusamyTCPStream::~TCPStream() {
8193a826f78f6313db791e6fc880439189897651b3Siva Velusamy    pthread_mutex_destroy(&mSocketWriteMutex);
8293a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
8393a826f78f6313db791e6fc880439189897651b3Siva Velusamy
8493a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid TCPStream::closeStream() {
8593a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (mSocket > 0) {
8693a826f78f6313db791e6fc880439189897651b3Siva Velusamy        close(mSocket);
8793a826f78f6313db791e6fc880439189897651b3Siva Velusamy        mSocket = 0;
880469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
9193a826f78f6313db791e6fc880439189897651b3Siva Velusamyint TCPStream::send(void *buf, size_t len) {
9293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (mSocket <= 0) {
9393a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return -1;
940469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
9693a826f78f6313db791e6fc880439189897651b3Siva Velusamy    pthread_mutex_lock(&mSocketWriteMutex);
9793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    int n = write(mSocket, buf, len);
9893a826f78f6313db791e6fc880439189897651b3Siva Velusamy    pthread_mutex_unlock(&mSocketWriteMutex);
9993a826f78f6313db791e6fc880439189897651b3Siva Velusamy
10093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return n;
10193a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
1020469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
10393a826f78f6313db791e6fc880439189897651b3Siva Velusamyint TCPStream::receive(void *data, size_t len) {
10493a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (mSocket <= 0) {
10593a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return -1;
1060469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1070469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
10893a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return read(mSocket, data, len);
10993a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
11093a826f78f6313db791e6fc880439189897651b3Siva Velusamy
11193a826f78f6313db791e6fc880439189897651b3Siva VelusamyBufferedOutputStream::BufferedOutputStream(TCPStream *stream, size_t bufferSize) {
11293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mStream = stream;
11393a826f78f6313db791e6fc880439189897651b3Siva Velusamy
11493a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mBufferSize = bufferSize;
11593a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mStringBuffer = "";
11693a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mStringBuffer.reserve(bufferSize);
11793a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
11893a826f78f6313db791e6fc880439189897651b3Siva Velusamy
11993a826f78f6313db791e6fc880439189897651b3Siva Velusamyint BufferedOutputStream::flush() {
12093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (mStringBuffer.size() == 0) {
12193a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return 0;
12293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    }
12393a826f78f6313db791e6fc880439189897651b3Siva Velusamy
12493a826f78f6313db791e6fc880439189897651b3Siva Velusamy    int n = mStream->send((void *)mStringBuffer.data(), mStringBuffer.size());
12593a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mStringBuffer.clear();
12693a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return n;
12793a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
12893a826f78f6313db791e6fc880439189897651b3Siva Velusamy
12993a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid BufferedOutputStream::enqueueMessage(GLMessage *msg) {
13093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    const uint32_t len = msg->ByteSize();
13193a826f78f6313db791e6fc880439189897651b3Siva Velusamy
13293a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mStringBuffer.append((const char *)&len, sizeof(len));    // append header
13393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    msg->AppendToString(&mStringBuffer);                      // append message
13493a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
13593a826f78f6313db791e6fc880439189897651b3Siva Velusamy
13693a826f78f6313db791e6fc880439189897651b3Siva Velusamyint BufferedOutputStream::send(GLMessage *msg) {
13793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    enqueueMessage(msg);
13893a826f78f6313db791e6fc880439189897651b3Siva Velusamy
13993a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (mStringBuffer.size() > mBufferSize) {
14093a826f78f6313db791e6fc880439189897651b3Siva Velusamy        return flush();
1410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
14293a826f78f6313db791e6fc880439189897651b3Siva Velusamy
14393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return 0;
1440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy};  // namespace gltrace
1470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy};  // namespace android
148