summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung-jae Park <nicesj.park@samsung.com>2014-11-25 20:06:49 +0900
committerSung-jae Park <nicesj.park@samsung.com>2014-11-25 20:06:52 +0900
commit7c0ed4cb7c51502cb9d7eaa3572345134fca13db (patch)
tree6dc6683c0cc43b5bfe0cbb2c87d5740920baac4e
parentc0f81a7de66900aea94ca56edc44ca82fd87bad2 (diff)
parent7fba50f7801739c3b566acc244144f045a095e69 (diff)
downloadcom-core-7c0ed4cb7c51502cb9d7eaa3572345134fca13db.tar.gz
com-core-7c0ed4cb7c51502cb9d7eaa3572345134fca13db.tar.bz2
com-core-7c0ed4cb7c51502cb9d7eaa3572345134fca13db.zip
Merge branch 'devel/home/master'
Change-Id: I4a31fe755296f79fa6f143f1f8b1a567c1ad087d
-rw-r--r--include/packet.h5
-rw-r--r--src/com-core.c6
-rw-r--r--src/com-core_packet.c67
-rw-r--r--src/packet.c905
4 files changed, 530 insertions, 453 deletions
diff --git a/include/packet.h b/include/packet.h
index 1292302..f2cfe49 100644
--- a/include/packet.h
+++ b/include/packet.h
@@ -41,7 +41,7 @@ enum packet_flag {
/*!
* \brief Version of current protocol (packet)
*/
-#define PACKET_VERSION 2
+#define PACKET_VERSION 3
/*!
* \brief Maximum length of a command string
@@ -377,6 +377,9 @@ extern const int const packet_size(const struct packet *packet);
*/
extern struct packet *packet_build(struct packet *packet, int offset, void *data, int size);
+extern int packet_fd(const struct packet *packet);
+extern int packet_set_fd(struct packet *packet, int fd);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/com-core.c b/src/com-core.c
index 208b564..ceec3a7 100644
--- a/src/com-core.c
+++ b/src/com-core.c
@@ -303,7 +303,7 @@ static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer cbdata)
g_io_channel_set_close_on_unref(gio, FALSE);
id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)client_cb, cbdata);
- if (id <= 0) {
+ if (id == 0) {
GError *err = NULL;
ErrPrint("Failed to add IO watch\n");
@@ -373,7 +373,7 @@ EAPI int com_core_server_create(const char *addr, int is_sync, int (*service_cb)
g_io_channel_set_close_on_unref(gio, FALSE);
id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc)accept_cb, cbdata);
- if (id <= 0) {
+ if (id == 0) {
GError *err = NULL;
ErrPrint("Failed to add IO watch\n");
free(cbdata);
@@ -449,7 +449,7 @@ EAPI int com_core_client_create(const char *addr, int is_sync, int (*service_cb)
g_io_channel_set_close_on_unref(gio, FALSE);
id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)client_cb, cbdata);
- if (id <= 0) {
+ if (id == 0) {
GError *err = NULL;
ErrPrint("Failed to add IO watch\n");
free(cbdata);
diff --git a/src/com-core_packet.c b/src/com-core_packet.c
index ea9ffc6..41ace18 100644
--- a/src/com-core_packet.c
+++ b/src/com-core_packet.c
@@ -284,7 +284,12 @@ static inline int packet_ready(int handle, struct recv_ctx *receive, struct meth
result = table[cmd_idx].handler(receive->pid, handle, receive->packet);
receive->inuse = 0;
if (result) {
- ret = s_info.vtable.send(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT);
+ if (packet_fd(result) >= 0) {
+ ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT, packet_fd(result));
+ } else {
+ ret = s_info.vtable.send(handle, (void *)packet_data(result), packet_size(result), DEFAULT_TIMEOUT);
+ }
+
if (ret < 0) {
ErrPrint("Failed to send an ack packet\n");
} else {
@@ -381,6 +386,7 @@ static int service_cb(int handle, void *data)
int ret;
int size;
char *ptr;
+ int fd = -1;
receive = find_recv_ctx(handle);
if (!receive) {
@@ -407,7 +413,7 @@ static int service_cb(int handle, void *data)
return -ENOMEM;
}
- ret = s_info.vtable.recv(handle, ptr, size, &pid, receive->timeout);
+ ret = s_info.vtable.recv_with_fd(handle, ptr, size, &pid, receive->timeout, &fd);
if (ret < 0) {
ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
free(ptr);
@@ -428,6 +434,14 @@ static int service_cb(int handle, void *data)
return -EFAULT; /*!< Return negative value will invoke the client_disconnected_cb */
}
+ if (fd >= 0) {
+ if (packet_fd(receive->packet) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(receive->packet), fd);
+ }
+
+ packet_set_fd(receive->packet, fd);
+ }
+
receive->offset += ret;
if (receive->offset == packet_header_size()) {
@@ -459,7 +473,7 @@ static int service_cb(int handle, void *data)
return -ENOMEM;
}
- ret = s_info.vtable.recv(handle, ptr, size, &pid, receive->timeout);
+ ret = s_info.vtable.recv_with_fd(handle, ptr, size, &pid, receive->timeout, &fd);
if (ret < 0) {
ErrPrint("Recv[%d], pid[%d :: %d]\n", ret, receive->pid, pid);
free(ptr);
@@ -479,6 +493,14 @@ static int service_cb(int handle, void *data)
return -EFAULT;
}
+ if (fd >= 0) {
+ if (packet_fd(receive->packet) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(receive->packet), fd);
+ }
+
+ packet_set_fd(receive->packet, fd);
+ }
+
receive->offset += ret;
if (receive->offset == packet_size(receive->packet)) {
@@ -538,7 +560,11 @@ EAPI int com_core_packet_async_send(int handle, struct packet *packet, double ti
ctx->data = data;
ctx->packet = packet_ref(packet);
- ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ if (packet_fd(packet) >= 0) {
+ ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
+ } else {
+ ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ }
if (ret != packet_size(packet)) {
ErrPrint("Send failed. %d <> %d (handle: %d)\n", ret, packet_size(packet), handle);
destroy_request_ctx(ctx);
@@ -557,7 +583,11 @@ EAPI int com_core_packet_send_only(int handle, struct packet *packet)
return -EINVAL;
}
- ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ if (packet_fd(packet) >= 0) {
+ ret = s_info.vtable.send_with_fd(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
+ } else {
+ ret = s_info.vtable.send(handle, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ }
if (ret != packet_size(packet)) {
ErrPrint("Failed to send whole packet\n");
return -EIO;
@@ -575,6 +605,7 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
struct packet *result = NULL;
void *ptr;
int size;
+ int recv_fd = -1;
if (!addr || !packet) {
ErrPrint("Invalid argument\n");
@@ -594,7 +625,11 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
ErrPrint("Error: %s\n", strerror(errno));
}
- ret = com_core_send(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ if (packet_fd(packet) >= 0) {
+ ret = com_core_send_with_fd(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT, packet_fd(packet));
+ } else {
+ ret = com_core_send(fd, (char *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
+ }
if (ret < 0) {
goto out;
}
@@ -606,7 +641,7 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
}
offset = 0;
- ret = com_core_recv(fd, (char *)ptr, packet_header_size(), &pid, timeout);
+ ret = com_core_recv_with_fd(fd, (char *)ptr, packet_header_size(), &pid, timeout, &recv_fd);
if (ret <= 0) {
DbgPrint("Recv returns %d\n", ret);
free(ptr);
@@ -620,6 +655,14 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
ErrPrint("Failed to build a packet\n");
goto out;
}
+
+ if (recv_fd >= 0) {
+ if (packet_fd(result) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(result), recv_fd);
+ }
+
+ packet_set_fd(result, recv_fd);
+ }
}
size = packet_payload_size(result);
@@ -642,7 +685,7 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
goto out;
}
- ret = com_core_recv(fd, (char *)ptr, size, &pid, timeout);
+ ret = com_core_recv_with_fd(fd, (char *)ptr, size, &pid, timeout, &recv_fd);
if (ret <= 0) {
DbgPrint("Recv returns %d\n", ret);
free(ptr);
@@ -653,6 +696,14 @@ EAPI struct packet *com_core_packet_oneshot_send(const char *addr, struct packet
result = packet_build(result, offset, ptr, ret);
offset += ret;
free(ptr);
+
+ if (result && recv_fd >= 0) {
+ if (packet_fd(result) >= 0) {
+ DbgPrint("Packet already has FD: %d (new: %d)\n", packet_fd(result), recv_fd);
+ }
+
+ packet_set_fd(result, recv_fd);
+ }
}
out:
diff --git a/src/packet.c b/src/packet.c
index 47b85fe..c40f78f 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -31,601 +31,624 @@
int errno;
struct data {
- struct {
- int version;
- int payload_size;
- char command[PACKET_MAX_CMD];
- enum packet_type type;
- enum packet_flag flag;
- double seq;
- unsigned long source;
- unsigned long destination;
- unsigned long mask;
- } head;
-
- char payload[];
+ struct {
+ int version;
+ int payload_size;
+ char command[PACKET_MAX_CMD];
+ enum packet_type type;
+ enum packet_flag flag;
+ double seq;
+ unsigned long source;
+ unsigned long destination;
+ unsigned long mask;
+ int fd;
+ } head;
+
+ char payload[];
};
struct packet {
- enum {
- VALID = 0xbeefbeef,
- INVALID = 0xdeaddead
- } state;
- int refcnt;
- struct data *data;
+ enum {
+ VALID = 0xbeefbeef,
+ INVALID = 0xdeaddead
+ } state;
+ int refcnt;
+ struct data *data;
};
EAPI const enum packet_type const packet_type(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return PACKET_ERROR;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return PACKET_ERROR;
+ }
- return packet->data->head.type;
+ return packet->data->head.type;
}
EAPI unsigned long packet_mask(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.mask;
+ return packet->data->head.mask;
}
EAPI int packet_set_mask(struct packet *packet, unsigned long mask)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- packet->data->head.mask = mask;
- return 0;
+ packet->data->head.mask = mask;
+ return 0;
}
EAPI const enum packet_flag const packet_flag(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return PACKET_FLAG_ERROR;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return PACKET_FLAG_ERROR;
+ }
- return packet->data->head.flag;
+ return packet->data->head.flag;
}
EAPI int packet_set_flag(struct packet *packet, enum packet_flag flag)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- packet->data->head.flag = flag;
- return 0;
+ packet->data->head.flag = flag;
+ return 0;
}
EAPI const unsigned long const packet_source(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.source;
+ return packet->data->head.source;
}
EAPI int packet_set_source(struct packet *packet, unsigned long source)
{
- if (!packet || packet->state != VALID || !packet->data || !source) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data || !source) {
+ return -EINVAL;
+ }
- packet->data->head.source = source;
- return 0;
+ packet->data->head.source = source;
+ return 0;
+}
+
+EAPI int packet_set_fd(struct packet *packet, int fd)
+{
+ if (!packet || packet->state != VALID || !packet->data || fd < 0) {
+ return -EINVAL;
+ }
+
+ packet->data->head.fd = fd;
+ return 0;
+}
+
+EAPI int packet_fd(const struct packet *packet)
+{
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
+
+ return packet->data->head.fd;
}
EAPI const unsigned long const packet_destination(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.destination;
+ return packet->data->head.destination;
}
EAPI int packet_set_destination(struct packet *packet, unsigned long destination)
{
- if (!packet || packet->state != VALID || !packet->data || !destination) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data || !destination) {
+ return -EINVAL;
+ }
- packet->data->head.destination = destination;
- return 0;
+ packet->data->head.destination = destination;
+ return 0;
}
EAPI const int const packet_version(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return PACKET_ERROR;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return PACKET_ERROR;
+ }
- return packet->data->head.version;
+ return packet->data->head.version;
}
EAPI const int const packet_header_size(void)
{
- struct data payload; /* Only for getting the size of header of packet */
+ struct data payload; /* Only for getting the size of header of packet */
- return sizeof(payload.head);
+ return sizeof(payload.head);
}
EAPI const int const packet_size(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- return sizeof(*packet->data) + packet->data->head.payload_size;
+ return sizeof(*packet->data) + packet->data->head.payload_size;
}
EAPI const double const packet_seq(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return 0;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return 0;
+ }
- return packet->data->head.seq;
+ return packet->data->head.seq;
}
EAPI const int const packet_payload_size(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return -EINVAL;
+ }
- return packet->data->head.payload_size;
+ return packet->data->head.payload_size;
}
EAPI const char * const packet_command(const struct packet *packet)
{
- if (!packet || packet->state != VALID || !packet->data) {
- return NULL;
- }
+ if (!packet || packet->state != VALID || !packet->data) {
+ return NULL;
+ }
- return packet->data->head.command;
+ return packet->data->head.command;
}
EAPI const void * const packet_data(const struct packet *packet)
{
- if (!packet || packet->state != VALID) {
- return NULL;
- }
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
- return packet->data;
+ return packet->data;
}
static inline __attribute__((always_inline)) struct data *check_and_expand_packet(struct data *packet, int *payload_size)
{
- struct data *new_packet;
+ struct data *new_packet;
- if (packet->head.payload_size < *payload_size) {
- return packet;
- }
+ if (packet->head.payload_size < *payload_size) {
+ return packet;
+ }
- new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
- if (!new_packet) {
- ErrPrint("Heap: %s\n", strerror(errno));
- free(packet);
- return NULL;
- }
+ new_packet = realloc(packet, sizeof(*packet) + *payload_size + BUFSIZ); /*!< Expanding to +BUFSIZ */
+ if (!new_packet) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(packet);
+ return NULL;
+ }
- *payload_size += BUFSIZ;
- return new_packet;
+ *payload_size += BUFSIZ;
+ return new_packet;
}
static inline struct packet *packet_body_filler(struct packet *packet, int payload_size, const char *ptr, va_list va)
{
- char *payload;
- char *str;
- int align;
-
- while (*ptr) {
- payload = packet->data->payload + packet->data->head.payload_size;
-
- switch (*ptr) {
- case 'i':
- case 'I':
- align = (unsigned long)payload & (sizeof(int) - 1);
- if (align) {
- align = sizeof(int) - align;
- }
-
- packet->data->head.payload_size += sizeof(int) + align;
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
- }
-
- *((int *)(payload + align)) = (int)va_arg(va, int);
- break;
- case 's':
- case 'S':
- str = (char *)va_arg(va, char *);
-
- if (str) {
- packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
- }
-
- strcpy(payload, str); /*!< Including NIL */
- } else {
- packet->data->head.payload_size += 1;
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
- }
-
- payload[0] = '\0';
- }
- break;
- case 'd':
- case 'D':
- align = (unsigned long)payload & (sizeof(double) - 1);
- if (align) {
- align = sizeof(double) - align;
- }
-
- packet->data->head.payload_size += sizeof(double) + align;
- packet->data = check_and_expand_packet(packet->data, &payload_size);
- if (!packet->data) {
- packet->state = INVALID;
- free(packet);
- packet = NULL;
- goto out;
- }
-
- *((double *)(payload + align)) = (double)va_arg(va, double);
- break;
- default:
- ErrPrint("Invalid type [%c]\n", *ptr);
+ char *payload;
+ char *str;
+ int align;
+
+ while (*ptr) {
+ payload = packet->data->payload + packet->data->head.payload_size;
+
+ switch (*ptr) {
+ case 'i':
+ case 'I':
+ align = (unsigned long)payload & (sizeof(int) - 1);
+ if (align) {
+ align = sizeof(int) - align;
+ }
+
+ packet->data->head.payload_size += sizeof(int) + align;
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
+ }
+
+ *((int *)(payload + align)) = (int)va_arg(va, int);
+ break;
+ case 's':
+ case 'S':
+ str = (char *)va_arg(va, char *);
+
+ if (str) {
+ packet->data->head.payload_size += strlen(str) + 1; /*!< Including NIL */
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
packet->state = INVALID;
- free(packet->data);
free(packet);
packet = NULL;
goto out;
+ }
+
+ strcpy(payload, str); /*!< Including NIL */
+ } else {
+ packet->data->head.payload_size += 1;
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
+ }
+
+ payload[0] = '\0';
+ }
+ break;
+ case 'd':
+ case 'D':
+ align = (unsigned long)payload & (sizeof(double) - 1);
+ if (align) {
+ align = sizeof(double) - align;
+ }
+
+ packet->data->head.payload_size += sizeof(double) + align;
+ packet->data = check_and_expand_packet(packet->data, &payload_size);
+ if (!packet->data) {
+ packet->state = INVALID;
+ free(packet);
+ packet = NULL;
+ goto out;
}
- ptr++;
+ *((double *)(payload + align)) = (double)va_arg(va, double);
+ break;
+ default:
+ ErrPrint("Invalid type [%c]\n", *ptr);
+ packet->state = INVALID;
+ free(packet->data);
+ free(packet);
+ packet = NULL;
+ goto out;
}
+ ptr++;
+ }
+
out:
- return packet;
+ return packet;
}
EAPI struct packet *packet_create_reply(const struct packet *packet, const char *fmt, ...)
{
- int payload_size;
- struct packet *result;
- va_list va;
-
- if (!packet || packet->state != VALID) {
- return NULL;
- }
-
- result = malloc(sizeof(*result));
- if (!result) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- payload_size = sizeof(*result->data) + BUFSIZ;
- result->refcnt = 0;
- result->data = calloc(1, payload_size);
- if (!packet->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- result->state = INVALID;
- free(result);
- return NULL;
- }
-
- result->state = VALID;
- result->data->head.source = packet->data->head.destination;
- result->data->head.destination = packet->data->head.source;
- result->data->head.mask = 0xFFFFFFFF;
-
- result->data->head.seq = packet->data->head.seq;
- result->data->head.type = PACKET_ACK;
- result->data->head.version = packet->data->head.version;
- if (packet->data->head.command[0] == PACKET_CMD_INT_TAG) {
- unsigned int *head_cmd = (unsigned int *)result->data->head.command;
- unsigned int *packet_cmd = (unsigned int *)packet->data->head.command;
-
- *head_cmd = *packet_cmd;
- } else {
- strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
- }
- result->data->head.payload_size = 0;
- payload_size -= sizeof(*result->data);
-
- va_start(va, fmt);
- result = packet_body_filler(result, payload_size, fmt, va);
- va_end(va);
-
- return packet_ref(result);
+ int payload_size;
+ struct packet *result;
+ va_list va;
+
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
+
+ result = malloc(sizeof(*result));
+ if (!result) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ payload_size = sizeof(*result->data) + BUFSIZ;
+ result->refcnt = 0;
+ result->data = calloc(1, payload_size);
+ if (!packet->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ result->state = INVALID;
+ free(result);
+ return NULL;
+ }
+
+ result->state = VALID;
+ result->data->head.source = packet->data->head.destination;
+ result->data->head.destination = packet->data->head.source;
+ result->data->head.mask = 0xFFFFFFFF;
+
+ result->data->head.seq = packet->data->head.seq;
+ result->data->head.type = PACKET_ACK;
+ result->data->head.version = packet->data->head.version;
+ result->data->head.fd = -1;
+ if (packet->data->head.command[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *head_cmd = (unsigned int *)result->data->head.command;
+ unsigned int *packet_cmd = (unsigned int *)packet->data->head.command;
+
+ *head_cmd = *packet_cmd;
+ } else {
+ strcpy(result->data->head.command, packet->data->head.command); /* we don't need to use strncmp */
+ }
+ result->data->head.payload_size = 0;
+ payload_size -= sizeof(*result->data);
+
+ va_start(va, fmt);
+ result = packet_body_filler(result, payload_size, fmt, va);
+ va_end(va);
+
+ return packet_ref(result);
}
EAPI int packet_swap_address(struct packet *packet)
{
- unsigned long tmp;
+ unsigned long tmp;
- if (!packet || packet->state != VALID) {
- return -EINVAL;
- }
+ if (!packet || packet->state != VALID) {
+ return -EINVAL;
+ }
- tmp = packet->data->head.source;
- packet->data->head.source = packet->data->head.destination;
- packet->data->head.destination = tmp;
+ tmp = packet->data->head.source;
+ packet->data->head.source = packet->data->head.destination;
+ packet->data->head.destination = tmp;
- return 0;
+ return 0;
}
EAPI struct packet *packet_create(const char *cmd, const char *fmt, ...)
{
- struct packet *packet;
- int payload_size;
- va_list va;
-
- if (strlen(cmd) >= PACKET_MAX_CMD) {
- ErrPrint("Command is too long\n");
- return NULL;
- }
-
- packet = malloc(sizeof(*packet));
- if (!packet) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- payload_size = sizeof(*packet->data) + BUFSIZ;
- packet->refcnt = 0;
- packet->data = calloc(1, payload_size);
- if (!packet->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet->state = INVALID;
- free(packet);
- return NULL;
- }
-
- packet->state = VALID;
- packet->data->head.source = 0lu;
- packet->data->head.destination = 0lu;
- packet->data->head.mask = 0xFFFFFFFF;
- packet->data->head.seq = util_timestamp();
- packet->data->head.type = PACKET_REQ;
- packet->data->head.version = PACKET_VERSION;
- if (cmd[0] == PACKET_CMD_INT_TAG) {
- unsigned int *head_cmd = (unsigned int *)packet->data->head.command;
- unsigned int *in_cmd = (unsigned int *)cmd;
-
- *head_cmd = *in_cmd;
- } else {
- strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
- }
- packet->data->head.payload_size = 0;
- payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
-
- va_start(va, fmt);
- packet = packet_body_filler(packet, payload_size, fmt, va);
- va_end(va);
-
- return packet_ref(packet);
+ struct packet *packet;
+ int payload_size;
+ va_list va;
+
+ if (strlen(cmd) >= PACKET_MAX_CMD) {
+ ErrPrint("Command is too long\n");
+ return NULL;
+ }
+
+ packet = malloc(sizeof(*packet));
+ if (!packet) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ payload_size = sizeof(*packet->data) + BUFSIZ;
+ packet->refcnt = 0;
+ packet->data = calloc(1, payload_size);
+ if (!packet->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet->state = INVALID;
+ free(packet);
+ return NULL;
+ }
+
+ packet->state = VALID;
+ packet->data->head.source = 0lu;
+ packet->data->head.destination = 0lu;
+ packet->data->head.mask = 0xFFFFFFFF;
+ packet->data->head.seq = util_timestamp();
+ packet->data->head.type = PACKET_REQ;
+ packet->data->head.version = PACKET_VERSION;
+ packet->data->head.fd = -1;
+ if (cmd[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *head_cmd = (unsigned int *)packet->data->head.command;
+ unsigned int *in_cmd = (unsigned int *)cmd;
+
+ *head_cmd = *in_cmd;
+ } else {
+ strncpy(packet->data->head.command, cmd, sizeof(packet->data->head.command));
+ }
+ packet->data->head.payload_size = 0;
+ payload_size -= sizeof(*packet->data); /*!< Usable payload size (except head size) */
+
+ va_start(va, fmt);
+ packet = packet_body_filler(packet, payload_size, fmt, va);
+ va_end(va);
+
+ return packet_ref(packet);
}
EAPI struct packet *packet_create_noack(const char *cmd, const char *fmt, ...)
{
- int payload_size;
- struct packet *result;
- va_list va;
-
- if (strlen(cmd) >= PACKET_MAX_CMD) {
- ErrPrint("Command is too long\n");
- return NULL;
- }
-
- result = malloc(sizeof(*result));
- if (!result) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- payload_size = sizeof(*result->data) + BUFSIZ;
- result->refcnt = 0;
- result->data = calloc(1, payload_size);
- if (!result->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- result->state = INVALID;
- free(result);
- return NULL;
- }
-
- result->state = VALID;
- result->data->head.source = 0lu;
- result->data->head.destination = 0lu;
- result->data->head.mask = 0xFFFFFFFF;
- result->data->head.seq = util_timestamp();
- result->data->head.type = PACKET_REQ_NOACK;
- result->data->head.version = PACKET_VERSION;
- if (cmd[0] == PACKET_CMD_INT_TAG) {
- unsigned int *head_cmd = (unsigned int *)result->data->head.command;
- unsigned int *cmd_in = (unsigned int *)cmd;
- *head_cmd = *cmd_in;
- } else {
- strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
- }
- result->data->head.payload_size = 0;
- payload_size -= sizeof(*result->data);
-
- va_start(va, fmt);
- result = packet_body_filler(result, payload_size, fmt, va);
- va_end(va);
-
- return packet_ref(result);
+ int payload_size;
+ struct packet *result;
+ va_list va;
+
+ if (strlen(cmd) >= PACKET_MAX_CMD) {
+ ErrPrint("Command is too long\n");
+ return NULL;
+ }
+
+ result = malloc(sizeof(*result));
+ if (!result) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ payload_size = sizeof(*result->data) + BUFSIZ;
+ result->refcnt = 0;
+ result->data = calloc(1, payload_size);
+ if (!result->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ result->state = INVALID;
+ free(result);
+ return NULL;
+ }
+
+ result->state = VALID;
+ result->data->head.source = 0lu;
+ result->data->head.destination = 0lu;
+ result->data->head.mask = 0xFFFFFFFF;
+ result->data->head.seq = util_timestamp();
+ result->data->head.type = PACKET_REQ_NOACK;
+ result->data->head.version = PACKET_VERSION;
+ result->data->head.fd = -1;
+ if (cmd[0] == PACKET_CMD_INT_TAG) {
+ unsigned int *head_cmd = (unsigned int *)result->data->head.command;
+ unsigned int *cmd_in = (unsigned int *)cmd;
+ *head_cmd = *cmd_in;
+ } else {
+ strncpy(result->data->head.command, cmd, sizeof(result->data->head.command));
+ }
+ result->data->head.payload_size = 0;
+ payload_size -= sizeof(*result->data);
+
+ va_start(va, fmt);
+ result = packet_body_filler(result, payload_size, fmt, va);
+ va_end(va);
+
+ return packet_ref(result);
}
EAPI int packet_get(const struct packet *packet, const char *fmt, ...)
{
- const char *ptr;
- va_list va;
- int ret = 0;
- char *payload;
- int offset = 0;
- int *int_ptr;
- double *double_ptr;
- char **str_ptr;
- int align;
-
- if (!packet || packet->state != VALID) {
- return -EINVAL;
- }
+ const char *ptr;
+ va_list va;
+ int ret = 0;
+ char *payload;
+ int offset = 0;
+ int *int_ptr;
+ double *double_ptr;
+ char **str_ptr;
+ int align;
+
+ if (!packet || packet->state != VALID) {
+ return -EINVAL;
+ }
+
+ va_start(va, fmt);
+
+ ptr = fmt;
+ while (*ptr && offset < packet->data->head.payload_size) {
+ payload = packet->data->payload + offset;
+ switch (*ptr) {
+ case 'i':
+ case 'I':
+ align = (unsigned long)payload & (sizeof(int) - 1);
+ if (align) {
+ align = sizeof(int) - align;
+ }
- va_start(va, fmt);
-
- ptr = fmt;
- while (*ptr && offset < packet->data->head.payload_size) {
- payload = packet->data->payload + offset;
- switch (*ptr) {
- case 'i':
- case 'I':
- align = (unsigned long)payload & (sizeof(int) - 1);
- if (align) {
- align = sizeof(int) - align;
- }
-
- int_ptr = (int *)va_arg(va, int *);
- *int_ptr = *((int *)(payload + align));
- offset += (sizeof(int) + align);
- ret++;
- break;
- case 'd':
- case 'D':
- align = (unsigned long)payload & (sizeof(double) - 1);
- if (align) {
- align = sizeof(double) - align;
- }
- double_ptr = (double *)va_arg(va, double *);
- *double_ptr = *((double *)(payload + align));
- offset += (sizeof(double) + align);
- ret++;
- break;
- case 's':
- case 'S':
- str_ptr = (char **)va_arg(va, char **);
- *str_ptr = payload;
- offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
- ret++;
- break;
- default:
- ret = -EINVAL;
- goto out;
+ int_ptr = (int *)va_arg(va, int *);
+ *int_ptr = *((int *)(payload + align));
+ offset += (sizeof(int) + align);
+ ret++;
+ break;
+ case 'd':
+ case 'D':
+ align = (unsigned long)payload & (sizeof(double) - 1);
+ if (align) {
+ align = sizeof(double) - align;
}
- ptr++;
- }
+ double_ptr = (double *)va_arg(va, double *);
+ *double_ptr = *((double *)(payload + align));
+ offset += (sizeof(double) + align);
+ ret++;
+ break;
+ case 's':
+ case 'S':
+ str_ptr = (char **)va_arg(va, char **);
+ *str_ptr = payload;
+ offset += (strlen(*str_ptr) + 1); /*!< Including NIL */
+ ret++;
+ break;
+ default:
+ ret = -EINVAL;
+ goto out;
+ }
+ ptr++;
+ }
out:
- va_end(va);
- return ret;
+ va_end(va);
+ return ret;
}
EAPI struct packet *packet_ref(struct packet *packet)
{
- if (!packet || packet->state != VALID) {
- return NULL;
- }
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
- packet->refcnt++;
- return packet;
+ packet->refcnt++;
+ return packet;
}
EAPI struct packet *packet_unref(struct packet *packet)
{
- if (!packet || packet->state != VALID) {
- return NULL;
- }
-
- packet->refcnt--;
- if (packet->refcnt < 0) {
- ErrPrint("Invalid refcnt\n");
- return NULL;
- }
-
- if (packet->refcnt == 0) {
- packet->state = INVALID;
- free(packet->data);
- free(packet);
- return NULL;
- }
-
- return packet;
+ if (!packet || packet->state != VALID) {
+ return NULL;
+ }
+
+ packet->refcnt--;
+ if (packet->refcnt < 0) {
+ ErrPrint("Invalid refcnt\n");
+ return NULL;
+ }
+
+ if (packet->refcnt == 0) {
+ packet->state = INVALID;
+ free(packet->data);
+ free(packet);
+ return NULL;
+ }
+
+ return packet;
}
EAPI int packet_destroy(struct packet *packet)
{
- packet_unref(packet);
- return 0;
+ packet_unref(packet);
+ return 0;
}
EAPI struct packet *packet_build(struct packet *packet, int offset, void *data, int size)
{
- char *ptr;
-
- if (packet == NULL) {
- if (offset) {
- ErrPrint("Invalid argument\n");
- return NULL;
- }
-
- packet = malloc(sizeof(*packet));
- if (!packet) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
+ char *ptr;
- packet->refcnt = 1;
- packet->data = calloc(1, size);
- if (!packet->data) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet->state = INVALID;
- free(packet);
- return NULL;
- }
-
- packet->state = VALID;
- memcpy(packet->data, data, size);
- packet->data->head.mask = 0xFFFFFFFF;
- return packet;
+ if (packet == NULL) {
+ if (offset) {
+ ErrPrint("Invalid argument\n");
+ return NULL;
}
- ptr = realloc(packet->data, offset + size);
- if (!ptr) {
- ErrPrint("Heap: %s\n", strerror(errno));
- packet->state = INVALID;
- free(packet->data);
- free(packet);
- return NULL;
+ packet = malloc(sizeof(*packet));
+ if (!packet) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
}
- packet->data = (struct data *)ptr;
- memcpy(ptr + offset, data, size);
+ packet->refcnt = 1;
+ packet->data = calloc(1, size);
+ if (!packet->data) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet->state = INVALID;
+ free(packet);
+ return NULL;
+ }
+ packet->state = VALID;
+ memcpy(packet->data, data, size);
+ packet->data->head.mask = 0xFFFFFFFF;
return packet;
+ }
+
+ ptr = realloc(packet->data, offset + size);
+ if (!ptr) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ packet->state = INVALID;
+ free(packet->data);
+ free(packet);
+ return NULL;
+ }
+
+ packet->data = (struct data *)ptr;
+ memcpy(ptr + offset, data, size);
+
+ return packet;
}
/* End of a file */