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