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