1fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#ifndef _SOCKET_CLIENT_H
2fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#define _SOCKET_CLIENT_H
3fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
4b7286aa02e1e554a1ef21a957fabe593f05c1260Mathias Agopian#include "List.h"
5fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
6fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <pthread.h>
78702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt#include <cutils/atomic.h>
830abb7234de2a9caa1add4b00a189436f0b24560Kenny Root#include <sys/types.h>
9a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn#include <sys/uio.h>
10fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
11fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatclass SocketClient {
12fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    int             mSocket;
134520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang    bool            mSocketOwned;
14fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    pthread_mutex_t mWriteMutex;
15fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
16a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // Peer process ID
1730abb7234de2a9caa1add4b00a189436f0b24560Kenny Root    pid_t mPid;
1830abb7234de2a9caa1add4b00a189436f0b24560Kenny Root
19a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // Peer user ID
2030abb7234de2a9caa1add4b00a189436f0b24560Kenny Root    uid_t mUid;
2130abb7234de2a9caa1add4b00a189436f0b24560Kenny Root
22a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // Peer group ID
2330abb7234de2a9caa1add4b00a189436f0b24560Kenny Root    gid_t mGid;
2430abb7234de2a9caa1add4b00a189436f0b24560Kenny Root
25a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // Reference count (starts at 1)
26648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    pthread_mutex_t mRefCountMutex;
27648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    int mRefCount;
28648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick
298702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt    int mCmdNum;
308702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt
318702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt    bool mUseCmdNum;
328702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt
33fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatpublic:
344520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang    SocketClient(int sock, bool owned);
358702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt    SocketClient(int sock, bool owned, bool useCmdNum);
364520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang    virtual ~SocketClient();
37fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
38fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    int getSocket() { return mSocket; }
3930abb7234de2a9caa1add4b00a189436f0b24560Kenny Root    pid_t getPid() const { return mPid; }
4030abb7234de2a9caa1add4b00a189436f0b24560Kenny Root    uid_t getUid() const { return mUid; }
4130abb7234de2a9caa1add4b00a189436f0b24560Kenny Root    gid_t getGid() const { return mGid; }
42a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    void setCmdNum(int cmdNum) {
43a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn        android_atomic_release_store(cmdNum, &mCmdNum);
44a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    }
458702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt    int getCmdNum() { return mCmdNum; }
46fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
478c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick    // Send null-terminated C strings:
48db017545796747115b8797f03e662b0f398a7c7bSan Mehat    int sendMsg(int code, const char *msg, bool addErrno);
498702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt    int sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum);
50a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    int sendMsg(const char *msg);
518c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick
527599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt    // Provides a mechanism to send a response code to the client.
537599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt    // Sends the code and a null character.
547bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun    int sendCode(int code);
557bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun
567599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt    // Provides a mechanism to send binary data to client.
577599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt    // Sends the code and a null character, followed by 4 bytes of
587bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun    // big-endian length, and the data.
597bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun    int sendBinaryMsg(int code, const void *data, int len);
607bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun
617bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun    // Sending binary data:
628c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick    int sendData(const void *data, int len);
63a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // iovec contents not preserved through call
64a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    int sendDatav(struct iovec *iov, int iovcnt);
65648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick
66648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    // Optional reference counting.  Reference count starts at 1.  If
67648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    // it's decremented to 0, it deletes itself.
68648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    // SocketListener creates a SocketClient (at refcount 1) and calls
69648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    // decRef() when it's done with the client.
70648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick    void incRef();
714be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick    bool decRef(); // returns true at 0 (but note: SocketClient already deleted)
728702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt
73a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // return a new string in quotes with '\\' and '\"' escaped for "my arg"
74a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // transmissions
75594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt    static char *quoteArg(const char *arg);
76594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt
778702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwaltprivate:
788702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt    void init(int socket, bool owned, bool useCmdNum);
797bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun
80a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // Sending binary data. The caller should make sure this is protected
817bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun    // from multiple threads entering simultaneously.
82a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // returns 0 if successful, -1 if there is a 0 byte write or if any
83a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    // other error occurred (use errno to get the error)
84a6e965578e44f8ae5f98de822ba5decec381d5fcMark Salyzyn    int sendDataLockedv(struct iovec *iov, int iovcnt);
85fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat};
86fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
87b7286aa02e1e554a1ef21a957fabe593f05c1260Mathias Agopiantypedef android::sysutils::List<SocketClient *> SocketClientCollection;
88fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#endif
89