aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulK <contact@paulk.fr>2011-10-25 21:10:59 +0200
committerJoerie de Gram <j.de.gram@gmail.com>2011-10-28 13:53:28 +0200
commit8b39af23371a7b2f0e8dc3640377a2d84ba4cfce (patch)
treecacec76a6deb14bfddddd05a3c347be8fcf288a7
parentaeb7a4c4069cfbbf4f177a038e8379ef7341bd02 (diff)
downloadexternal_libsamsung-ipc-8b39af23371a7b2f0e8dc3640377a2d84ba4cfce.zip
external_libsamsung-ipc-8b39af23371a7b2f0e8dc3640377a2d84ba4cfce.tar.gz
external_libsamsung-ipc-8b39af23371a7b2f0e8dc3640377a2d84ba4cfce.tar.bz2
added handlers support and default handlers for crespo.
-rw-r--r--Android.mk3
-rw-r--r--include/radio.h20
-rw-r--r--samsung-ipc/crespo_ipc.c184
-rw-r--r--samsung-ipc/crespo_ipc.h2
-rw-r--r--samsung-ipc/ipc.c100
-rw-r--r--samsung-ipc/ipc_private.h25
-rw-r--r--tools/modemctrl.c131
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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <pthread.h>
+
#include <radio.h>
+#include <crespo_ipc.h>
+
+#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;
}