aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--samsung-ipc/ipc_utils.c18
-rw-r--r--tools/Makefile.am2
-rw-r--r--tools/ipc-modem.c174
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;
}