diff options
-rw-r--r-- | samsung-ipc/ipc_utils.c | 18 | ||||
-rw-r--r-- | tools/Makefile.am | 2 | ||||
-rw-r--r-- | tools/ipc-modem.c | 174 |
3 files changed, 168 insertions, 26 deletions
diff --git a/samsung-ipc/ipc_utils.c b/samsung-ipc/ipc_utils.c index d8b69b7..3b824f2 100644 --- a/samsung-ipc/ipc_utils.c +++ b/samsung-ipc/ipc_utils.c @@ -33,6 +33,24 @@ #include "ipc.h" +const char *ipc_client_string(unsigned char type) +{ + static char type_string[5] = { 0 }; + + switch (type) { + case IPC_CLIENT_TYPE_FMT: + return "FMT"; + case IPC_CLIENT_TYPE_RFS: + return "RFS"; + case IPC_CLIENT_TYPE_DUMMY: + return "DUMMY"; + default: + snprintf((char *) &type_string, sizeof(type_string), + "0x%02x", type); + return type_string; + } +} + int ipc_seq_valid(unsigned char seq) { if (seq == 0x00 || seq == 0xff) diff --git a/tools/Makefile.am b/tools/Makefile.am index 4d5fa8b..4d1663f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,7 +20,7 @@ TESTS = nv_data-imei.py \ ipc_modem_SOURCES = ipc-modem.c ipc_modem_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la -ipc_modem_LDFLAGS = +ipc_modem_LDFLAGS = -lpthread ipc_test_SOURCES = ipc-test.c ipc_test_LDADD = $(top_builddir)/samsung-ipc/libsamsung-ipc.la diff --git a/tools/ipc-modem.c b/tools/ipc-modem.c index 9314de6..2492092 100644 --- a/tools/ipc-modem.c +++ b/tools/ipc-modem.c @@ -50,6 +50,14 @@ int call_done; char sim_pin[8]; +static struct ipc_modem_client { + const char *name; + pthread_t thread; + pthread_mutex_t mutex; + pthread_attr_t attr; + struct ipc_client *client; +}; + int seq_get(void) { if (seq == 0xff) @@ -92,7 +100,6 @@ void modem_snd_audio_path_ctrl(struct ipc_client *client) IPC_TYPE_SET, (void *) &data, 1); } - void modem_exec_call_out(struct ipc_client *client, char *num) { struct ipc_call_outgoing_data call_out; @@ -351,7 +358,8 @@ void modem_response_net(__attribute__((unused)) struct ipc_client *client, } } -void modem_response_handle(struct ipc_client *client, struct ipc_message *resp) +void modem_response_fmt_handle(struct ipc_client *client, + struct ipc_message *resp) { switch (IPC_GROUP(resp->command)) { case IPC_GROUP_NET: @@ -376,36 +384,63 @@ void modem_response_handle(struct ipc_client *client, struct ipc_message *resp) } } - -int modem_read_loop(struct ipc_client *client) +int modem_read(struct ipc_client *client, char const *channel_name) { struct ipc_message resp; + struct timeval timeout; int rc; memset(&resp, 0, sizeof(resp)); + timeout.tv_sec = 0; + timeout.tv_usec = 50000; + rc = ipc_client_poll(client, NULL, &timeout); + if (rc < 0) { + printf("[E] poll of %s client failed\n", channel_name); + return -1; + } + + if (rc == 0) { + /* timeout */ + return 0; + } + + rc = ipc_client_recv(client, &resp); + if (rc < 0) { + printf("[E] " + "Can't RECV from %s channel: please run this again" + "\n", channel_name); + return -1; + } + + /* We have no RFS handler (yet) in ipc-modem */ + if (channel_name == "FMT") + modem_response_fmt_handle(client, &resp); + + if (resp.data != NULL) + free(resp.data); + + return rc; +} + +void modem_read_loop(struct ipc_modem_client *modem_client) +{ + int rc; + while (1) { usleep(3000); - rc = ipc_client_poll(client, NULL, NULL); - if (rc < 0) - continue; + rc = modem_read(modem_client->client, modem_client->name); - rc = ipc_client_recv(client, &resp); - if (rc < 0) { - printf("[E] " - "Can't RECV from modem: please run this again" - "\n"); + switch (rc) { + case -1: + return; + case 0: + break; + default: break; } - - modem_response_handle(client, &resp); - - if (resp.data != NULL) - free(resp.data); } - - return 0; } void modem_log_handler(__attribute__((unused)) void *user_data, @@ -466,6 +501,45 @@ int modem_stop(struct ipc_client *client) return 0; } +int modem_create_channel_thread(struct ipc_client *client, const char* name) +{ + int rc; + + struct ipc_modem_client modem_client; + + printf("[2] Starting modem_read_loop on %s client\n", name); + + modem_client.client = client; + modem_client.name = name; + + rc = pthread_attr_init(&modem_client.attr); + if (rc) { + printf("[E] %s pthread_attr_init failed with error %d\n", + name, rc); + return rc; + } + + rc = pthread_attr_setdetachstate(&modem_client.attr, + PTHREAD_CREATE_DETACHED); + if (rc) { + printf("[E] %s pthread_attr_setdetachstate failed with error %d\n", + name, rc); + return rc; + } + + rc = pthread_create(&modem_client.thread, + &modem_client.attr, + (void *) modem_read_loop, + (void *) &modem_client); + if (rc) { + printf("[E] %s pthread_create failed with error %d\n", + name, rc); + return rc; + } + + return rc; +} + void print_help(void) { printf("usage: ipc-modem <command>\n"); @@ -476,20 +550,24 @@ void print_help(void) printf("\tpower-off power off the modem\n"); printf("arguments:\n"); printf("\t--debug enable debug messages\n"); + printf("\t--rfs enable RFS client in addition to FMT client\n"); printf("\t--pin=[PIN] provide SIM card PIN\n"); } int main(int argc, char *argv[]) { - struct ipc_client *client_fmt; + struct ipc_client *client_fmt = 0; + struct ipc_client *client_rfs = 0; int c = 0; int opt_i = 0; int rc = -1; int debug = 0; + int rfs = 0; struct option opt_l[] = { {"help", no_argument, 0, 0 }, {"debug", no_argument, 0, 0 }, + {"rfs", no_argument, 0, 0 }, {"pin", required_argument, 0, 0 }, {0, 0, 0, 0 } }; @@ -512,6 +590,9 @@ int main(int argc, char *argv[]) } else if (strcmp(opt_l[opt_i].name, "debug") == 0) { debug = 1; printf("[I] Debug enabled\n"); + } else if (strcmp(opt_l[opt_i].name, "rfs") == 0) { + rfs = 1; + printf("[I] RFS enabled\n"); } else if (strcmp(opt_l[opt_i].name, "pin") == 0) { if (optarg) { if (strlen(optarg) < 8) { @@ -536,12 +617,31 @@ int main(int argc, char *argv[]) goto modem_quit; } + if (rfs) { + client_rfs = ipc_client_create(IPC_CLIENT_TYPE_RFS); + if (client_rfs == 0) { + printf("[E] Could not create RFS client; aborting ...\n"); + goto modem_quit; + } + } else { + client_rfs = 0; + } + if (debug == 0) { ipc_client_log_callback_register(client_fmt, modem_log_handler_quiet, NULL); + if (rfs) { + ipc_client_log_callback_register( + client_rfs, modem_log_handler_quiet, NULL); + } } else { ipc_client_log_callback_register(client_fmt, modem_log_handler, NULL); + if (rfs) { + ipc_client_log_callback_register(client_rfs, + modem_log_handler, + NULL); + } } while (optind < argc) { @@ -561,18 +661,40 @@ int main(int argc, char *argv[]) printf("[E] Something went wrong " "while bootstrapping modem\n"); } else if (strncmp(argv[optind], "start", 5) == 0) { - printf("[0] Starting modem on FMT client\n"); + printf("[0] Starting modem FMT client\n"); rc = modem_start(client_fmt); if (rc < 0) { - printf("[E] Something went wrong\n"); + printf("[E] Something went wrong " + "starting FMT client\n"); modem_stop(client_fmt); return 1; } - printf("[1] Starting modem_read_loop on FMT client\n"); - modem_read_loop(client_fmt); + /* RFS should be started before FMT */ + if (rfs) { + printf("[1] Starting modem RFS client\n"); + ipc_client_data_create(client_rfs); + rc = ipc_client_open(client_rfs); + if (rc < 0) { + printf("[E] Something went wrong " + "starting RFS client\n"); + ipc_client_close(client_rfs); + modem_stop(client_fmt); + return 1; + } + rc = modem_create_channel_thread(client_rfs, + "RFS"); + if (rc) + return rc; + + } else { + printf("[1] Skipping modem RFS client start\n"); + } + + rc = modem_create_channel_thread(client_fmt, "FMT"); + if (rc) + return rc; - modem_stop(client_fmt); } else { printf("[E] Unknown argument: '%s'\n", argv[optind]); print_help(); @@ -585,6 +707,8 @@ int main(int argc, char *argv[]) modem_quit: if (client_fmt != 0) ipc_client_destroy(client_fmt); + if (client_rfs != 0) + ipc_client_destroy(client_rfs); return 0; } |