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;
59 EAPI const enum packet_type const packet_type(const struct packet *packet)
61 if (!packet || packet->state != VALID || !packet->data) {
65 return packet->data->head.type;
68 EAPI unsigned long packet_mask(const struct packet *packet)
70 if (!packet || packet->state != VALID || !packet->data) {
74 return packet->data->head.mask;
77 EAPI int packet_set_mask(struct packet *packet, unsigned long mask)
79 if (!packet || packet->state != VALID || !packet->data) {
83 packet->data->head.mask = mask;
87 EAPI const enum packet_flag const packet_flag(const struct packet *packet)
89 if (!packet || packet->state != VALID || !packet->data) {
90 return PACKET_FLAG_ERROR;
93 return packet->data->head.flag;
96 EAPI int packet_set_flag(struct packet *packet, enum packet_flag flag)
98 if (!packet || packet->state != VALID || !packet->data) {
102 packet->data->head.flag = flag;
106 EAPI const unsigned long const packet_source(const struct packet *packet)
108 if (!packet || packet->state != VALID || !packet->data) {
112 return packet->data->head.source;
115 EAPI int packet_set_source(struct packet *packet, unsigned long source)
117 if (!packet || packet->state != VALID || !packet->data || !source) {
121 packet->data->head.source = source;
125 EAPI int packet_set_fd(struct packet *packet, int fd)
127 if (!packet || packet->state != VALID || !packet->data || fd < 0) {
131 packet->data->head.fd = fd;
135 EAPI int packet_fd(const struct packet *packet)
137 if (!packet || packet->state != VALID || !packet->data) {
141 return packet->data->head.fd;
144 EAPI const unsigned long const packet_destination(const struct packet *packet)
146 if (!packet || packet->state != VALID || !packet->data) {
150 return packet->data->head.destination;
153 EAPI int packet_set_destination(struct packet *packet, unsigned long destination)
155 if (!packet || packet->state != VALID || !packet->data || !destination) {
159 packet->data->head.destination = destination;
163 EAPI const int const packet_version(const struct packet *packet)
165 if (!packet || packet->state != VALID || !packet->data) {
169 return packet->data->head.version;
172 EAPI const int const packet_header_size(void)
174 struct data payload; /* Only for getting the size of header of packet */
176 return sizeof(payload.head);
179 EAPI const int const packet_size(const struct packet *packet)
181 if (!packet || packet->state != VALID || !packet->data) {
185 return sizeof(*packet->data) + packet->data->head.payload_size;
188 EAPI const double const packet_seq(const struct packet *packet)
190 if (!packet || packet->state != VALID || !packet->data) {
194 return packet->data->head.seq;
197 EAPI const int const packet_payload_size(const struct packet *packet)
199 if (!packet || packet->state != VALID || !packet->data) {
203 return packet->data->head.payload_size;
206 EAPI const char * const packet_command(const struct packet *packet)
208 if (!packet || packet->state != VALID || !packet->data) {
212 return packet->data->head.command;
215 EAPI const void * const packet_data(const struct packet *packet)
217 if (!packet || packet->state != VALID) {
224 static inline __attribute__((always_inline)) struct data *check_and_expand_packet(struct data *packet, int *payload_size)
226 struct data *new_packet;
228 if (packet->head.payload_size < *payload_size) {
232 new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
234 ErrPrint("Heap: %s\n", strerror(errno));
239 *payload_size += BUFSIZ;
243 static inline struct packet *packet_body_filler(struct packet *packet, int payload_size, const char *ptr, va_list va)
250 payload = packet->data->payload + packet->data->head.payload_size;
255 align = (unsigned long)payload & (sizeof(int) - 1);
257 align = sizeof(int) - align;
260 packet->data->head.payload_size += sizeof(int) + align;
261 packet->data = check_and_expand_packet(packet->data, &payload_size);
263 packet->state = INVALID;
269 *((int *)(payload + align)) = (int)va_arg(va, int);
273 str = (char *)va_arg(va, char *);
276 packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
277 packet->data = check_and_expand_packet(packet->data, &payload_size);
279 packet->state = INVALID;
285 strcpy(payload, str); /*!< Including NIL */
287 packet->data->head.payload_size += 1;
288 packet->data = check_and_expand_packet(packet->data, &payload_size);
290 packet->state = INVALID;
301 align = (unsigned long)payload & (sizeof(double) - 1);
303 align = sizeof(double) - align;
306 packet->data->head.payload_size += sizeof(double) + align;
307 packet->data = check_and_expand_packet(packet->data, &payload_size);
309 packet->state = INVALID;
315 *((double *)(payload + align)) = (double)va_arg(va, double);
318 ErrPrint("Invalid type [%c]\n", *ptr);
319 packet->state = INVALID;
333 EAPI struct packet *packet_create_reply(const struct packet *packet, const char *fmt, ...)
336 struct packet *result;
339 if (!packet || packet->state != VALID) {
343 result = malloc(sizeof(*result));
345 ErrPrint("Heap: %s\n", strerror(errno));
349 payload_size = sizeof(*result->data) + BUFSIZ;
351 result->data = calloc(1, payload_size);
353 ErrPrint("Heap: %s\n", strerror(errno));
354 result->state = INVALID;
359 result->state = VALID;
360 result->data->head.source = packet->data->head.destination;
361 result->data->head.destination = packet->data->head.source;
362 result->data->head.mask = 0xFFFFFFFF;
364 result->data->head.seq = packet->data->head.seq;
365 result->data->head.type = PACKET_ACK;
366 result->data->head.version = packet->data->head.version;
367 result->data->head.fd = -1;
368 if (packet->data->head.command[0] == PACKET_CMD_INT_TAG) {
369 unsigned int *head_cmd = (unsigned int *)result->data->head.command;
370 unsigned int *packet_cmd = (unsigned int *)packet->data->head.command;
372 *head_cmd = *packet_cmd;
374 strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
376 result->data->head.payload_size = 0;
377 payload_size -= sizeof(*result->data);
380 result = packet_body_filler(result, payload_size, fmt, va);
383 return packet_ref(result);
386 EAPI int packet_swap_address(struct packet *packet)
390 if (!packet || packet->state != VALID) {
394 tmp = packet->data->head.source;
395 packet->data->head.source = packet->data->head.destination;
396 packet->data->head.destination = tmp;
401 EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
403 struct packet *packet;
407 if (strlen(cmd) >= PACKET_MAX_CMD) {
408 ErrPrint("Command is too long\n");
412 packet = malloc(sizeof(*packet));
414 ErrPrint("Heap: %s\n", strerror(errno));
418 payload_size = sizeof(*packet->data) + BUFSIZ;
420 packet->data = calloc(1, payload_size);
422 ErrPrint("Heap: %s\n", strerror(errno));
423 packet->state = INVALID;
428 packet->state = VALID;
429 packet->data->head.source = 0lu;
430 packet->data->head.destination = 0lu;
431 packet->data->head.mask = 0xFFFFFFFF;
432 packet->data->head.seq = util_timestamp();
433 packet->data->head.type = PACKET_REQ;
434 packet->data->head.version = PACKET_VERSION;
435 packet->data->head.fd = -1;
436 if (cmd[0] == PACKET_CMD_INT_TAG) {
437 unsigned int *head_cmd = (unsigned int *)packet->data->head.command;
438 unsigned int *in_cmd = (unsigned int *)cmd;
442 strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
444 packet->data->head.payload_size = 0;
445 payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
448 packet = packet_body_filler(packet, payload_size, fmt, va);
451 return packet_ref(packet);
454 EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
457 struct packet *result;
460 if (strlen(cmd) >= PACKET_MAX_CMD) {
461 ErrPrint("Command is too long\n");
465 result = malloc(sizeof(*result));
467 ErrPrint("Heap: %s\n", strerror(errno));
471 payload_size = sizeof(*result->data) + BUFSIZ;
473 result->data = calloc(1, payload_size);
475 ErrPrint("Heap: %s\n", strerror(errno));
476 result->state = INVALID;
481 result->state = VALID;
482 result->data->head.source = 0lu;
483 result->data->head.destination = 0lu;
484 result->data->head.mask = 0xFFFFFFFF;
485 result->data->head.seq = util_timestamp();
486 result->data->head.type = PACKET_REQ_NOACK;
487 result->data->head.version = PACKET_VERSION;
488 result->data->head.fd = -1;
489 if (cmd[0] == PACKET_CMD_INT_TAG) {
490 unsigned int *head_cmd = (unsigned int *)result->data->head.command;
491 unsigned int *cmd_in = (unsigned int *)cmd;
494 strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
496 result->data->head.payload_size = 0;
497 payload_size -= sizeof(*result->data);
500 result = packet_body_filler(result, payload_size, fmt, va);
503 return packet_ref(result);
506 EAPI int packet_get(const struct packet *packet, const char *fmt, ...)
518 if (!packet || packet->state != VALID) {
525 while (*ptr && offset < packet->data->head.payload_size) {
526 payload = packet->data->payload + offset;
530 align = (unsigned long)payload & (sizeof(int) - 1);
532 align = sizeof(int) - align;
535 int_ptr = (int *)va_arg(va, int *);
536 *int_ptr = *((int *)(payload + align));
537 offset += (sizeof(int) + align);
542 align = (unsigned long)payload & (sizeof(double) - 1);
544 align = sizeof(double) - align;
546 double_ptr = (double *)va_arg(va, double *);
547 *double_ptr = *((double *)(payload + align));
548 offset += (sizeof(double) + align);
553 str_ptr = (char **)va_arg(va, char **);
555 offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
570 EAPI struct packet *packet_ref(struct packet *packet)
572 if (!packet || packet->state != VALID) {
580 EAPI struct packet *packet_unref(struct packet *packet)
582 if (!packet || packet->state != VALID) {
587 if (packet->refcnt < 0) {
588 ErrPrint("Invalid refcnt\n");
592 if (packet->refcnt == 0) {
593 packet->state = INVALID;
602 EAPI int packet_destroy(struct packet *packet)
604 packet_unref(packet);
608 EAPI struct packet *packet_build(struct packet *packet, int offset, void *data, int size)
612 if (packet == NULL) {
614 ErrPrint("Invalid argument\n");
618 packet = malloc(sizeof(*packet));
620 ErrPrint("Heap: %s\n", strerror(errno));
625 packet->data = calloc(1, size);
627 ErrPrint("Heap: %s\n", strerror(errno));
628 packet->state = INVALID;
633 packet->state = VALID;
634 memcpy(packet->data, data, size);
635 packet->data->head.mask = 0xFFFFFFFF;
639 ptr = realloc(packet->data, offset + size);
641 ErrPrint("Heap: %s\n", strerror(errno));
642 packet->state = INVALID;
648 packet->data = (struct data *)ptr;
649 memcpy(ptr + offset, data, size);