From db86a3b1a55eb9e47e547bc17205c5cbaec96d2f Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 1 Feb 2018 02:09:35 +0000 Subject: [PATCH] rmtfs: Migrate to new QMI encoder/decoder library Utilize the QMI encoder/decoder functions being part of libqrtr instead of rolling our own. Signed-off-by: Bjorn Andersson --- Makefile | 2 +- qmi_rmtfs.c | 846 ++++++++++++++++------------------------------------ qmi_rmtfs.h | 213 ++++--------- rmtfs.c | 423 ++++++++++++-------------- 4 files changed, 508 insertions(+), 976 deletions(-) diff --git a/Makefile b/Makefile index 403d562..0fdb279 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CFLAGS := -Wall -g -I../qrtr/lib -O2 LDFLAGS := -L../qrtr -lqrtr -ludev prefix := /usr/local -SRCS := qmi_rmtfs.c qmi_tlv.c rmtfs.c sharedmem.c storage.c util.c +SRCS := qmi_rmtfs.c rmtfs.c sharedmem.c storage.c util.c OBJS := $(SRCS:.c=.o) $(OUT): $(OBJS) diff --git a/qmi_rmtfs.c b/qmi_rmtfs.c index 095e5ab..bda2b78 100644 --- a/qmi_rmtfs.c +++ b/qmi_rmtfs.c @@ -2,599 +2,255 @@ #include #include "qmi_rmtfs.h" -struct rmtfs_open_req *rmtfs_open_req_alloc(unsigned txn) -{ - return (struct rmtfs_open_req*)qmi_tlv_init(txn, 1, 0); -} - -struct rmtfs_open_req *rmtfs_open_req_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_open_req*)qmi_tlv_decode(buf, len, txn, 0); -} - -void *rmtfs_open_req_encode(struct rmtfs_open_req *open_req, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)open_req, len); -} - -void rmtfs_open_req_free(struct rmtfs_open_req *open_req) -{ - qmi_tlv_free((struct qmi_tlv*)open_req); -} - -int rmtfs_open_req_set_path(struct rmtfs_open_req *open_req, char *buf, size_t len) -{ - return qmi_tlv_set((struct qmi_tlv*)open_req, 1, buf, len); -} - -int rmtfs_open_req_get_path(struct rmtfs_open_req *open_req, char *buf, size_t buflen) -{ - size_t len; - char *ptr; - - ptr = qmi_tlv_get((struct qmi_tlv*)open_req, 1, &len); - if (!ptr) - return -ENOENT; - - if (len >= buflen) - return -ENOMEM; - - memcpy(buf, ptr, len); - buf[len] = '\0'; - return len; -} - -struct rmtfs_open_resp *rmtfs_open_resp_alloc(unsigned txn) -{ - return (struct rmtfs_open_resp*)qmi_tlv_init(txn, 1, 2); -} - -struct rmtfs_open_resp *rmtfs_open_resp_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_open_resp*)qmi_tlv_decode(buf, len, txn, 2); -} - -void *rmtfs_open_resp_encode(struct rmtfs_open_resp *open_resp, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)open_resp, len); -} - -void rmtfs_open_resp_free(struct rmtfs_open_resp *open_resp) -{ - qmi_tlv_free((struct qmi_tlv*)open_resp); -} - -int rmtfs_open_resp_set_result(struct rmtfs_open_resp *open_resp, struct rmtfs_qmi_result *val) -{ - return qmi_tlv_set((struct qmi_tlv*)open_resp, 2, val, sizeof(struct rmtfs_qmi_result)); -} - -struct rmtfs_qmi_result *rmtfs_open_resp_get_result(struct rmtfs_open_resp *open_resp) -{ - size_t len; - void *ptr; - - ptr = qmi_tlv_get((struct qmi_tlv*)open_resp, 2, &len); - if (!ptr) - return NULL; - - if (len != sizeof(struct rmtfs_qmi_result)) - return NULL; - - return ptr; -} - -int rmtfs_open_resp_set_caller_id(struct rmtfs_open_resp *open_resp, uint32_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)open_resp, 16, &val, sizeof(uint32_t)); -} - -int rmtfs_open_resp_get_caller_id(struct rmtfs_open_resp *open_resp, uint32_t *val) -{ - uint32_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)open_resp, 16, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint32_t)) - return -EINVAL; - - *val = *(uint32_t*)ptr; - return 0; -} - -struct rmtfs_close_req *rmtfs_close_req_alloc(unsigned txn) -{ - return (struct rmtfs_close_req*)qmi_tlv_init(txn, 2, 0); -} - -struct rmtfs_close_req *rmtfs_close_req_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_close_req*)qmi_tlv_decode(buf, len, txn, 0); -} - -void *rmtfs_close_req_encode(struct rmtfs_close_req *close_req, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)close_req, len); -} - -void rmtfs_close_req_free(struct rmtfs_close_req *close_req) -{ - qmi_tlv_free((struct qmi_tlv*)close_req); -} - -int rmtfs_close_req_set_caller_id(struct rmtfs_close_req *close_req, uint32_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)close_req, 1, &val, sizeof(uint32_t)); -} - -int rmtfs_close_req_get_caller_id(struct rmtfs_close_req *close_req, uint32_t *val) -{ - uint32_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)close_req, 1, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint32_t)) - return -EINVAL; - - *val = *(uint32_t*)ptr; - return 0; -} - -struct rmtfs_close_resp *rmtfs_close_resp_alloc(unsigned txn) -{ - return (struct rmtfs_close_resp*)qmi_tlv_init(txn, 2, 2); -} - -struct rmtfs_close_resp *rmtfs_close_resp_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_close_resp*)qmi_tlv_decode(buf, len, txn, 2); -} - -void *rmtfs_close_resp_encode(struct rmtfs_close_resp *close_resp, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)close_resp, len); -} - -void rmtfs_close_resp_free(struct rmtfs_close_resp *close_resp) -{ - qmi_tlv_free((struct qmi_tlv*)close_resp); -} - -int rmtfs_close_resp_set_result(struct rmtfs_close_resp *close_resp, struct rmtfs_qmi_result *val) -{ - return qmi_tlv_set((struct qmi_tlv*)close_resp, 2, val, sizeof(struct rmtfs_qmi_result)); -} - -struct rmtfs_qmi_result *rmtfs_close_resp_get_result(struct rmtfs_close_resp *close_resp) -{ - size_t len; - void *ptr; - - ptr = qmi_tlv_get((struct qmi_tlv*)close_resp, 2, &len); - if (!ptr) - return NULL; - - if (len != sizeof(struct rmtfs_qmi_result)) - return NULL; - - return ptr; -} - -struct rmtfs_iovec_req *rmtfs_iovec_req_alloc(unsigned txn) -{ - return (struct rmtfs_iovec_req*)qmi_tlv_init(txn, 3, 0); -} - -struct rmtfs_iovec_req *rmtfs_iovec_req_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_iovec_req*)qmi_tlv_decode(buf, len, txn, 0); -} - -void *rmtfs_iovec_req_encode(struct rmtfs_iovec_req *iovec_req, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)iovec_req, len); -} - -void rmtfs_iovec_req_free(struct rmtfs_iovec_req *iovec_req) -{ - qmi_tlv_free((struct qmi_tlv*)iovec_req); -} - -int rmtfs_iovec_req_set_caller_id(struct rmtfs_iovec_req *iovec_req, uint32_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)iovec_req, 1, &val, sizeof(uint32_t)); -} - -int rmtfs_iovec_req_get_caller_id(struct rmtfs_iovec_req *iovec_req, uint32_t *val) -{ - uint32_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)iovec_req, 1, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint32_t)) - return -EINVAL; - - *val = *(uint32_t*)ptr; - return 0; -} - -int rmtfs_iovec_req_set_direction(struct rmtfs_iovec_req *iovec_req, uint8_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)iovec_req, 2, &val, sizeof(uint8_t)); -} - -int rmtfs_iovec_req_get_direction(struct rmtfs_iovec_req *iovec_req, uint8_t *val) -{ - uint8_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)iovec_req, 2, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint8_t)) - return -EINVAL; - - *val = *(uint8_t*)ptr; - return 0; -} - -int rmtfs_iovec_req_set_iovec(struct rmtfs_iovec_req *iovec_req, struct rmtfs_iovec_entry *val, size_t count) -{ - return qmi_tlv_set_array((struct qmi_tlv*)iovec_req, 3, 1, val, count, sizeof(struct rmtfs_iovec_entry)); -} - -struct rmtfs_iovec_entry *rmtfs_iovec_req_get_iovec(struct rmtfs_iovec_req *iovec_req, size_t *count) -{ - size_t size; - size_t len; - void *ptr; - - ptr = qmi_tlv_get_array((struct qmi_tlv*)iovec_req, 3, 1, &len, &size); - if (!ptr) - return NULL; - - if (size != sizeof(struct rmtfs_iovec_entry)) - return NULL; - - *count = len; - return ptr; -} - -int rmtfs_iovec_req_set_is_force_sync(struct rmtfs_iovec_req *iovec_req, uint8_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)iovec_req, 4, &val, sizeof(uint8_t)); -} - -int rmtfs_iovec_req_get_is_force_sync(struct rmtfs_iovec_req *iovec_req, uint8_t *val) -{ - uint8_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)iovec_req, 4, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint8_t)) - return -EINVAL; - - *val = *(uint8_t*)ptr; - return 0; -} - -struct rmtfs_iovec_resp *rmtfs_iovec_resp_alloc(unsigned txn) -{ - return (struct rmtfs_iovec_resp*)qmi_tlv_init(txn, 3, 2); -} - -struct rmtfs_iovec_resp *rmtfs_iovec_resp_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_iovec_resp*)qmi_tlv_decode(buf, len, txn, 2); -} - -void *rmtfs_iovec_resp_encode(struct rmtfs_iovec_resp *iovec_resp, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)iovec_resp, len); -} - -void rmtfs_iovec_resp_free(struct rmtfs_iovec_resp *iovec_resp) -{ - qmi_tlv_free((struct qmi_tlv*)iovec_resp); -} - -int rmtfs_iovec_resp_set_result(struct rmtfs_iovec_resp *iovec_resp, struct rmtfs_qmi_result *val) -{ - return qmi_tlv_set((struct qmi_tlv*)iovec_resp, 2, val, sizeof(struct rmtfs_qmi_result)); -} - -struct rmtfs_qmi_result *rmtfs_iovec_resp_get_result(struct rmtfs_iovec_resp *iovec_resp) -{ - size_t len; - void *ptr; - - ptr = qmi_tlv_get((struct qmi_tlv*)iovec_resp, 2, &len); - if (!ptr) - return NULL; - - if (len != sizeof(struct rmtfs_qmi_result)) - return NULL; - - return ptr; -} - -struct rmtfs_alloc_buf_req *rmtfs_alloc_buf_req_alloc(unsigned txn) -{ - return (struct rmtfs_alloc_buf_req*)qmi_tlv_init(txn, 4, 0); -} - -struct rmtfs_alloc_buf_req *rmtfs_alloc_buf_req_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_alloc_buf_req*)qmi_tlv_decode(buf, len, txn, 0); -} - -void *rmtfs_alloc_buf_req_encode(struct rmtfs_alloc_buf_req *alloc_buf_req, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)alloc_buf_req, len); -} - -void rmtfs_alloc_buf_req_free(struct rmtfs_alloc_buf_req *alloc_buf_req) -{ - qmi_tlv_free((struct qmi_tlv*)alloc_buf_req); -} - -int rmtfs_alloc_buf_req_set_caller_id(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)alloc_buf_req, 1, &val, sizeof(uint32_t)); -} - -int rmtfs_alloc_buf_req_get_caller_id(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t *val) -{ - uint32_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)alloc_buf_req, 1, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint32_t)) - return -EINVAL; - - *val = *(uint32_t*)ptr; - return 0; -} - -int rmtfs_alloc_buf_req_set_buff_size(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)alloc_buf_req, 2, &val, sizeof(uint32_t)); -} - -int rmtfs_alloc_buf_req_get_buff_size(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t *val) -{ - uint32_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)alloc_buf_req, 2, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint32_t)) - return -EINVAL; - - *val = *(uint32_t*)ptr; - return 0; -} - -struct rmtfs_alloc_buf_resp *rmtfs_alloc_buf_resp_alloc(unsigned txn) -{ - return (struct rmtfs_alloc_buf_resp*)qmi_tlv_init(txn, 4, 2); -} - -struct rmtfs_alloc_buf_resp *rmtfs_alloc_buf_resp_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_alloc_buf_resp*)qmi_tlv_decode(buf, len, txn, 2); -} - -void *rmtfs_alloc_buf_resp_encode(struct rmtfs_alloc_buf_resp *alloc_buf_resp, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)alloc_buf_resp, len); -} - -void rmtfs_alloc_buf_resp_free(struct rmtfs_alloc_buf_resp *alloc_buf_resp) -{ - qmi_tlv_free((struct qmi_tlv*)alloc_buf_resp); -} - -int rmtfs_alloc_buf_resp_set_result(struct rmtfs_alloc_buf_resp *alloc_buf_resp, struct rmtfs_qmi_result *val) -{ - return qmi_tlv_set((struct qmi_tlv*)alloc_buf_resp, 2, val, sizeof(struct rmtfs_qmi_result)); -} - -struct rmtfs_qmi_result *rmtfs_alloc_buf_resp_get_result(struct rmtfs_alloc_buf_resp *alloc_buf_resp) -{ - size_t len; - void *ptr; - - ptr = qmi_tlv_get((struct qmi_tlv*)alloc_buf_resp, 2, &len); - if (!ptr) - return NULL; - - if (len != sizeof(struct rmtfs_qmi_result)) - return NULL; - - return ptr; -} - -int rmtfs_alloc_buf_resp_set_buff_address(struct rmtfs_alloc_buf_resp *alloc_buf_resp, uint64_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)alloc_buf_resp, 16, &val, sizeof(uint64_t)); -} - -int rmtfs_alloc_buf_resp_get_buff_address(struct rmtfs_alloc_buf_resp *alloc_buf_resp, uint64_t *val) -{ - uint64_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)alloc_buf_resp, 16, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint64_t)) - return -EINVAL; - - *val = *(uint64_t*)ptr; - return 0; -} - -struct rmtfs_dev_error_req *rmtfs_dev_error_req_alloc(unsigned txn) -{ - return (struct rmtfs_dev_error_req*)qmi_tlv_init(txn, 5, 0); -} - -struct rmtfs_dev_error_req *rmtfs_dev_error_req_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_dev_error_req*)qmi_tlv_decode(buf, len, txn, 0); -} - -void *rmtfs_dev_error_req_encode(struct rmtfs_dev_error_req *dev_error_req, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)dev_error_req, len); -} - -void rmtfs_dev_error_req_free(struct rmtfs_dev_error_req *dev_error_req) -{ - qmi_tlv_free((struct qmi_tlv*)dev_error_req); -} - -int rmtfs_dev_error_req_set_caller_id(struct rmtfs_dev_error_req *dev_error_req, uint32_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)dev_error_req, 1, &val, sizeof(uint32_t)); -} - -int rmtfs_dev_error_req_get_caller_id(struct rmtfs_dev_error_req *dev_error_req, uint32_t *val) -{ - uint32_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)dev_error_req, 1, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint32_t)) - return -EINVAL; - - *val = *(uint32_t*)ptr; - return 0; -} - -struct rmtfs_dev_error_resp *rmtfs_dev_error_resp_alloc(unsigned txn) -{ - return (struct rmtfs_dev_error_resp*)qmi_tlv_init(txn, 5, 2); -} - -struct rmtfs_dev_error_resp *rmtfs_dev_error_resp_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_dev_error_resp*)qmi_tlv_decode(buf, len, txn, 2); -} - -void *rmtfs_dev_error_resp_encode(struct rmtfs_dev_error_resp *dev_error_resp, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)dev_error_resp, len); -} - -void rmtfs_dev_error_resp_free(struct rmtfs_dev_error_resp *dev_error_resp) -{ - qmi_tlv_free((struct qmi_tlv*)dev_error_resp); -} - -int rmtfs_dev_error_resp_set_result(struct rmtfs_dev_error_resp *dev_error_resp, struct rmtfs_qmi_result *val) -{ - return qmi_tlv_set((struct qmi_tlv*)dev_error_resp, 2, val, sizeof(struct rmtfs_qmi_result)); -} - -struct rmtfs_qmi_result *rmtfs_dev_error_resp_get_result(struct rmtfs_dev_error_resp *dev_error_resp) -{ - size_t len; - void *ptr; - - ptr = qmi_tlv_get((struct qmi_tlv*)dev_error_resp, 2, &len); - if (!ptr) - return NULL; - - if (len != sizeof(struct rmtfs_qmi_result)) - return NULL; - - return ptr; -} - -int rmtfs_dev_error_resp_set_status(struct rmtfs_dev_error_resp *dev_error_resp, uint8_t val) -{ - return qmi_tlv_set((struct qmi_tlv*)dev_error_resp, 16, &val, sizeof(uint8_t)); -} - -int rmtfs_dev_error_resp_get_status(struct rmtfs_dev_error_resp *dev_error_resp, uint8_t *val) -{ - uint8_t *ptr; - size_t len; - - ptr = qmi_tlv_get((struct qmi_tlv*)dev_error_resp, 16, &len); - if (!ptr) - return -ENOENT; - - if (len != sizeof(uint8_t)) - return -EINVAL; - - *val = *(uint8_t*)ptr; - return 0; -} - -struct rmtfs_force_sync *rmtfs_force_sync_alloc(unsigned txn) -{ - return (struct rmtfs_force_sync*)qmi_tlv_init(txn, 6, 4); -} - -struct rmtfs_force_sync *rmtfs_force_sync_parse(void *buf, size_t len, unsigned *txn) -{ - return (struct rmtfs_force_sync*)qmi_tlv_decode(buf, len, txn, 4); -} - -void *rmtfs_force_sync_encode(struct rmtfs_force_sync *force_sync, size_t *len) -{ - return qmi_tlv_encode((struct qmi_tlv*)force_sync, len); -} - -void rmtfs_force_sync_free(struct rmtfs_force_sync *force_sync) -{ - qmi_tlv_free((struct qmi_tlv*)force_sync); -} - -int rmtfs_force_sync_set_caller_id(struct rmtfs_force_sync *force_sync, uint32_t *val, size_t count) -{ - return qmi_tlv_set_array((struct qmi_tlv*)force_sync, 1, 1, val, count, sizeof(uint32_t)); -} - -uint32_t *rmtfs_force_sync_get_caller_id(struct rmtfs_force_sync *force_sync, size_t *count) -{ - uint32_t *ptr; - size_t size; - size_t len; - - ptr = qmi_tlv_get_array((struct qmi_tlv*)force_sync, 1, 1, &len, &size); - if (!ptr) - return NULL; - - if (size != sizeof(uint32_t)) - return NULL; - - *count = len; - return ptr; -} +struct qmi_elem_info rmtfs_qmi_result_ei[] = { + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint16_t), + .offset = offsetof(struct rmtfs_qmi_result, result), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint16_t), + .offset = offsetof(struct rmtfs_qmi_result, error), + }, + {} +}; + +struct qmi_elem_info rmtfs_iovec_entry_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .offset = offsetof(struct rmtfs_iovec_entry, sector_addr), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .offset = offsetof(struct rmtfs_iovec_entry, phys_offset), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .offset = offsetof(struct rmtfs_iovec_entry, num_sector), + }, + {} +}; + +struct qmi_elem_info rmtfs_open_req_ei[] = { + { + .data_type = QMI_STRING, + .elem_len = 256, + .elem_size = sizeof(char), + .array_type = VAR_LEN_ARRAY, + .tlv_type = 1, + .offset = offsetof(struct rmtfs_open_req, path) + }, + {} +}; + +struct qmi_elem_info rmtfs_open_resp_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct rmtfs_qmi_result), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_open_resp, result), + .ei_array = rmtfs_qmi_result_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(bool), + .tlv_type = 16, + .offset = offsetof(struct rmtfs_open_resp, caller_id_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .tlv_type = 16, + .offset = offsetof(struct rmtfs_open_resp, caller_id), + }, + {} +}; + +struct qmi_elem_info rmtfs_close_req_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .tlv_type = 1, + .offset = offsetof(struct rmtfs_close_req, caller_id), + }, + {} +}; + +struct qmi_elem_info rmtfs_close_resp_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct rmtfs_qmi_result), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_close_resp, result), + .ei_array = rmtfs_qmi_result_ei, + }, + {} +}; + +struct qmi_elem_info rmtfs_iovec_req_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .tlv_type = 1, + .offset = offsetof(struct rmtfs_iovec_req, caller_id), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_iovec_req, direction), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .tlv_type = 3, + .offset = offsetof(struct rmtfs_iovec_req, iovec_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = 255, + .elem_size = sizeof(struct rmtfs_iovec_entry), + .array_type = VAR_LEN_ARRAY, + .tlv_type = 3, + .offset = offsetof(struct rmtfs_iovec_req, iovec), + .ei_array = rmtfs_iovec_entry_ei, + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .tlv_type = 4, + .offset = offsetof(struct rmtfs_iovec_req, is_force_sync), + }, + {} +}; + +struct qmi_elem_info rmtfs_iovec_resp_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct rmtfs_qmi_result), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_iovec_resp, result), + .ei_array = rmtfs_qmi_result_ei, + }, + {} +}; + +struct qmi_elem_info rmtfs_alloc_buf_req_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .tlv_type = 1, + .offset = offsetof(struct rmtfs_alloc_buf_req, caller_id), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_alloc_buf_req, buff_size), + }, + {} +}; + +struct qmi_elem_info rmtfs_alloc_buf_resp_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct rmtfs_qmi_result), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_alloc_buf_resp, result), + .ei_array = rmtfs_qmi_result_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(bool), + .tlv_type = 16, + .offset = offsetof(struct rmtfs_alloc_buf_resp, buff_address_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint64_t), + .tlv_type = 16, + .offset = offsetof(struct rmtfs_alloc_buf_resp, buff_address), + }, + {} +}; + +struct qmi_elem_info rmtfs_dev_error_req_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint32_t), + .tlv_type = 1, + .offset = offsetof(struct rmtfs_dev_error_req, caller_id), + }, + {} +}; + +struct qmi_elem_info rmtfs_dev_error_resp_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct rmtfs_qmi_result), + .tlv_type = 2, + .offset = offsetof(struct rmtfs_dev_error_resp, result), + .ei_array = rmtfs_qmi_result_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(bool), + .tlv_type = 16, + .offset = offsetof(struct rmtfs_dev_error_resp, status_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .tlv_type = 16, + .offset = offsetof(struct rmtfs_dev_error_resp, status), + }, + {} +}; + +struct qmi_elem_info rmtfs_force_sync_ei[] = { + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .tlv_type = 1, + .offset = offsetof(struct rmtfs_force_sync, caller_id_len), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 10, + .elem_size = sizeof(uint32_t), + .array_type = VAR_LEN_ARRAY, + .tlv_type = 1, + .offset = offsetof(struct rmtfs_force_sync, caller_id), + }, + {} +}; diff --git a/qmi_rmtfs.h b/qmi_rmtfs.h index bcb989f..03cbc8f 100644 --- a/qmi_rmtfs.h +++ b/qmi_rmtfs.h @@ -2,19 +2,9 @@ #define __QMI_RMTFS_H__ #include -#include +#include -struct qmi_tlv; - -struct qmi_tlv *qmi_tlv_init(unsigned txn, unsigned msg_id, unsigned type); -struct qmi_tlv *qmi_tlv_decode(void *buf, size_t len, unsigned *txn, unsigned type); -void *qmi_tlv_encode(struct qmi_tlv *tlv, size_t *len); -void qmi_tlv_free(struct qmi_tlv *tlv); - -void *qmi_tlv_get(struct qmi_tlv *tlv, unsigned id, size_t *len); -void *qmi_tlv_get_array(struct qmi_tlv *tlv, unsigned id, unsigned len_size, size_t *len, size_t *size); -int qmi_tlv_set(struct qmi_tlv *tlv, unsigned id, void *buf, size_t len); -int qmi_tlv_set_array(struct qmi_tlv *tlv, unsigned id, unsigned len_size, void *buf, size_t len, size_t size); +#include "libqrtr.h" #define QMI_RMTFS_RESULT_SUCCESS 0 #define QMI_RMTFS_RESULT_FAILURE 1 @@ -39,158 +29,73 @@ struct rmtfs_iovec_entry { uint32_t num_sector; }; -struct rmtfs_open_req; -struct rmtfs_open_resp; -struct rmtfs_close_req; -struct rmtfs_close_resp; -struct rmtfs_iovec_req; -struct rmtfs_iovec_resp; -struct rmtfs_alloc_buf_req; -struct rmtfs_alloc_buf_resp; -struct rmtfs_dev_error_req; -struct rmtfs_dev_error_resp; -struct rmtfs_force_sync; +struct rmtfs_open_req { + uint32_t path_len; + char path[256]; +}; -/* - * rmtfs_open_req message - */ -struct rmtfs_open_req *rmtfs_open_req_alloc(unsigned txn); -struct rmtfs_open_req *rmtfs_open_req_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_open_req_encode(struct rmtfs_open_req *open_req, size_t *len); -void rmtfs_open_req_free(struct rmtfs_open_req *open_req); +struct rmtfs_open_resp { + struct rmtfs_qmi_result result; + bool caller_id_valid; + uint32_t caller_id; +}; -int rmtfs_open_req_set_path(struct rmtfs_open_req *open_req, char *buf, size_t len); -int rmtfs_open_req_get_path(struct rmtfs_open_req *open_req, char *buf, size_t buflen); +struct rmtfs_close_req { + uint32_t caller_id; +}; -/* - * rmtfs_open_resp message - */ -struct rmtfs_open_resp *rmtfs_open_resp_alloc(unsigned txn); -struct rmtfs_open_resp *rmtfs_open_resp_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_open_resp_encode(struct rmtfs_open_resp *open_resp, size_t *len); -void rmtfs_open_resp_free(struct rmtfs_open_resp *open_resp); +struct rmtfs_close_resp { + struct rmtfs_qmi_result result; +}; -int rmtfs_open_resp_set_result(struct rmtfs_open_resp *open_resp, struct rmtfs_qmi_result *val); -struct rmtfs_qmi_result *rmtfs_open_resp_get_result(struct rmtfs_open_resp *open_resp); +struct rmtfs_iovec_req { + uint32_t caller_id; + uint8_t direction; + size_t iovec_len; + struct rmtfs_iovec_entry iovec[255]; + uint8_t is_force_sync; +}; -int rmtfs_open_resp_set_caller_id(struct rmtfs_open_resp *open_resp, uint32_t val); -int rmtfs_open_resp_get_caller_id(struct rmtfs_open_resp *open_resp, uint32_t *val); +struct rmtfs_iovec_resp { + struct rmtfs_qmi_result result; +}; -/* - * rmtfs_close_req message - */ -struct rmtfs_close_req *rmtfs_close_req_alloc(unsigned txn); -struct rmtfs_close_req *rmtfs_close_req_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_close_req_encode(struct rmtfs_close_req *close_req, size_t *len); -void rmtfs_close_req_free(struct rmtfs_close_req *close_req); +struct rmtfs_alloc_buf_req { + uint32_t caller_id; + uint32_t buff_size; +}; -int rmtfs_close_req_set_caller_id(struct rmtfs_close_req *close_req, uint32_t val); -int rmtfs_close_req_get_caller_id(struct rmtfs_close_req *close_req, uint32_t *val); +struct rmtfs_alloc_buf_resp { + struct rmtfs_qmi_result result; + bool buff_address_valid; + uint64_t buff_address; +}; -/* - * rmtfs_close_resp message - */ -struct rmtfs_close_resp *rmtfs_close_resp_alloc(unsigned txn); -struct rmtfs_close_resp *rmtfs_close_resp_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_close_resp_encode(struct rmtfs_close_resp *close_resp, size_t *len); -void rmtfs_close_resp_free(struct rmtfs_close_resp *close_resp); +struct rmtfs_dev_error_req { + uint32_t caller_id; +}; -int rmtfs_close_resp_set_result(struct rmtfs_close_resp *close_resp, struct rmtfs_qmi_result *val); -struct rmtfs_qmi_result *rmtfs_close_resp_get_result(struct rmtfs_close_resp *close_resp); +struct rmtfs_dev_error_resp { + struct rmtfs_qmi_result result; + bool status_valid; + uint8_t status; +}; -/* - * rmtfs_iovec_req message - */ -struct rmtfs_iovec_req *rmtfs_iovec_req_alloc(unsigned txn); -struct rmtfs_iovec_req *rmtfs_iovec_req_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_iovec_req_encode(struct rmtfs_iovec_req *iovec_req, size_t *len); -void rmtfs_iovec_req_free(struct rmtfs_iovec_req *iovec_req); +struct rmtfs_force_sync { + size_t caller_id_len; + uint32_t caller_id[10]; +}; -int rmtfs_iovec_req_set_caller_id(struct rmtfs_iovec_req *iovec_req, uint32_t val); -int rmtfs_iovec_req_get_caller_id(struct rmtfs_iovec_req *iovec_req, uint32_t *val); - -int rmtfs_iovec_req_set_direction(struct rmtfs_iovec_req *iovec_req, uint8_t val); -int rmtfs_iovec_req_get_direction(struct rmtfs_iovec_req *iovec_req, uint8_t *val); - -int rmtfs_iovec_req_set_iovec(struct rmtfs_iovec_req *iovec_req, struct rmtfs_iovec_entry *val, size_t count); -struct rmtfs_iovec_entry *rmtfs_iovec_req_get_iovec(struct rmtfs_iovec_req *iovec_req, size_t *count); - -int rmtfs_iovec_req_set_is_force_sync(struct rmtfs_iovec_req *iovec_req, uint8_t val); -int rmtfs_iovec_req_get_is_force_sync(struct rmtfs_iovec_req *iovec_req, uint8_t *val); - -/* - * rmtfs_iovec_resp message - */ -struct rmtfs_iovec_resp *rmtfs_iovec_resp_alloc(unsigned txn); -struct rmtfs_iovec_resp *rmtfs_iovec_resp_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_iovec_resp_encode(struct rmtfs_iovec_resp *iovec_resp, size_t *len); -void rmtfs_iovec_resp_free(struct rmtfs_iovec_resp *iovec_resp); - -int rmtfs_iovec_resp_set_result(struct rmtfs_iovec_resp *iovec_resp, struct rmtfs_qmi_result *val); -struct rmtfs_qmi_result *rmtfs_iovec_resp_get_result(struct rmtfs_iovec_resp *iovec_resp); - -/* - * rmtfs_alloc_buf_req message - */ -struct rmtfs_alloc_buf_req *rmtfs_alloc_buf_req_alloc(unsigned txn); -struct rmtfs_alloc_buf_req *rmtfs_alloc_buf_req_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_alloc_buf_req_encode(struct rmtfs_alloc_buf_req *alloc_buf_req, size_t *len); -void rmtfs_alloc_buf_req_free(struct rmtfs_alloc_buf_req *alloc_buf_req); - -int rmtfs_alloc_buf_req_set_caller_id(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t val); -int rmtfs_alloc_buf_req_get_caller_id(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t *val); - -int rmtfs_alloc_buf_req_set_buff_size(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t val); -int rmtfs_alloc_buf_req_get_buff_size(struct rmtfs_alloc_buf_req *alloc_buf_req, uint32_t *val); - -/* - * rmtfs_alloc_buf_resp message - */ -struct rmtfs_alloc_buf_resp *rmtfs_alloc_buf_resp_alloc(unsigned txn); -struct rmtfs_alloc_buf_resp *rmtfs_alloc_buf_resp_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_alloc_buf_resp_encode(struct rmtfs_alloc_buf_resp *alloc_buf_resp, size_t *len); -void rmtfs_alloc_buf_resp_free(struct rmtfs_alloc_buf_resp *alloc_buf_resp); - -int rmtfs_alloc_buf_resp_set_result(struct rmtfs_alloc_buf_resp *alloc_buf_resp, struct rmtfs_qmi_result *val); -struct rmtfs_qmi_result *rmtfs_alloc_buf_resp_get_result(struct rmtfs_alloc_buf_resp *alloc_buf_resp); - -int rmtfs_alloc_buf_resp_set_buff_address(struct rmtfs_alloc_buf_resp *alloc_buf_resp, uint64_t val); -int rmtfs_alloc_buf_resp_get_buff_address(struct rmtfs_alloc_buf_resp *alloc_buf_resp, uint64_t *val); - -/* - * rmtfs_dev_error_req message - */ -struct rmtfs_dev_error_req *rmtfs_dev_error_req_alloc(unsigned txn); -struct rmtfs_dev_error_req *rmtfs_dev_error_req_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_dev_error_req_encode(struct rmtfs_dev_error_req *dev_error_req, size_t *len); -void rmtfs_dev_error_req_free(struct rmtfs_dev_error_req *dev_error_req); - -int rmtfs_dev_error_req_set_caller_id(struct rmtfs_dev_error_req *dev_error_req, uint32_t val); -int rmtfs_dev_error_req_get_caller_id(struct rmtfs_dev_error_req *dev_error_req, uint32_t *val); - -/* - * rmtfs_dev_error_resp message - */ -struct rmtfs_dev_error_resp *rmtfs_dev_error_resp_alloc(unsigned txn); -struct rmtfs_dev_error_resp *rmtfs_dev_error_resp_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_dev_error_resp_encode(struct rmtfs_dev_error_resp *dev_error_resp, size_t *len); -void rmtfs_dev_error_resp_free(struct rmtfs_dev_error_resp *dev_error_resp); - -int rmtfs_dev_error_resp_set_result(struct rmtfs_dev_error_resp *dev_error_resp, struct rmtfs_qmi_result *val); -struct rmtfs_qmi_result *rmtfs_dev_error_resp_get_result(struct rmtfs_dev_error_resp *dev_error_resp); - -int rmtfs_dev_error_resp_set_status(struct rmtfs_dev_error_resp *dev_error_resp, uint8_t val); -int rmtfs_dev_error_resp_get_status(struct rmtfs_dev_error_resp *dev_error_resp, uint8_t *val); - -/* - * rmtfs_force_sync message - */ -struct rmtfs_force_sync *rmtfs_force_sync_alloc(unsigned txn); -struct rmtfs_force_sync *rmtfs_force_sync_parse(void *buf, size_t len, unsigned *txn); -void *rmtfs_force_sync_encode(struct rmtfs_force_sync *force_sync, size_t *len); -void rmtfs_force_sync_free(struct rmtfs_force_sync *force_sync); - -int rmtfs_force_sync_set_caller_id(struct rmtfs_force_sync *force_sync, uint32_t *val, size_t count); -uint32_t *rmtfs_force_sync_get_caller_id(struct rmtfs_force_sync *force_sync, size_t *count); +extern struct qmi_elem_info rmtfs_open_req_ei[]; +extern struct qmi_elem_info rmtfs_open_resp_ei[]; +extern struct qmi_elem_info rmtfs_close_req_ei[]; +extern struct qmi_elem_info rmtfs_close_resp_ei[]; +extern struct qmi_elem_info rmtfs_iovec_req_ei[]; +extern struct qmi_elem_info rmtfs_iovec_resp_ei[]; +extern struct qmi_elem_info rmtfs_alloc_buf_req_ei[]; +extern struct qmi_elem_info rmtfs_alloc_buf_resp_ei[]; +extern struct qmi_elem_info rmtfs_dev_error_req_ei[]; +extern struct qmi_elem_info rmtfs_dev_error_resp_ei[]; +extern struct qmi_elem_info rmtfs_force_sync_ei[]; #endif diff --git a/rmtfs.c b/rmtfs.c index b7852e9..5ad5796 100644 --- a/rmtfs.c +++ b/rmtfs.c @@ -21,14 +21,10 @@ #define RMTFS_QMI_VERSION 1 #define RMTFS_QMI_INSTANCE 0 -static struct rmtfs_mem *rmem; +static inline __le32 cpu_to_le32(uint32_t x) { return htole32(x); } +static inline uint32_t le32_to_cpu(__le32 x) { return le32toh(x); } -/* TODO: include from kernel once it lands */ -struct sockaddr_qrtr { - unsigned short sq_family; - uint32_t sq_node; - uint32_t sq_port; -}; +static struct rmtfs_mem *rmem; static bool dbgprintf_enabled; static void dbgprintf(const char *fmt, ...) @@ -53,155 +49,132 @@ static void qmi_result_error(struct rmtfs_qmi_result *result, unsigned error) result->error = error; } -static void rmtfs_open(int sock, unsigned node, unsigned port, void *msg, size_t msg_len) +static void rmtfs_open(int sock, const struct qrtr_packet *pkt) { - struct rmtfs_qmi_result result = {}; - struct rmtfs_open_resp *resp; - struct rmtfs_open_req *req; + struct rmtfs_open_resp resp = {}; + struct rmtfs_open_req req = {}; + DEFINE_QRTR_PACKET(resp_buf, 256); + unsigned int txn; + ssize_t len; int caller_id = -1; - unsigned txn; - size_t len; - void *ptr; - char path[256] = {}; int ret; - req = rmtfs_open_req_parse(msg, msg_len, &txn); - if (!req) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - ret = rmtfs_open_req_get_path(req, path, sizeof(path)); + ret = qmi_decode_message(&req, &txn, pkt, QMI_REQUEST, + QMI_RMTFS_OPEN, rmtfs_open_req_ei); if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_MALFORMED_MSG); goto respond; } - caller_id = storage_get(node, path); - if (caller_id < 0) - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + caller_id = storage_get(pkt->node, req.path); + if (caller_id < 0) { + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); + goto respond; + } + + resp.caller_id = caller_id; + resp.caller_id_valid = true; respond: - dbgprintf("[RMTFS] open %s => %d (%d:%d)\n", path, caller_id, result.result, result.error); + dbgprintf("[RMTFS] open %s => %d (%d:%d)\n", + req.path, caller_id, resp.result.result, resp.result.error); - resp = rmtfs_open_resp_alloc(txn); - rmtfs_open_resp_set_result(resp, &result); - rmtfs_open_resp_set_caller_id(resp, caller_id); - ptr = rmtfs_open_resp_encode(resp, &len); - if (!ptr) - goto free_resp; + len = qmi_encode_message(&resp_buf, + QMI_RESPONSE, QMI_RMTFS_OPEN, txn, &resp, + rmtfs_open_resp_ei); + if (len < 0) { + fprintf(stderr, "[RMTFS] failed to encode open-response: %s\n", + strerror(-len)); + return; + } - ret = qrtr_sendto(sock, node, port, ptr, len); + ret = qrtr_sendto(sock, pkt->node, pkt->port, + resp_buf.data, resp_buf.data_len); if (ret < 0) - fprintf(stderr, "[RMTFS] failed to send open-response: %s\n", strerror(-ret)); - -free_resp: - rmtfs_open_resp_free(resp); - rmtfs_open_req_free(req); + fprintf(stderr, "[RMTFS] failed to send open-response: %s\n", + strerror(-ret)); } -static void rmtfs_close(int sock, unsigned node, unsigned port, void *msg, size_t msg_len) +static void rmtfs_close(int sock, const struct qrtr_packet *pkt) { - struct rmtfs_qmi_result result = {}; - struct rmtfs_close_resp *resp; - struct rmtfs_close_req *req; - uint32_t caller_id; - unsigned txn; - size_t len; - void *ptr; + struct rmtfs_close_resp resp = {}; + struct rmtfs_close_req req = {}; + DEFINE_QRTR_PACKET(resp_buf, 256); + unsigned int txn; + ssize_t len; int ret; - req = rmtfs_close_req_parse(msg, msg_len, &txn); - if (!req) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - ret = rmtfs_close_req_get_caller_id(req, &caller_id); + ret = qmi_decode_message(&req, &txn, pkt, QMI_REQUEST, + QMI_RMTFS_CLOSE, rmtfs_close_req_ei); if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_MALFORMED_MSG); goto respond; } - ret = storage_put(node, caller_id); - if (ret < 0) - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + ret = storage_put(pkt->node, req.caller_id); + if (ret < 0) { + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); + } rmtfs_mem_free(rmem); respond: - dbgprintf("[RMTFS] close %d => (%d:%d)\n", caller_id, result.result, result.error); + dbgprintf("[RMTFS] close %s => %d (%d:%d)\n", + req.caller_id, resp.result.result, resp.result.error); - resp = rmtfs_close_resp_alloc(txn); - rmtfs_close_resp_set_result(resp, &result); - ptr = rmtfs_close_resp_encode(resp, &len); - if (!ptr) - goto free_resp; + len = qmi_encode_message(&resp_buf, + QMI_RESPONSE, QMI_RMTFS_CLOSE, txn, &resp, + rmtfs_close_resp_ei); + if (len < 0) { + fprintf(stderr, "[RMTFS] failed to encode close-response: %s\n", + strerror(-len)); + return; + } - ret = qrtr_sendto(sock, node, port, ptr, len); + ret = qrtr_sendto(sock, pkt->node, pkt->port, + resp_buf.data, resp_buf.data_len); if (ret < 0) - fprintf(stderr, "[RMTFS] failed to send close-response: %s\n", strerror(-ret)); - -free_resp: - rmtfs_close_resp_free(resp); - rmtfs_close_req_free(req); + fprintf(stderr, "[RMTFS] failed to send close-response: %s\n", + strerror(-ret)); } -static void rmtfs_iovec(int sock, unsigned node, unsigned port, void *msg, size_t msg_len) +static void rmtfs_iovec(int sock, struct qrtr_packet *pkt) { struct rmtfs_iovec_entry *entries; - struct rmtfs_qmi_result result = {}; - struct rmtfs_iovec_resp *resp; - struct rmtfs_iovec_req *req; + struct rmtfs_iovec_resp resp = {}; + struct rmtfs_iovec_req req = {}; + DEFINE_QRTR_PACKET(resp_buf, 256); unsigned long phys_offset; - uint32_t caller_id; - size_t num_entries; + uint32_t caller_id = 0; + size_t num_entries = 0; uint8_t is_write; - uint8_t force; + uint8_t force = 0; unsigned txn; + ssize_t len; ssize_t n; - size_t len; - void *ptr; char buf[SECTOR_SIZE]; int ret; int fd; int i; int j; - req = rmtfs_iovec_req_parse(msg, msg_len, &txn); - if (!req) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - ret = rmtfs_iovec_req_get_caller_id(req, &caller_id); + ret = qmi_decode_message(&req, &txn, pkt, QMI_REQUEST, + QMI_RMTFS_RW_IOVEC, rmtfs_iovec_req_ei); if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_MALFORMED_MSG); goto respond; } - ret = rmtfs_iovec_req_get_direction(req, &is_write); - if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } + caller_id = req.caller_id; + is_write = req.direction; + entries = req.iovec; + num_entries = req.iovec_len; + force = req.is_force_sync; - entries = rmtfs_iovec_req_get_iovec(req, &num_entries); - if (!entries) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - ret = rmtfs_iovec_req_get_is_force_sync(req, &force); - if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - fd = storage_get_handle(node, caller_id); + fd = storage_get_handle(pkt->node, caller_id); if (fd < 0) { fprintf(stderr, "[RMTFS] iovec request for non-existing caller\n"); - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); goto respond; } @@ -211,7 +184,7 @@ static void rmtfs_iovec(int sock, unsigned node, unsigned port, void *msg, size_ n = lseek(fd, entries[i].sector_addr * SECTOR_SIZE, SEEK_SET); if (n < 0) { fprintf(stderr, "[RMTFS] failed to seek sector %d\n", entries[i].sector_addr); - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); goto respond; } @@ -227,7 +200,7 @@ static void rmtfs_iovec(int sock, unsigned node, unsigned port, void *msg, size_ if (n != SECTOR_SIZE) { fprintf(stderr, "[RMTFS] failed to %s sector %d\n", is_write ? "write" : "read", entries[i].sector_addr + j); - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); goto respond; } @@ -237,7 +210,7 @@ static void rmtfs_iovec(int sock, unsigned node, unsigned port, void *msg, size_ respond: dbgprintf("[RMTFS] iovec %d, %sforced => (%d:%d)\n", caller_id, force ? "" : "not ", - result.result, result.error); + resp.result.result, resp.result.error); for (i = 0; i < num_entries; i++) { dbgprintf("[RMTFS] %s %d:%d 0x%x\n", is_write ? "write" : "read", entries[i].sector_addr, @@ -245,145 +218,136 @@ respond: entries[i].phys_offset); } - resp = rmtfs_iovec_resp_alloc(txn); - rmtfs_iovec_resp_set_result(resp, &result); - ptr = rmtfs_iovec_resp_encode(resp, &len); - if (!ptr) - goto free_resp; + len = qmi_encode_message(&resp_buf, + QMI_RESPONSE, QMI_RMTFS_RW_IOVEC, txn, &resp, + rmtfs_iovec_resp_ei); + if (len < 0) { + fprintf(stderr, "[RMTFS] failed to encode iovec-response: %s\n", + strerror(-len)); + return; + } - ret = qrtr_sendto(sock, node, port, ptr, len); + ret = qrtr_sendto(sock, pkt->node, pkt->port, + resp_buf.data, resp_buf.data_len); if (ret < 0) - fprintf(stderr, "[RMTFS] failed to send iovec-response: %s\n", strerror(-ret)); - -free_resp: - rmtfs_iovec_resp_free(resp); - rmtfs_iovec_req_free(req); + fprintf(stderr, "[RMTFS] failed to send iovec-response: %s\n", + strerror(-ret)); } -static void rmtfs_alloc_buf(int sock, unsigned node, unsigned port, void *msg, size_t msg_len) +static void rmtfs_alloc_buf(int sock, struct qrtr_packet *pkt) { - struct rmtfs_alloc_buf_resp *resp; - struct rmtfs_alloc_buf_req *req; - struct rmtfs_qmi_result result = {}; - uint32_t alloc_size; - uint32_t caller_id; - int64_t address; + struct rmtfs_alloc_buf_resp resp = {}; + struct rmtfs_alloc_buf_req req = {}; + DEFINE_QRTR_PACKET(resp_buf, 256); + uint32_t alloc_size = 0; + uint32_t caller_id = 0; + int64_t address = 0; unsigned txn; - size_t len; - void *ptr; + ssize_t len; int ret; - req = rmtfs_alloc_buf_req_parse(msg, msg_len, &txn); - if (!req) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); + ret = qmi_decode_message(&req, &txn, pkt, QMI_REQUEST, + QMI_RMTFS_ALLOC_BUFF, rmtfs_alloc_buf_req_ei); + if (ret < 0) { + qmi_result_error(&resp.result, QMI_RMTFS_ERR_MALFORMED_MSG); goto respond; } - ret = rmtfs_alloc_buf_req_get_caller_id(req, &caller_id); - if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - ret = rmtfs_alloc_buf_req_get_buff_size(req, &alloc_size); - if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } + caller_id = req.caller_id; + alloc_size = req.buff_size; address = rmtfs_mem_alloc(rmem, alloc_size); - if (address < 0) - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + if (address < 0) { + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); + goto respond; + } + resp.buff_address = address; + resp.buff_address_valid = true; respond: - dbgprintf("[RMTFS] alloc %d, %d => 0x%lx (%d:%d)\n", caller_id, alloc_size, address, result.result, result.error); + dbgprintf("[RMTFS] alloc %d, %d => 0x%lx (%d:%d)\n", caller_id, alloc_size, address, resp.result.result, resp.result.error); - resp = rmtfs_alloc_buf_resp_alloc(txn); - rmtfs_alloc_buf_resp_set_result(resp, &result); - rmtfs_alloc_buf_resp_set_buff_address(resp, address); - ptr = rmtfs_alloc_buf_resp_encode(resp, &len); - if (!ptr) - goto free_resp; + len = qmi_encode_message(&resp_buf, + QMI_RESPONSE, QMI_RMTFS_ALLOC_BUFF, txn, &resp, + rmtfs_alloc_buf_resp_ei); + if (len < 0) { + fprintf(stderr, "[RMTFS] failed to encode alloc-buf-response: %s\n", + strerror(-len)); + return; + } - ret = qrtr_sendto(sock, node, port, ptr, len); + ret = qrtr_sendto(sock, pkt->node, pkt->port, + resp_buf.data, resp_buf.data_len); if (ret < 0) - fprintf(stderr, "[RMTFS] failed to send alloc-response: %s\n", strerror(-ret)); - -free_resp: - rmtfs_alloc_buf_resp_free(resp); - rmtfs_alloc_buf_req_free(req); + fprintf(stderr, "[RMTFS] failed to send alloc-buf-response: %s\n", + strerror(-ret)); } -static void rmtfs_get_dev_error(int sock, unsigned node, unsigned port, void *msg, size_t msg_len) +static void rmtfs_get_dev_error(int sock, struct qrtr_packet *pkt) { - struct rmtfs_dev_error_resp *resp; - struct rmtfs_dev_error_req *req; - struct rmtfs_qmi_result result = {}; - uint32_t caller_id; - int dev_error; + struct rmtfs_dev_error_resp resp = {}; + struct rmtfs_dev_error_req req = {}; + DEFINE_QRTR_PACKET(resp_buf, 256); + int dev_error = 0; unsigned txn; - size_t len; - void *ptr; + ssize_t len; int ret; - req = rmtfs_dev_error_req_parse(msg, msg_len, &txn); - if (!req) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); - goto respond; - } - - ret = rmtfs_dev_error_req_get_caller_id(req, &caller_id); + ret = qmi_decode_message(&req, &txn, pkt, QMI_REQUEST, + QMI_RMTFS_GET_DEV_ERROR, + rmtfs_dev_error_req_ei); if (ret < 0) { - qmi_result_error(&result, QMI_RMTFS_ERR_MALFORMED_MSG); + qmi_result_error(&resp.result, QMI_RMTFS_ERR_MALFORMED_MSG); goto respond; } - dev_error = storage_get_error(node, caller_id); - if (dev_error < 0) - qmi_result_error(&result, QMI_RMTFS_ERR_INTERNAL); + dev_error = storage_get_error(pkt->node, req.caller_id); + if (dev_error < 0) { + qmi_result_error(&resp.result, QMI_RMTFS_ERR_INTERNAL); + goto respond; + } + + resp.status = dev_error; + resp.status_valid = true; respond: - dbgprintf("[RMTFS] dev_error %d => %d (%d:%d)\n", caller_id, dev_error, result.result, result.error); + dbgprintf("[RMTFS] dev_error %d => %d (%d:%d)\n", req.caller_id, dev_error, resp.result.result, resp.result.error); - resp = rmtfs_dev_error_resp_alloc(txn); - rmtfs_dev_error_resp_set_result(resp, &result); - rmtfs_dev_error_resp_set_status(resp, dev_error); - ptr = rmtfs_dev_error_resp_encode(resp, &len); - if (!ptr) - goto free_resp; + len = qmi_encode_message(&resp_buf, + QMI_RESPONSE, QMI_RMTFS_GET_DEV_ERROR, txn, + &resp, rmtfs_dev_error_resp_ei); + if (len < 0) { + fprintf(stderr, "[RMTFS] failed to encode dev-error-response: %s\n", + strerror(-len)); + return; + } - ret = qrtr_sendto(sock, node, port, ptr, len); + ret = qrtr_sendto(sock, pkt->node, pkt->port, + resp_buf.data, resp_buf.data_len); if (ret < 0) - fprintf(stderr, "[RMTFS] failed to send error-response: %s\n", strerror(-ret)); - -free_resp: - rmtfs_dev_error_resp_free(resp); - rmtfs_dev_error_req_free(req); + fprintf(stderr, "[RMTFS] failed to send dev-error-response: %s\n", + strerror(-ret)); } -static int rmtfs_bye(uint32_t node, void *data) +static int rmtfs_bye(uint32_t node) { dbgprintf("[RMTFS] bye from %d\n", node); return 0; } -static int rmtfs_del_client(uint32_t node, uint32_t port, void *data) +static int rmtfs_del_client(uint32_t node, uint32_t port) { dbgprintf("[RMTFS] del_client %d:%d\n", node, port); return 0; } -struct qrtr_ind_ops rmtfs_ctrl_ops = { - .bye = rmtfs_bye, - .del_client = rmtfs_del_client, -}; - static int handle_rmtfs(int sock) { struct sockaddr_qrtr sq; - struct qmi_packet *qmi; + struct qrtr_packet pkt; + unsigned int msg_id; socklen_t sl; char buf[4096]; int ret; @@ -399,37 +363,44 @@ static int handle_rmtfs(int sock) dbgprintf("[RMTFS] packet; from: %d:%d\n", sq.sq_node, sq.sq_port); - if (qrtr_is_ctrl_addr(&sq)) { - return qrtr_handle_ctrl_msg(&sq, buf, sizeof(buf), - &rmtfs_ctrl_ops, NULL); + ret = qrtr_decode(&pkt, buf, ret, &sq); + if (ret < 0) { + fprintf(stderr, "[RMTFS] unable to decode qrtr packet\n"); + return ret; } - qmi = (struct qmi_packet*)buf; - if (qmi->msg_len != ret - sizeof(struct qmi_packet)) { - fprintf(stderr, "[RMTFS] Invalid length of incoming qmi request\n"); - return -EINVAL; - } + switch (pkt.type) { + case QRTR_TYPE_BYE: + return rmtfs_bye(pkt.node); + case QRTR_TYPE_DEL_CLIENT: + return rmtfs_del_client(pkt.node, pkt.port); + case QRTR_TYPE_DATA: + ret = qmi_decode_header(&pkt, &msg_id); + if (ret < 0) + return ret; - switch (qmi->msg_id) { - case QMI_RMTFS_OPEN: - rmtfs_open(sock, sq.sq_node, sq.sq_port, qmi, qmi->msg_len); - break; - case QMI_RMTFS_CLOSE: - rmtfs_close(sock, sq.sq_node, sq.sq_port, qmi, qmi->msg_len); - break; - case QMI_RMTFS_RW_IOVEC: - rmtfs_iovec(sock, sq.sq_node, sq.sq_port, qmi, qmi->msg_len); - break; - case QMI_RMTFS_ALLOC_BUFF: - rmtfs_alloc_buf(sock, sq.sq_node, sq.sq_port, qmi, qmi->msg_len); - break; - case QMI_RMTFS_GET_DEV_ERROR: - rmtfs_get_dev_error(sock, sq.sq_node, sq.sq_port, qmi, qmi->msg_len); - break; - default: - fprintf(stderr, "[RMTFS] Unknown request: %d\n", qmi->msg_id); - ret = -EINVAL; - break; + switch (msg_id) { + case QMI_RMTFS_OPEN: + rmtfs_open(sock, &pkt); + break; + case QMI_RMTFS_CLOSE: + rmtfs_close(sock, &pkt); + break; + case QMI_RMTFS_RW_IOVEC: + rmtfs_iovec(sock, &pkt); + break; + case QMI_RMTFS_ALLOC_BUFF: + rmtfs_alloc_buf(sock, &pkt); + break; + case QMI_RMTFS_GET_DEV_ERROR: + rmtfs_get_dev_error(sock, &pkt); + break; + default: + fprintf(stderr, "[RMTFS] Unknown request: %d\n", msg_id); + break; + } + + return 0; } return ret;