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