cis_config
ClientComm.h
1 
2 #ifndef CISCLIENTCOMM_H_
3 #define CISCLIENTCOMM_H_
4 
5 #include <../tools.h>
6 #include <CommBase.h>
7 #include <DefaultComm.h>
8 #include <comm_header.h>
9 
10 #ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
11 extern "C" {
12 #endif
13 
14 // Handle is send address
15 // Info is response
16 static unsigned _client_rand_seeded = 0;
17 
23 static inline
24 int new_client_address(comm_t *comm) {
25  if (!(_client_rand_seeded)) {
26  srand(ptr2seed(comm));
27  _client_rand_seeded = 1;
28  }
29  comm->type = _default_comm;
30  return new_default_address(comm);
31 };
32 
38 static inline
39 int init_client_comm(comm_t *comm) {
40  int ret = 0;
41  if (!(_client_rand_seeded)) {
42  srand(ptr2seed(comm));
43  _client_rand_seeded = 1;
44  }
45  // Called to create temp comm for send/recv
46  if ((strlen(comm->name) == 0) && (strlen(comm->address) > 0)) {
47  comm->type = _default_comm;
48  return init_default_comm(comm);
49  }
50  // Called to initialize/create client comm
51  char *seri_out = (char*)malloc(strlen(comm->direction) + 1);
52  if (seri_out == NULL) {
53  cislog_error("init_client_comm: Failed to malloc output serializer.");
54  return -1;
55  }
56  strcpy(seri_out, comm->direction);
57  comm_t *handle;
58  if (strlen(comm->name) == 0) {
59  handle = new_comm_base(comm->address, "send", _default_comm, (void*)seri_out);
60  sprintf(handle->name, "client_request.%s", comm->address);
61  } else {
62  handle = init_comm_base(comm->name, "send", _default_comm, (void*)seri_out);
63  }
64  ret = init_default_comm(handle);
65  strcpy(comm->address, handle->address);
66  comm->handle = (void*)handle;
67  // Keep track of response comms
68  int *ncomm = (int*)malloc(sizeof(int));
69  if (ncomm == NULL) {
70  cislog_error("init_client_comm: Failed to malloc ncomm.");
71  return -1;
72  }
73  ncomm[0] = 0;
74  handle->info = (void*)ncomm;
75  strcpy(comm->direction, "send");
76  comm->always_send_header = 1;
77  comm_t ***info = (comm_t***)malloc(sizeof(comm_t**));
78  if (info == NULL) {
79  cislog_error("init_client_comm: Failed to malloc info.");
80  return -1;
81  }
82  info[0] = NULL;
83  comm->info = (void*)info;
84  return ret;
85 };
86 
87 static inline
88 int get_client_response_count(const comm_t x) {
89  comm_t *handle = (comm_t*)(x.handle);
90  int out = 0;
91  if (handle != NULL) {
92  out = ((int*)(handle->info))[0];
93  }
94  return out;
95 };
96 
97 static inline
98 void set_client_response_count(const comm_t x, const int new_val) {
99  comm_t *handle = (comm_t*)(x.handle);
100  if (handle != NULL) {
101  int *count = (int*)(handle->info);
102  count[0] = new_val;
103  }
104 };
105 
106 static inline
107 void inc_client_response_count(const comm_t x) {
108  comm_t *handle = (comm_t*)(x.handle);
109  if (handle != NULL) {
110  int *count = (int*)(handle->info);
111  count[0]++;
112  }
113 };
114 
115 static inline
116 void dec_client_response_count(const comm_t x) {
117  comm_t *handle = (comm_t*)(x.handle);
118  if (handle != NULL) {
119  int *count = (int*)(handle->info);
120  count[0]--;
121  }
122 };
123 
124 static inline
125 void free_client_response_count(comm_t *x) {
126  comm_t *handle = (comm_t*)(x->handle);
127  if (handle != NULL) {
128  int *count = (int*)(handle->info);
129  free(count);
130  handle->info = NULL;
131  }
132 };
133 
139 static inline
140 int free_client_comm(comm_t *x) {
141  if (x->info != NULL) {
142  comm_t ***info = (comm_t***)(x->info);
143  if (info[0] != NULL) {
144  int ncomm = get_client_response_count(*x);
145  int i;
146  for (i = 0; i < ncomm; i++) {
147  if (info[0][i] != NULL) {
148  free_default_comm(info[0][i]);
149  free_comm_base(info[0][i]);
150  free(info[0][i]);
151  }
152  }
153  free(*info);
154  info[0] = NULL;
155  }
156  free(info);
157  x->info = NULL;
158  }
159  free_client_response_count(x);
160  if (x->handle != NULL) {
161  comm_t *handle = (comm_t*)(x->handle);
162  free_default_comm(handle);
163  free_comm_base(handle);
164  free(x->handle);
165  x->handle = NULL;
166  }
167  return 0;
168 };
169 
175 static inline
176 int client_comm_nmsg(const comm_t x) {
177  comm_t *handle = (comm_t*)(x.handle);
178  int ret = default_comm_nmsg(*handle);
179  return ret;
180 };
181 
189 static inline
190 comm_head_t client_response_header(comm_t x, comm_head_t head) {
191  // Initialize new comm
192  int ncomm = get_client_response_count(x);
193  comm_t ***res_comm = (comm_t***)(x.info);
194  res_comm[0] = (comm_t**)realloc(res_comm[0], sizeof(comm_t*)*(ncomm + 1));
195  if (res_comm[0] == NULL) {
196  cislog_error("client_response_header: Failed to realloc response comm.");
197  head.valid = 0;
198  return head;
199  }
200  char *seri_copy = (char*)malloc(strlen((char*)(x.serializer->info)) + 1);
201  if (seri_copy == NULL) {
202  cislog_error("client_response_header: Failed to malloc copy of serializer info.");
203  head.valid = 0;
204  return head;
205  }
206  strcpy(seri_copy, (char*)(x.serializer->info));
207  res_comm[0][ncomm] = new_comm_base(NULL, "recv", _default_comm, seri_copy);
208  int ret = new_default_address(res_comm[0][ncomm]);
209  if (ret < 0) {
210  cislog_error("client_response_header(%s): could not create response comm", x.name);
211  head.valid = 0;
212  return head;
213  }
214  res_comm[0][ncomm]->sent_eof[0] = 1;
215  res_comm[0][ncomm]->recv_eof[0] = 1;
216  inc_client_response_count(x);
217  ncomm = get_client_response_count(x);
218  cislog_debug("client_response_header(%s): Created response comm number %d",
219  x.name, ncomm);
220  // Add address & request ID to header
221  strcpy(head.response_address, res_comm[0][ncomm - 1]->address);
222  sprintf(head.request_id, "%d", rand());
223  cislog_debug("client_response_header(%s): response_address = %s, request_id = %s",
224  x.name, head.response_address, head.request_id);
225  return head;
226 };
227 
235 static inline
236 int client_comm_send(comm_t x, const char *data, const size_t len) {
237  int ret;
238  cislog_debug("client_comm_send(%s): %d bytes", x.name, len);
239  if (x.handle == NULL) {
240  cislog_error("client_comm_send(%s): no request comm registered", x.name);
241  return -1;
242  }
243  comm_t *req_comm = (comm_t*)(x.handle);
244  ret = default_comm_send(*req_comm, data, len);
245  if (is_eof(data)) {
246  req_comm->sent_eof[0] = 1;
247  }
248  return ret;
249 };
250 
262 static inline
263 int client_comm_recv(comm_t x, char **data, const size_t len, const int allow_realloc) {
264  cislog_debug("client_comm_recv(%s)", x.name);
265  if ((x.info == NULL) || (get_client_response_count(x) == 0)) {
266  cislog_error("client_comm_recv(%s): no response comm registered", x.name);
267  return -1;
268  }
269  comm_t ***res_comm = (comm_t***)(x.info);
270  int ret = default_comm_recv(res_comm[0][0][0], data, len, allow_realloc);
271  if (ret < 0) {
272  cislog_error("client_comm_recv(%s): default_comm_recv returned %d",
273  x.name, ret);
274  return ret;
275  }
276  // Close response comm and decrement count of response comms
277  cislog_debug("client_comm_recv(%s): default_comm_recv returned %d",
278  x.name, ret);
279  free_default_comm(res_comm[0][0]);
280  free_comm_base(res_comm[0][0]);
281  free(res_comm[0][0]);
282  dec_client_response_count(x);
283  int nresp = get_client_response_count(x);
284  memmove(*res_comm, *res_comm + 1, nresp*sizeof(comm_t*));
285  return ret;
286 };
287 
288 
289 #ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
290 }
291 #endif
292 
293 #endif /*CISCLIENTCOMM_H_*/
void * handle
Pointer to handle for comm.
Definition: CommBase.h:29
char response_address[COMMBUFFSIZ]
Response address.
Definition: comm_header.h:27
char request_id[COMMBUFFSIZ]
Request id.
Definition: comm_header.h:28
void * info
Pointer to any extra info comm requires.
Definition: CommBase.h:30
Communication structure.
Definition: CommBase.h:23
char address[COMM_ADDRESS_SIZE]
Comm address.
Definition: CommBase.h:26
void * info
Pointer to any extra info serializer requires.
Definition: SerializeBase.h:21
comm_type type
Comm type.
Definition: CommBase.h:24
int valid
1 if the header is valid, 0 otherwise.
Definition: comm_header.h:25
int always_send_header
1 if comm should always send a header.
Definition: CommBase.h:33
seri_t * serializer
Serializer for comm messages.
Definition: CommBase.h:31
char direction[COMM_DIR_SIZE]
send or recv for direction messages will go.
Definition: CommBase.h:27
char name[COMM_NAME_SIZE]
Comm name.
Definition: CommBase.h:25
int * sent_eof
Flag specifying if EOF has been sent.
Definition: CommBase.h:36
int * recv_eof
Flag specifying if EOF has been received.
Definition: CommBase.h:37
Header information passed by comms for multipart messages.
Definition: comm_header.h:19