diff options
-rw-r--r-- | include/sysutils/SocketClient.h | 19 | ||||
-rw-r--r-- | libsysutils/src/SocketClient.cpp | 43 |
2 files changed, 57 insertions, 5 deletions
diff --git a/include/sysutils/SocketClient.h b/include/sysutils/SocketClient.h index 65a5b1b..a298f25 100644 --- a/include/sysutils/SocketClient.h +++ b/include/sysutils/SocketClient.h @@ -45,7 +45,18 @@ public: int sendMsg(int code, const char *msg, bool addErrno); int sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum); - //Sending binary data: + // Provides a mechanism to send a response code to the client. The message uses + // the same format as in sendMsg method above. + // Sends the code, a space, and a null character. + int sendCode(int code); + + // Provides a mechanism to send binary data to client. The message uses the + // same format as in sendMsg method above. + // Sends the code, a space, and a null character, followed by 4 bytes of + // big-endian length, and the data. + int sendBinaryMsg(int code, const void *data, int len); + + // Sending binary data: int sendData(const void *data, int len); // Optional reference counting. Reference count starts at 1. If @@ -59,6 +70,12 @@ private: // Send null-terminated C strings int sendMsg(const char *msg); void init(int socket, bool owned, bool useCmdNum); + + // Sending binary data. The caller should use make sure this is protected + // from multiple threads entering simultaneously. + // returns 0 if successful, -1 if there is a 0 byte write and -2 if any other + // error occurred (use errno to get the error) + int sendDataLocked(const void *data, int len); }; typedef android::sysutils::List<SocketClient *> SocketClientCollection; diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp index d9fc48c..d9713a6 100644 --- a/libsysutils/src/SocketClient.cpp +++ b/libsysutils/src/SocketClient.cpp @@ -4,6 +4,7 @@ #include <sys/types.h> #include <pthread.h> #include <string.h> +#include <arpa/inet.h> #define LOG_TAG "SocketClient" #include <cutils/log.h> @@ -78,6 +79,34 @@ int SocketClient::sendMsg(int code, const char *msg, bool addErrno, bool useCmdN return ret; } + +int SocketClient::sendBinaryMsg(int code, const void *data, int len) { + + /* 5 bytes for the code & space + 4 bytes for the len */ + char buf[9]; + /* Write the code */ + snprintf(buf, 5, "%.3d ", code); + /* Write the len */ + uint32_t tmp = htonl(len); + memcpy(buf + 5, &tmp, sizeof(uint32_t)); + + pthread_mutex_lock(&mWriteMutex); + int result = sendDataLocked(buf, sizeof(buf)); + if (result == 0 && len > 0) { + result = sendDataLocked(data, len); + } + pthread_mutex_unlock(&mWriteMutex); + + return result; +} + +// Sends the code (c-string null-terminated). +int SocketClient::sendCode(int code) { + char buf[5]; + snprintf(buf, 5, "%.3d ", code); + return sendData(buf, 5); +} + int SocketClient::sendMsg(const char *msg) { if (mSocket < 0) { errno = EHOSTUNREACH; @@ -92,7 +121,16 @@ int SocketClient::sendMsg(const char *msg) { return 0; } -int SocketClient::sendData(const void* data, int len) { +int SocketClient::sendData(const void *data, int len) { + + pthread_mutex_lock(&mWriteMutex); + int rc = sendDataLocked(data, len); + pthread_mutex_unlock(&mWriteMutex); + + return rc; +} + +int SocketClient::sendDataLocked(const void *data, int len) { int rc = 0; const char *p = (const char*) data; int brtw = len; @@ -101,7 +139,6 @@ int SocketClient::sendData(const void* data, int len) { return 0; } - pthread_mutex_lock(&mWriteMutex); while (brtw > 0) { rc = write(mSocket, p, brtw); if (rc > 0) { @@ -113,7 +150,6 @@ int SocketClient::sendData(const void* data, int len) { if (rc < 0 && errno == EINTR) continue; - pthread_mutex_unlock(&mWriteMutex); if (rc == 0) { SLOGW("0 length write :("); errno = EIO; @@ -122,7 +158,6 @@ int SocketClient::sendData(const void* data, int len) { } return -1; } - pthread_mutex_unlock(&mWriteMutex); return 0; } |