/* ** Copyright 2011, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include #include #include #include #include "header.h" namespace android { char sockBuff [BUFFSIZE]; int serverSock = -1, clientSock = -1; void StopDebugServer(); static void Die(const char * msg) { LOGD("\n*\n*\n* GLESv2_dbg: Die: %s \n*\n*", msg); StopDebugServer(); exit(1); } void StartDebugServer() { LOGD("GLESv2_dbg: StartDebugServer"); if (serverSock >= 0) return; LOGD("GLESv2_dbg: StartDebugServer create socket"); struct sockaddr_in server = {}, client = {}; /* Create the TCP socket */ if ((serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { Die("Failed to create socket"); } /* Construct the server sockaddr_in structure */ server.sin_family = AF_INET; /* Internet/IP */ server.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */ server.sin_port = htons(5039); /* server port */ /* Bind the server socket */ socklen_t sizeofSockaddr_in = sizeof(sockaddr_in); if (bind(serverSock, (struct sockaddr *) &server, sizeof(server)) < 0) { Die("Failed to bind the server socket"); } /* Listen on the server socket */ if (listen(serverSock, 1) < 0) { Die("Failed to listen on server socket"); } LOGD("server started on %d \n", server.sin_port); /* Wait for client connection */ if ((clientSock = accept(serverSock, (struct sockaddr *) &client, &sizeofSockaddr_in)) < 0) { Die("Failed to accept client connection"); } LOGD("Client connected: %s\n", inet_ntoa(client.sin_addr)); // fcntl(clientSock, F_SETFL, O_NONBLOCK); GLESv2Debugger::Message msg, cmd; msg.set_context_id(0); msg.set_function(GLESv2Debugger::Message_Function_ACK); msg.set_has_next_message(false); msg.set_expect_response(true); Send(msg, cmd); } void StopDebugServer() { LOGD("GLESv2_dbg: StopDebugServer"); if (clientSock > 0) { close(clientSock); clientSock = -1; } if (serverSock > 0) { close(serverSock); serverSock = -1; } } void Send(const GLESv2Debugger::Message & msg, GLESv2Debugger::Message & cmd) { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex); // TODO: this is just temporary static std::string str; const_cast(msg).set_context_id(pthread_self()); msg.SerializeToString(&str); unsigned len = str.length(); len = htonl(len); int sent = -1; sent = send(clientSock, (const char *)&len, sizeof(len), 0); if (sent != sizeof(len)) { LOGD("actual sent=%d expected=%d clientSock=%d", sent, sizeof(len), clientSock); Die("Failed to send message length"); } sent = send(clientSock, str.c_str(), str.length(), 0); if (sent != str.length()) { LOGD("actual sent=%d expected=%d clientSock=%d", sent, str.length(), clientSock); Die("Failed to send message"); } if (!msg.expect_response()) { pthread_mutex_unlock(&mutex); return; } int received = recv(clientSock, sockBuff, 4, MSG_WAITALL); if (received < 0) Die("Failed to receive response"); else if (4 != received) { LOGD("received %dB: %.8X", received, *(unsigned *)sockBuff); Die("Received length mismatch, expected 4"); } len = ntohl(*(unsigned *)sockBuff); static void * buffer = NULL; static unsigned bufferSize = 0; if (bufferSize < len) { buffer = realloc(buffer, len); ASSERT(buffer); bufferSize = len; } received = recv(clientSock, buffer, len, MSG_WAITALL); if (received < 0) Die("Failed to receive response"); else if (len != received) Die("Received length mismatch"); cmd.Clear(); cmd.ParseFromArray(buffer, len); //LOGD("Message sent tid=%lu len=%d", pthread_self(), str.length()); pthread_mutex_unlock(&mutex); } }; // namespace android {