From 8b39af23371a7b2f0e8dc3640377a2d84ba4cfce Mon Sep 17 00:00:00 2001 From: PaulK Date: Tue, 25 Oct 2011 21:10:59 +0200 Subject: added handlers support and default handlers for crespo. --- Android.mk | 3 +- include/radio.h | 20 ++++- samsung-ipc/crespo_ipc.c | 184 ++++++++++++++++++++++++++++++++++++++++++++-- samsung-ipc/crespo_ipc.h | 2 + samsung-ipc/ipc.c | 100 +++++++++++++++++++++---- samsung-ipc/ipc_private.h | 25 +++++-- tools/modemctrl.c | 131 +++++++++++++++++++++++++++++++-- 7 files changed, 423 insertions(+), 42 deletions(-) diff --git a/Android.mk b/Android.mk index 082c81c..f646042 100644 --- a/Android.mk +++ b/Android.mk @@ -15,7 +15,8 @@ modemctrl_files := tools/modemctrl.c LOCAL_SRC_FILES := $(samsung-ipc_files) $(modemctrl_files) LOCAL_SHARED_LIBRARIES := libutils -LOCAL_C_INCLUDES := $(LOCAL_PATH)/include +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/samsung-ipc LOCAL_CFLAGS += -Iexternal/openssl/include LOCAL_LDFLAGS += -lcrypto diff --git a/include/radio.h b/include/radio.h index 193a324..ec903df 100644 --- a/include/radio.h +++ b/include/radio.h @@ -59,19 +59,31 @@ struct ipc_response { }; struct ipc_client; +struct ipc_handlers; -typedef int (*ipc_client_transport_cb)(uint8_t *data, unsigned int size, void *user_data); typedef void (*ipc_client_log_handler_cb)(const char *message, void *user_data); +typedef void *(*ipc_handler_data_cb)(void); +typedef int (*ipc_io_handler_cb)(void *data, unsigned int size, void *io_data); +typedef int (*ipc_handler_cb)(void *data); + struct ipc_client *ipc_client_new(int client_type); -int ipc_client_set_log_handler(struct ipc_client *client, ipc_client_log_handler_cb log_handler_cb, void *user_data); -int ipc_client_set_delegates(struct ipc_client *client, ipc_client_transport_cb write, void *write_data, - ipc_client_transport_cb read, void *read_data); int ipc_client_free(struct ipc_client *client); +int ipc_client_set_log_handler(struct ipc_client *client, ipc_client_log_handler_cb log_handler_cb, void *user_data); + +int ipc_client_set_handlers(struct ipc_client *client, struct ipc_handlers *handlers); +int ipc_client_set_io_handlers(struct ipc_client *client, void *io_data, + ipc_io_handler_cb read, ipc_io_handler_cb write, + ipc_io_handler_cb open, ipc_io_handler_cb close); +void *ipc_client_get_handlers_io_data(struct ipc_client *client); +int ipc_client_set_handlers_io_data(struct ipc_client *client, void *io_data); + int ipc_client_bootstrap_modem(struct ipc_client *client); int ipc_client_open(struct ipc_client *client); int ipc_client_close(struct ipc_client *client); +int ipc_client_power_on(struct ipc_client *client); +int ipc_client_power_off(struct ipc_client *client); int ipc_client_recv(struct ipc_client *client, struct ipc_response *response); diff --git a/samsung-ipc/crespo_ipc.c b/samsung-ipc/crespo_ipc.c index 45c19b7..95a2321 100644 --- a/samsung-ipc/crespo_ipc.c +++ b/samsung-ipc/crespo_ipc.c @@ -274,6 +274,8 @@ boot_loop_start: free(nv_data_p); + close(modem_ctl_fd); + rc = 0; goto exit; @@ -314,9 +316,9 @@ int crespo_ipc_client_send(struct ipc_client *client, struct ipc_request *reques memcpy(modem_data.data, &reqhdr, sizeof(struct ipc_header)); memcpy((unsigned char *)modem_data.data + sizeof(struct ipc_header), request->data, request->length); - assert(client->write != NULL); + assert(client->handlers->write != NULL); - rc = client->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->write_data); + rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->io_data); return rc; } @@ -356,9 +358,9 @@ int crespo_ipc_client_recv(struct ipc_client *client, struct ipc_response *respo wake_lock("secril_fmt-interface", sizeof("secril_fmt-interface") - 1); // FIXME sizeof("...") is ugly! - assert(client->read != NULL); - bread = client->read((uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE, client->read_data); - if (bread <= 0) + assert(client->handlers->read != NULL); + bread = client->handlers->read((uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE, client->handlers->io_data); + if (bread < 0) { ipc_client_log(client, "ERROR: crespo_ipc_client_recv: can't receive enough bytes from modem to process incoming response!"); return 1; @@ -372,6 +374,8 @@ int crespo_ipc_client_recv(struct ipc_client *client, struct ipc_response *respo return 1; } + /* You MUST send back modem_data */ + resphdr = (struct ipc_header *) modem_data.data; response->mseq = resphdr->mseq; @@ -397,11 +401,175 @@ int crespo_ipc_client_recv(struct ipc_client *client, struct ipc_response *respo return 0; } +int crespo_ipc_open(void *data, unsigned int size, void *io_data) +{ + int type=*((int *) data); + int fd=-1; + + switch(type) + { + case IPC_CLIENT_TYPE_CRESPO_FMT: + fd = open("/dev/modem_fmt", O_RDWR | O_NDELAY); + printf("crespo_ipc_open: opening /dev/modem_fmt\n"); + break; + case IPC_CLIENT_TYPE_CRESPO_RFS: + fd = open("/dev/modem_rfs", O_RDWR | O_NDELAY); + printf("crespo_ipc_open: opening /dev/modem_rfs\n"); + break; + default: + break; + } + + if(fd < 0) + return -1; + + if(io_data == NULL) + return -1; + + memcpy(io_data, &fd, sizeof(int)); + + return 0; +} + +int crespo_ipc_close(void *data, unsigned int size, void *io_data) +{ + int fd = -1; + + if(io_data == NULL) + return -1; + + fd = *((int *) io_data); + + if(fd < 0) + return -1; + + close(fd); + + return 0; +} + +int crespo_ipc_read(void *data, unsigned int size, void *io_data) +{ + int fd = -1; + int rc; + + if(io_data == NULL) + return -1; + + if(data == NULL) + return -1; + + fd = *((int *) io_data); + + if(fd < 0) + return -1; + + rc = ioctl(fd, IOCTL_MODEM_RECV, data); + + if(rc < 0) + return -1; + + return 0; +} + +int crespo_ipc_write(void *data, unsigned int size, void *io_data) +{ + int fd = -1; + int rc; + + if(io_data == NULL) + return -1; + + fd = *((int *) io_data); + + if(fd < 0) + return -1; + + rc = ioctl(fd, IOCTL_MODEM_SEND, data); + + if(rc < 0) + return -1; + + return 0; +} + +int crespo_ipc_power_on(void *data) +{ + int fd=open("/dev/modem_ctl", O_RDWR); + int rc; + +/* + fd = open("/sys/devices/platform/modemctl/power_mode", O_RDWR); + rc = write(fd, "1", 1); +*/ + + if(fd < 0) + return -1; + + rc = ioctl(fd, IOCTL_MODEM_START); + close(fd); + + if(rc < 0) + return -1; + + return 0; +} + +int crespo_ipc_power_off(void *data) +{ + int fd=open("/dev/modem_ctl", O_RDWR); + int rc; + +/* + fd = open("/sys/devices/platform/modemctl/power_mode", O_RDWR); + rc = write(fd, "0", 1); +*/ + + if(fd < 0) + return -1; + + rc = ioctl(fd, IOCTL_MODEM_OFF); + close(fd); + + if(rc < 0) + return -1; + + return 0; +} + +void *crespo_ipc_io_data_reg(void) +{ + void *data = NULL; + + data = malloc(sizeof(int)); + + return data; +} + +int crespo_ipc_io_data_unreg(void *data) +{ + if(data == NULL) + return -1; + + free(data); + + return 0; +} + +struct ipc_handlers crespo_ipc_default_handlers = { + .read = crespo_ipc_read, + .write = crespo_ipc_write, + .open = crespo_ipc_open, + .close = crespo_ipc_close, + .io_data_reg = crespo_ipc_io_data_reg, + .io_data_unreg = crespo_ipc_io_data_unreg, + .io_data = NULL, + .power_on = crespo_ipc_power_on, + .power_off = crespo_ipc_power_off, +}; + struct ipc_ops crespo_ipc_ops = { - .open = NULL, - .close = NULL, .send = crespo_ipc_client_send, .recv = crespo_ipc_client_recv, .bootstrap = crespo_modem_bootstrap, }; - diff --git a/samsung-ipc/crespo_ipc.h b/samsung-ipc/crespo_ipc.h index 7bf6abc..a6540b5 100644 --- a/samsung-ipc/crespo_ipc.h +++ b/samsung-ipc/crespo_ipc.h @@ -45,4 +45,6 @@ void *file_read(char *file_name, int size, int block_size); int wake_lock(char *lock_name, int size); int wake_unlock(char *lock_name, int size); +extern struct ipc_handlers crespo_ipc_default_handlers; + #endif diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index 3054b98..b539d6d 100644 --- a/samsung-ipc/ipc.c +++ b/samsung-ipc/ipc.c @@ -72,6 +72,7 @@ struct ipc_client* ipc_client_new(int client_type) client = (struct ipc_client*) malloc(sizeof(struct ipc_client)); client->type = client_type; client->ops = ops; + client->handlers = (struct ipc_handlers *) malloc(sizeof(struct ipc_handlers)); client->log_handler = log_handler_default; return client; @@ -79,6 +80,9 @@ struct ipc_client* ipc_client_new(int client_type) int ipc_client_free(struct ipc_client *client) { + if(client->handlers->io_data != NULL) + client->handlers->io_data_unreg(client->handlers->io_data); + free(client->handlers); free(client); client = NULL; return 0; @@ -86,7 +90,7 @@ int ipc_client_free(struct ipc_client *client) int ipc_client_set_log_handler(struct ipc_client *client, ipc_client_log_handler_cb log_handler_cb, void *user_data) { - if (client == NULL) + if(client == NULL) return -1; client->log_handler = log_handler_cb; @@ -95,18 +99,59 @@ int ipc_client_set_log_handler(struct ipc_client *client, ipc_client_log_handler return 0; } +int ipc_client_set_io_handlers(struct ipc_client *client, void *io_data, + ipc_io_handler_cb read, ipc_io_handler_cb write, + ipc_io_handler_cb open, ipc_io_handler_cb close) +{ + if(client == NULL) + return -1; + + if(read != NULL) + client->handlers->read = read; + if(write != NULL) + client->handlers->write = write; + if(open != NULL) + client->handlers->open = open; + if(close != NULL) + client->handlers->close = close; + if(io_data != NULL) + { + client->handlers->io_data = io_data; + if(client->handlers->io_data_reg != NULL) + client->handlers->io_data = client->handlers->io_data_reg(); + } -int ipc_client_set_delegates(struct ipc_client *client, - ipc_client_transport_cb write, void *write_data, - ipc_client_transport_cb read, void *read_data) + return 0; +} + +int ipc_client_set_handlers(struct ipc_client *client, struct ipc_handlers *handlers) { - if (client == NULL) + if(client == NULL) return -1; + if(handlers == NULL) + return -1; + + memcpy(client->handlers, handlers, sizeof(struct ipc_handlers)); - client->read = read; - client->read_data = read_data; - client->write = write; - client->write_data = write_data; + if(client->handlers->io_data_reg != NULL) + client->handlers->io_data = client->handlers->io_data_reg(); + + return 0; +} + +void *ipc_client_get_handlers_io_data(struct ipc_client *client) +{ + return client->handlers->io_data; +} + +int ipc_client_set_handlers_io_data(struct ipc_client *client, void *io_data) +{ + if(client == NULL) + return -1; + if(io_data == NULL) + return -1; + + client->handlers->io_data=io_data; return 0; } @@ -123,22 +168,47 @@ int ipc_client_bootstrap_modem(struct ipc_client *client) int ipc_client_open(struct ipc_client *client) { + int type; + int fd; + if (client == NULL || - client->ops == NULL || - client->ops->open == NULL) + client->handlers == NULL || + client->handlers->open == NULL) return -1; - return client->ops->open(client); + type = client->type; + + return client->handlers->open(&type, 0, client->handlers->io_data); } int ipc_client_close(struct ipc_client *client) { if (client == NULL || - client->ops == NULL || - client->ops->close == NULL) + client->handlers == NULL || + client->handlers->open == NULL) + return -1; + + return client->handlers->close(NULL, 0, client->handlers->io_data); +} + +int ipc_client_power_on(struct ipc_client *client) +{ + if (client == NULL || + client->handlers == NULL || + client->handlers->open == NULL) + return -1; + + return client->handlers->power_on(NULL); +} + +int ipc_client_power_off(struct ipc_client *client) +{ + if (client == NULL || + client->handlers == NULL || + client->handlers->open == NULL) return -1; - return client->ops->close(client); + return client->handlers->power_off(NULL); } int _ipc_client_send(struct ipc_client *client, struct ipc_request *request) diff --git a/samsung-ipc/ipc_private.h b/samsung-ipc/ipc_private.h index d724781..be74c74 100644 --- a/samsung-ipc/ipc_private.h +++ b/samsung-ipc/ipc_private.h @@ -27,25 +27,34 @@ void ipc_client_log(struct ipc_client *client, const char *message, ...); struct ipc_ops { int (*bootstrap)(struct ipc_client *client); - int (*open)(struct ipc_client *client); - int (*close)(struct ipc_client *client); int (*send)(struct ipc_client *client, struct ipc_request*); int (*recv)(struct ipc_client *client, struct ipc_response*); }; +struct ipc_handlers { + /* Transport handlers/data */ + ipc_io_handler_cb read; + ipc_io_handler_cb write; + ipc_io_handler_cb open; + ipc_io_handler_cb close; + + ipc_handler_data_cb io_data_reg; + ipc_handler_cb io_data_unreg; + void *io_data; + + /* Power handlers */ + ipc_handler_cb power_on; + ipc_handler_cb power_off; +}; + struct ipc_client { int type; - /* callbacks for transport handling */ - ipc_client_transport_cb read; - void *read_data; - ipc_client_transport_cb write; - void *write_data; - ipc_client_log_handler_cb log_handler; void *log_data; struct ipc_ops *ops; + struct ipc_handlers *handlers; }; diff --git a/tools/modemctrl.c b/tools/modemctrl.c index 14237eb..4460f7d 100644 --- a/tools/modemctrl.c +++ b/tools/modemctrl.c @@ -21,7 +21,20 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include +#include + +#define RC_CHECK printf("line %d, rc = %d\n", __LINE__, rc); void print_help() { @@ -32,23 +45,129 @@ void print_help() printf("\tpower-off power off the modem\n"); } +int crespo_read_loop(struct ipc_client *client) +{ + struct ipc_response resp; + void *io_data = NULL; + int fd = -1; + fd_set fds; + + io_data = ipc_client_get_handlers_io_data(client); + fd = *((int *) io_data); + + if(fd < 0) { + return -1; + } + + memset(&resp, 0, sizeof(resp)); + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + while(1) { + usleep(3000); + + select(fd + 1, &fds, NULL, NULL, NULL); + + if(FD_ISSET(fd, &fds)) + { + ipc_client_recv(client, &resp); + if(resp.data != NULL) + free(resp.data); + } + } +} + +int modem_start(struct ipc_client *client) +{ + int rc; + + ipc_client_set_handlers(client, &crespo_ipc_default_handlers); + ipc_client_bootstrap_modem(client); + + rc = ipc_client_power_on(client); + if(rc < 0) + return -1; + + rc = ipc_client_open(client); + if(rc < 0) + return -1; + + + return 0; +} + +int modem_stop(struct ipc_client *client) +{ + ipc_client_close(client); + ipc_client_power_off(client); + + return 0; +} + int main(int argc, char *argv[]) { - struct ipc_client *client; - int error; + struct ipc_client *crespo_fmt_client; + struct ipc_client *crespo_rfs_client; + int rc; if (argc != 2) { print_help(); exit(1); } - client = ipc_client_new(IPC_CLIENT_TYPE_CRESPO_FMT); + crespo_fmt_client = ipc_client_new(IPC_CLIENT_TYPE_CRESPO_FMT); + crespo_rfs_client = ipc_client_new(IPC_CLIENT_TYPE_CRESPO_RFS); + + if (!strncmp(argv[1], "power-on", sizeof("power-on"))) { + ipc_client_power_on(crespo_fmt_client); + } + + else if (!strncmp(argv[1], "power-off", sizeof("power-off"))) { + ipc_client_power_off(crespo_fmt_client); + } + + else if (!strncmp(argv[1], "stop-all", 8)) { + ipc_client_close(crespo_fmt_client); + ipc_client_close(crespo_rfs_client); + ipc_client_power_off(crespo_fmt_client); + } + + else if (!strncmp(argv[1], "start-fmt", 9)) { + printf("Starting modem on FMT client\n"); + rc = modem_start(crespo_fmt_client); + if(rc < 0) { + printf("Somethign went wrong\n"); + modem_stop(crespo_fmt_client); + return 1; + } + + printf("Starting crespo_read_loop on FMT client\n"); + crespo_read_loop(crespo_fmt_client); - if (!strncmp(argv[1], "bootstrap", 9)) { - ipc_client_bootstrap_modem(client); + modem_stop(crespo_fmt_client); + } + + else if (!strncmp(argv[1], "start-rfs", 9)) { + printf("Starting modem on RFS client\n"); + rc = modem_start(crespo_rfs_client); + if(rc < 0) { + printf("Somethign went wrong\n"); + modem_stop(crespo_rfs_client); + return 1; + } + + printf("Starting crespo_read_loop on RFS client\n"); + crespo_read_loop(crespo_rfs_client); + + modem_stop(crespo_rfs_client); + } + else { + printf("Unknown command!\n"); } - ipc_client_free(client); + ipc_client_free(crespo_fmt_client); + ipc_client_free(crespo_rfs_client); return 0; } -- cgit v1.1