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) {
64 return packet->data->head.type;
67 EAPI unsigned long packet_mask(const struct packet *packet)
69 if (!packet || packet->state != VALID || !packet->data) {
73 return packet->data->head.mask;
76 EAPI int packet_set_mask(struct packet *packet, unsigned long mask)
78 if (!packet || packet->state != VALID || !packet->data) {
82 packet->data->head.mask = mask;
86 EAPI const enum packet_flag const packet_flag(const struct packet *packet)
88 if (!packet || packet->state != VALID || !packet->data) {
89 return PACKET_FLAG_ERROR;
92 return packet->data->head.flag;
95 EAPI int packet_set_flag(struct packet *packet, enum packet_flag flag)
97 if (!packet || packet->state != VALID || !packet->data) {
101 packet->data->head.flag = flag;
105 EAPI const unsigned long const packet_source(const struct packet *packet)
107 if (!packet || packet->state != VALID || !packet->data) {
111 return packet->data->head.source;
114 EAPI int packet_set_source(struct packet *packet, unsigned long source)
116 if (!packet || packet->state != VALID || !packet->data || !source) {
120 packet->data->head.source = source;
124 EAPI const unsigned long const packet_destination(const struct packet *packet)
126 if (!packet || packet->state != VALID || !packet->data) {
130 return packet->data->head.destination;
133 EAPI int packet_set_destination(struct packet *packet, unsigned long destination)
135 if (!packet || packet->state != VALID || !packet->data || !destination) {
139 packet->data->head.destination = destination;
143 EAPI const int const packet_version(const struct packet *packet)
145 if (!packet || packet->state != VALID || !packet->data) {
149 return packet->data->head.version;
152 EAPI const int const packet_header_size(void)
154 struct data payload; /* Only for getting the size of header of packet */
156 return sizeof(payload.head);
159 EAPI const int const packet_size(const struct packet *packet)
161 if (!packet || packet->state != VALID || !packet->data) {
165 return sizeof(*packet->data) + packet->data->head.payload_size;
168 EAPI const double const packet_seq(const struct packet *packet)
170 if (!packet || packet->state != VALID || !packet->data) {
174 return packet->data->head.seq;
177 EAPI const int const packet_payload_size(const struct packet *packet)
179 if (!packet || packet->state != VALID || !packet->data) {
183 return packet->data->head.payload_size;
186 EAPI const char * const packet_command(const struct packet *packet)
188 if (!packet || packet->state != VALID || !packet->data) {
192 return packet->data->head.command;
195 EAPI const void * const packet_data(const struct packet *packet)
197 if (!packet || packet->state != VALID) {
204 static inline __attribute__((always_inline)) struct data *check_and_expand_packet(struct data *packet, int *payload_size)
206 struct data *new_packet;
208 if (packet->head.payload_size < *payload_size) {
212 new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
214 ErrPrint("Heap: %s\n", strerror(errno));
219 *payload_size += BUFSIZ;
223 static inline struct packet *packet_body_filler(struct packet *packet, int payload_size, const char *ptr, va_list va)
230 payload = packet->data->payload + packet->data->head.payload_size;
235 align = (unsigned long)payload & (sizeof(int) - 1);
237 align = sizeof(int) - align;
240 packet->data->head.payload_size += sizeof(int) + align;
241 packet->data = check_and_expand_packet(packet->data, &payload_size);
243 packet->state = INVALID;
249 *((int *)(payload + align)) = (int)va_arg(va, int);
253 str = (char *)va_arg(va, char *);
256 packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
257 packet->data = check_and_expand_packet(packet->data, &payload_size);
259 packet->state = INVALID;
265 strcpy(payload, str); /*!< Including NIL */
267 packet->data->head.payload_size += 1;
268 packet->data = check_and_expand_packet(packet->data, &payload_size);
270 packet->state = INVALID;
281 align = (unsigned long)payload & (sizeof(double) - 1);
283 align = sizeof(double) - align;
286 packet->data->head.payload_size += sizeof(double) + align;
287 packet->data = check_and_expand_packet(packet->data, &payload_size);
289 packet->state = INVALID;
295 *((double *)(payload + align)) = (double)va_arg(va, double);
298 ErrPrint("Invalid type [%c]\n", *ptr);
299 packet->state = INVALID;
313 EAPI struct packet *packet_create_reply(const struct packet *packet, const char *fmt, ...)
316 struct packet *result;
319 if (!packet || packet->state != VALID) {
323 result = malloc(sizeof(*result));
325 ErrPrint("Heap: %s\n", strerror(errno));
329 payload_size = sizeof(*result->data) + BUFSIZ;
331 result->data = calloc(1, payload_size);
333 ErrPrint("Heap: %s\n", strerror(errno));
334 result->state = INVALID;
339 result->state = VALID;
340 result->data->head.source = packet->data->head.destination;
341 result->data->head.destination = packet->data->head.source;
342 result->data->head.mask = 0xFFFFFFFF;
344 result->data->head.seq = packet->data->head.seq;
345 result->data->head.type = PACKET_ACK;
346 result->data->head.version = packet->data->head.version;
347 strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
348 result->data->head.payload_size = 0;
349 payload_size -= sizeof(*result->data);
352 result = packet_body_filler(result, payload_size, fmt, va);
355 return packet_ref(result);
358 EAPI int packet_swap_address(struct packet *packet)
362 if (!packet || packet->state != VALID) {
366 tmp = packet->data->head.source;
367 packet->data->head.source = packet->data->head.destination;
368 packet->data->head.destination = tmp;
373 EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
375 struct packet *packet;
379 if (strlen(cmd) >= PACKET_MAX_CMD) {
380 ErrPrint("Command is too long\n");
384 packet = malloc(sizeof(*packet));
386 ErrPrint("Heap: %s\n", strerror(errno));
390 payload_size = sizeof(*packet->data) + BUFSIZ;
392 packet->data = calloc(1, payload_size);
394 ErrPrint("Heap: %s\n", strerror(errno));
395 packet->state = INVALID;
400 packet->state = VALID;
401 packet->data->head.source = 0lu;
402 packet->data->head.destination = 0lu;
403 packet->data->head.mask = 0xFFFFFFFF;
404 packet->data->head.seq = util_timestamp();
405 packet->data->head.type = PACKET_REQ;
406 packet->data->head.version = PACKET_VERSION;
407 strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
408 packet->data->head.payload_size = 0;
409 payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
412 packet = packet_body_filler(packet, payload_size, fmt, va);
415 return packet_ref(packet);
418 EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
421 struct packet *result;
424 if (strlen(cmd) >= PACKET_MAX_CMD) {
425 ErrPrint("Command is too long\n");
429 result = malloc(sizeof(*result));
431 ErrPrint("Heap: %s\n", strerror(errno));
435 payload_size = sizeof(*result->data) + BUFSIZ;
437 result->data = calloc(1, payload_size);
439 ErrPrint("Heap: %s\n", strerror(errno));
440 result->state = INVALID;
445 result->state = VALID;
446 result->data->head.source = 0lu;
447 result->data->head.destination = 0lu;
448 result->data->head.mask = 0xFFFFFFFF;
449 result->data->head.seq = util_timestamp();
450 result->data->head.type = PACKET_REQ_NOACK;
451 result->data->head.version = PACKET_VERSION;
452 strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
453 result->data->head.payload_size = 0;
454 payload_size -= sizeof(*result->data);
457 result = packet_body_filler(result, payload_size, fmt, va);
460 return packet_ref(result);
463 EAPI int packet_get(const struct packet *packet, const char *fmt, ...)
475 if (!packet || packet->state != VALID) {
482 while (*ptr && offset < packet->data->head.payload_size) {
483 payload = packet->data->payload + offset;
487 align = (unsigned long)payload & (sizeof(int) - 1);
489 align = sizeof(int) - align;
492 int_ptr = (int *)va_arg(va, int *);
493 *int_ptr = *((int *)(payload + align));
494 offset += (sizeof(int) + align);
499 align = (unsigned long)payload & (sizeof(double) - 1);
501 align = sizeof(double) - align;
503 double_ptr = (double *)va_arg(va, double *);
504 *double_ptr = *((double *)(payload + align));
505 offset += (sizeof(double) + align);
510 str_ptr = (char **)va_arg(va, char **);
512 offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
527 EAPI struct packet *packet_ref(struct packet *packet)
529 if (!packet || packet->state != VALID) {
537 EAPI struct packet *packet_unref(struct packet *packet)
539 if (!packet || packet->state != VALID) {
544 if (packet->refcnt < 0) {
545 ErrPrint("Invalid refcnt\n");
549 if (packet->refcnt == 0) {
550 packet->state = INVALID;
559 EAPI int packet_destroy(struct packet *packet)
561 packet_unref(packet);
565 EAPI struct packet *packet_build(struct packet *packet, int offset, void *data, int size)
569 if (packet == NULL) {
571 ErrPrint("Invalid argument\n");
575 packet = malloc(sizeof(*packet));
577 ErrPrint("Heap: %s\n", strerror(errno));
582 packet->data = calloc(1, size);
584 ErrPrint("Heap: %s\n", strerror(errno));
585 packet->state = INVALID;
590 packet->state = VALID;
591 memcpy(packet->data, data, size);
592 packet->data->head.mask = 0xFFFFFFFF;
596 ptr = realloc(packet->data, offset + size);
598 ErrPrint("Heap: %s\n", strerror(errno));
599 packet->state = INVALID;
605 packet->data = (struct data *)ptr;
606 memcpy(ptr + offset, data, size);