2 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
37 char command[PACKET_MAX_CMD];
38 enum packet_type type;
39 enum packet_flag flag;
42 unsigned long destination;
58 EAPI const enum packet_type const packet_type(const struct packet *packet)
60 if (!packet || packet->state != VALID || !packet->data)
63 return packet->data->head.type;
66 EAPI unsigned long packet_mask(const struct packet *packet)
68 if (!packet || packet->state != VALID || !packet->data)
71 return packet->data->head.mask;
74 EAPI int packet_set_mask(struct packet *packet, unsigned long mask)
76 if (!packet || packet->state != VALID || !packet->data)
79 packet->data->head.mask = mask;
83 EAPI const enum packet_flag const packet_flag(const struct packet *packet)
85 if (!packet || packet->state != VALID || !packet->data)
86 return PACKET_FLAG_ERROR;
88 return packet->data->head.flag;
91 EAPI int packet_set_flag(struct packet *packet, enum packet_flag flag)
93 if (!packet || packet->state != VALID || !packet->data)
96 packet->data->head.flag = flag;
100 EAPI const unsigned long const packet_source(const struct packet *packet)
102 if (!packet || packet->state != VALID || !packet->data)
105 return packet->data->head.source;
108 EAPI int packet_set_source(struct packet *packet, unsigned long source)
110 if (!packet || packet->state != VALID || !packet->data || !source)
113 packet->data->head.source = source;
117 EAPI const unsigned long const packet_destination(const struct packet *packet)
119 if (!packet || packet->state != VALID || !packet->data)
122 return packet->data->head.destination;
125 EAPI int packet_set_destination(struct packet *packet, unsigned long destination)
127 if (!packet || packet->state != VALID || !packet->data || !destination)
130 packet->data->head.destination = destination;
134 EAPI const int const packet_version(const struct packet *packet)
136 if (!packet || packet->state != VALID || !packet->data)
139 return packet->data->head.version;
142 EAPI const int const packet_header_size(void)
144 struct data payload; /* Only for getting the size of header of packet */
146 return sizeof(payload.head);
149 EAPI const int const packet_size(const struct packet *packet)
151 if (!packet || packet->state != VALID || !packet->data)
154 return sizeof(*packet->data) + packet->data->head.payload_size;
157 EAPI const double const packet_seq(const struct packet *packet)
159 if (!packet || packet->state != VALID || !packet->data)
162 return packet->data->head.seq;
165 EAPI const int const packet_payload_size(const struct packet *packet)
167 if (!packet || packet->state != VALID || !packet->data)
170 return packet->data->head.payload_size;
173 EAPI const char * const packet_command(const struct packet *packet)
175 if (!packet || packet->state != VALID || !packet->data)
178 return packet->data->head.command;
181 EAPI const void * const packet_data(const struct packet *packet)
183 if (!packet || packet->state != VALID)
189 static inline __attribute__((always_inline)) struct data *check_and_expand_packet(struct data *packet, int *payload_size)
191 struct data *new_packet;
193 if (packet->head.payload_size < *payload_size)
196 new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
198 ErrPrint("Heap: %s\n", strerror(errno));
203 *payload_size += BUFSIZ;
207 static inline struct packet *packet_body_filler(struct packet *packet, int payload_size, const char *ptr, va_list va)
213 payload = packet->data->payload + packet->data->head.payload_size;
218 packet->data->head.payload_size += sizeof(int);
219 packet->data = check_and_expand_packet(packet->data, &payload_size);
221 packet->state = INVALID;
227 *((int *)payload) = (int)va_arg(va, int);
231 str = (char *)va_arg(va, char *);
234 packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
235 packet->data = check_and_expand_packet(packet->data, &payload_size);
237 packet->state = INVALID;
243 strcpy(payload, str); /*!< Including NIL */
245 packet->data->head.payload_size += 1;
246 packet->data = check_and_expand_packet(packet->data, &payload_size);
248 packet->state = INVALID;
259 packet->data->head.payload_size += sizeof(double);
260 packet->data = check_and_expand_packet(packet->data, &payload_size);
262 packet->state = INVALID;
268 *((double *)payload) = (double)va_arg(va, double);
271 ErrPrint("Invalid type [%c]\n", *ptr);
272 packet->state = INVALID;
286 EAPI struct packet *packet_create_reply(const struct packet *packet, const char *fmt, ...)
289 struct packet *result;
292 if (!packet || packet->state != VALID)
295 result = malloc(sizeof(*result));
297 ErrPrint("Heap: %s\n", strerror(errno));
301 payload_size = sizeof(*result->data) + BUFSIZ;
303 result->data = calloc(1, payload_size);
305 ErrPrint("Heap: %s\n", strerror(errno));
306 result->state = INVALID;
311 result->state = VALID;
312 result->data->head.source = packet->data->head.destination;
313 result->data->head.destination = packet->data->head.source;
314 result->data->head.mask = 0xFFFFFFFF;
316 result->data->head.seq = packet->data->head.seq;
317 result->data->head.type = PACKET_ACK;
318 result->data->head.version = packet->data->head.version;
319 strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
320 result->data->head.payload_size = 0;
321 payload_size -= sizeof(*result->data);
324 result = packet_body_filler(result, payload_size, fmt, va);
327 return packet_ref(result);
330 EAPI int packet_swap_address(struct packet *packet)
334 if (!packet || packet->state != VALID)
337 tmp = packet->data->head.source;
338 packet->data->head.source = packet->data->head.destination;
339 packet->data->head.destination = tmp;
344 EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
346 struct packet *packet;
351 if (strlen(cmd) >= PACKET_MAX_CMD) {
352 ErrPrint("Command is too long\n");
356 packet = malloc(sizeof(*packet));
358 ErrPrint("Heap: %s\n", strerror(errno));
362 payload_size = sizeof(*packet->data) + BUFSIZ;
364 packet->data = calloc(1, payload_size);
366 ErrPrint("Heap: %s\n", strerror(errno));
367 packet->state = INVALID;
372 packet->state = VALID;
373 gettimeofday(&tv, NULL);
374 packet->data->head.source = 0lu;
375 packet->data->head.destination = 0lu;
376 packet->data->head.mask = 0xFFFFFFFF;
377 packet->data->head.seq = tv.tv_sec + tv.tv_usec / 1000000.0f;
378 packet->data->head.type = PACKET_REQ;
379 packet->data->head.version = PACKET_VERSION;
380 strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
381 packet->data->head.payload_size = 0;
382 payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
385 packet = packet_body_filler(packet, payload_size, fmt, va);
388 return packet_ref(packet);
391 EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
394 struct packet *result;
398 if (strlen(cmd) >= PACKET_MAX_CMD) {
399 ErrPrint("Command is too long\n");
403 result = malloc(sizeof(*result));
405 ErrPrint("Heap: %s\n", strerror(errno));
409 payload_size = sizeof(*result->data) + BUFSIZ;
411 result->data = calloc(1, payload_size);
413 ErrPrint("Heap: %s\n", strerror(errno));
414 result->state = INVALID;
419 result->state = VALID;
420 gettimeofday(&tv, NULL);
421 result->data->head.source = 0lu;
422 result->data->head.destination = 0lu;
423 result->data->head.mask = 0xFFFFFFFF;
424 result->data->head.seq = tv.tv_sec + tv.tv_usec / 1000000.0f;
425 result->data->head.type = PACKET_REQ_NOACK;
426 result->data->head.version = PACKET_VERSION;
427 strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
428 result->data->head.payload_size = 0;
429 payload_size -= sizeof(*result->data);
432 result = packet_body_filler(result, payload_size, fmt, va);
435 return packet_ref(result);
438 EAPI int packet_get(const struct packet *packet, const char *fmt, ...)
449 if (!packet || packet->state != VALID)
455 while (*ptr && offset < packet->data->head.payload_size) {
456 payload = packet->data->payload + offset;
460 int_ptr = (int *)va_arg(va, int *);
461 *int_ptr = *((int *)payload);
462 offset += sizeof(int);
467 double_ptr = (double *)va_arg(va, double *);
468 *double_ptr = *((double *)payload);
469 offset += sizeof(double);
474 str_ptr = (char **)va_arg(va, char **);
476 offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
491 EAPI struct packet *packet_ref(struct packet *packet)
493 if (!packet || packet->state != VALID)
500 EAPI struct packet *packet_unref(struct packet *packet)
502 if (!packet || packet->state != VALID)
506 if (packet->refcnt < 0) {
507 ErrPrint("Invalid refcnt\n");
511 if (packet->refcnt == 0) {
512 packet->state = INVALID;
521 EAPI int packet_destroy(struct packet *packet)
523 packet_unref(packet);
527 EAPI struct packet *packet_build(struct packet *packet, int offset, void *data, int size)
531 if (packet == NULL) {
533 ErrPrint("Invalid argument\n");
537 packet = malloc(sizeof(*packet));
539 ErrPrint("Heap: %s\n", strerror(errno));
544 packet->data = calloc(1, size);
546 ErrPrint("Heap: %s\n", strerror(errno));
547 packet->state = INVALID;
552 packet->state = VALID;
553 memcpy(packet->data, data, size);
554 packet->data->head.mask = 0xFFFFFFFF;
558 ptr = realloc(packet->data, offset + size);
560 ErrPrint("Heap: %s\n", strerror(errno));
561 packet->state = INVALID;
567 packet->data = (struct data *)ptr;
568 memcpy(ptr + offset, data, size);