1 /***********************************************************************************************************************************
2 Protocol Client
3 ***********************************************************************************************************************************/
4 #ifndef PROTOCOL_CLIENT_H
5 #define PROTOCOL_CLIENT_H
6
7 /***********************************************************************************************************************************
8 Message types used by the protocol
9 ***********************************************************************************************************************************/
10 typedef enum
11 {
12 // Data passed between client and server in either direction. This can be used as many times as needed.
13 protocolMessageTypeData = 0,
14
15 // Indicates no more data for the server to return to the client and ends the command
16 protocolMessageTypeDataEnd = 1,
17
18 // Command sent from the client to the server
19 protocolMessageTypeCommand = 2,
20
21 // An error occurred on the server and the command ended abnormally. protocolMessageTypeDataEnd will not be sent to the client.
22 protocolMessageTypeError = 3,
23 } ProtocolMessageType;
24
25 /***********************************************************************************************************************************
26 Object type
27 ***********************************************************************************************************************************/
28 typedef struct ProtocolClient ProtocolClient;
29
30 #include "common/io/read.h"
31 #include "common/io/write.h"
32 #include "common/type/object.h"
33 #include "protocol/command.h"
34
35 /***********************************************************************************************************************************
36 Constants
37 ***********************************************************************************************************************************/
38 #define PROTOCOL_GREETING_NAME "name"
39 STRING_DECLARE(PROTOCOL_GREETING_NAME_STR);
40 #define PROTOCOL_GREETING_SERVICE "service"
41 STRING_DECLARE(PROTOCOL_GREETING_SERVICE_STR);
42 #define PROTOCOL_GREETING_VERSION "version"
43 STRING_DECLARE(PROTOCOL_GREETING_VERSION_STR);
44
45 #define PROTOCOL_COMMAND_EXIT STRID5("exit", 0xa27050)
46 #define PROTOCOL_COMMAND_NOOP STRID5("noop", 0x83dee0)
47
48 /***********************************************************************************************************************************
49 This size should be safe for most pack data without wasting a lot of space. If binary data is being transferred then this size can
50 be added to the expected binary size to account for overhead.
51 ***********************************************************************************************************************************/
52 #define PROTOCOL_PACK_DEFAULT_SIZE 1024
53
54 // Pack large enough for standard data. Note that the buffer will automatically resize when required.
55 __attribute__((always_inline)) static inline PackWrite *
protocolPackNew(void)56 protocolPackNew(void)
57 {
58 return pckWriteNewBuf(bufNew(PROTOCOL_PACK_DEFAULT_SIZE));
59 }
60
61 /***********************************************************************************************************************************
62 Constructors
63 ***********************************************************************************************************************************/
64 ProtocolClient *protocolClientNew(const String *name, const String *service, IoRead *read, IoWrite *write);
65
66 /***********************************************************************************************************************************
67 Getters/Setters
68 ***********************************************************************************************************************************/
69 typedef struct ProtocolClientPub
70 {
71 MemContext *memContext; // Mem context
72 IoRead *read; // Read interface
73 } ProtocolClientPub;
74
75 // Read file descriptor
76 __attribute__((always_inline)) static inline int
protocolClientIoReadFd(ProtocolClient * const this)77 protocolClientIoReadFd(ProtocolClient *const this)
78 {
79 return ioReadFd(THIS_PUB(ProtocolClient)->read);
80 }
81
82 /***********************************************************************************************************************************
83 Functions
84 ***********************************************************************************************************************************/
85 // Execute a command and get the result
86 PackRead *protocolClientExecute(ProtocolClient *this, ProtocolCommand *command, bool resultRequired);
87
88 // Move to a new parent mem context
89 __attribute__((always_inline)) static inline ProtocolClient *
protocolClientMove(ProtocolClient * const this,MemContext * const parentNew)90 protocolClientMove(ProtocolClient *const this, MemContext *const parentNew)
91 {
92 return objMove(this, parentNew);
93 }
94
95 // Send noop to test connection or keep it alive
96 void protocolClientNoOp(ProtocolClient *this);
97
98 // Get data put by the server
99 PackRead *protocolClientDataGet(ProtocolClient *this);
100 void protocolClientDataEndGet(ProtocolClient *this);
101
102 // Put command to the server
103 void protocolClientCommandPut(ProtocolClient *this, ProtocolCommand *command);
104
105 // Put data to the server
106 void protocolClientDataPut(ProtocolClient *this, PackWrite *data);
107
108 /***********************************************************************************************************************************
109 Destructor
110 ***********************************************************************************************************************************/
111 __attribute__((always_inline)) static inline void
protocolClientFree(ProtocolClient * const this)112 protocolClientFree(ProtocolClient *const this)
113 {
114 objFree(this);
115 }
116
117 /***********************************************************************************************************************************
118 Macros for function logging
119 ***********************************************************************************************************************************/
120 String *protocolClientToLog(const ProtocolClient *this);
121
122 #define FUNCTION_LOG_PROTOCOL_CLIENT_TYPE \
123 ProtocolClient *
124 #define FUNCTION_LOG_PROTOCOL_CLIENT_FORMAT(value, buffer, bufferSize) \
125 FUNCTION_LOG_STRING_OBJECT_FORMAT(value, protocolClientToLog, buffer, bufferSize)
126
127 #endif
128