aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ipc-modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ipc-modem.c')
-rw-r--r--tools/ipc-modem.c364
1 files changed, 276 insertions, 88 deletions
diff --git a/tools/ipc-modem.c b/tools/ipc-modem.c
index 5977a7e..24d9806 100644
--- a/tools/ipc-modem.c
+++ b/tools/ipc-modem.c
@@ -19,6 +19,7 @@
*/
#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
@@ -94,8 +95,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;
@@ -395,7 +394,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:
@@ -420,49 +420,85 @@ 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) {
+ ipc_modem_log(client,
+ MODEM_LOG_ERROR,
+ "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) {
+ ipc_modem_log(client,
+ MODEM_LOG_ERROR,
+ "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 (!strcmp(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) {
- ipc_modem_log(
- client,
- MODEM_LOG_ERROR,
- "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;
+ pthread_exit((void*)rc);
}
-int modem_dummy_read_loop(__attribute__((unused)) struct ipc_client *client)
+void modem_dummy_read_loop(struct ipc_modem_client *modem_client)
{
+ int rc = 0;
+
while (true) {
- ipc_modem_log(client,
- MODEM_LOG_INFO, "%s: looping\n", __func__);
+ ipc_modem_log(modem_client->client,
+ MODEM_LOG_INFO,
+ "%s: looping for the %s channel\n",
+ __func__,
+ modem_client->name);
sleep(1);
}
- return 0;
+ pthread_exit((void*)rc);
}
void modem_log_handler(void *user_data, const char *msg)
@@ -513,34 +549,110 @@ void ipc_modem_log(__attribute__((unused)) struct ipc_client *client,
modem_log_handler(prefix, buffer);
}
-int modem_start(struct ipc_client *client)
+int modem_start(struct ipc_client *client_fmt, struct ipc_client *client_rfs)
{
int rc = -1;
- ipc_client_data_create(client);
- rc = ipc_client_boot(client);
- if (rc < 0)
- return -1;
+ /* We need to boot the modem before opening the channels */
+ ipc_client_data_create(client_fmt);
+ rc = ipc_client_boot(client_fmt);
+ if (rc < 0)
+ return -1;
+ usleep(300);
+
+ /* Then we open the RFS channel as this should be done at the end
+ * of the boot, before opening the FMT channel as at least on
+ * one herolte kernel, the modem kernel drivers requires it.
+ */
+ if (client_rfs) {
+ ipc_client_data_create(client_rfs);
+ rc = ipc_client_open(client_rfs);
+ if (rc < 0) {
+ ipc_modem_log(client_rfs, MODEM_LOG_ERROR, "Something went wrong "
+ "opening the RFS channel\n");
+ return -1;
+ }
+ }
- usleep(300);
+ /* Then we finally open the FMT channel */
+ rc = ipc_client_open(client_fmt);
+ if (rc < 0)
+ return -1;
- rc = ipc_client_open(client);
- if (rc < 0)
- return -1;
+ /* Some modem like aries have power_on callbacks that
+ * need to be called after booting the modem
+ */
+ rc = ipc_client_power_on(client_fmt);
+ if (rc < 0)
+ return -1;
- rc = ipc_client_power_on(client);
- if (rc < 0)
- return -1;
+ return 0;
+}
+
+int modem_stop(struct ipc_client *client_fmt, struct ipc_client *client_rfs)
+{
+ if (client_rfs)
+ ipc_client_close(client_fmt);
+
+ ipc_client_power_off(client_fmt);
+ ipc_client_close(client_fmt);
return 0;
}
-int modem_stop(struct ipc_client *client)
+int modem_create_channel_thread(struct ipc_modem_client *modem_client,
+ struct cmdline_opts *cmdline_opts)
{
- ipc_client_power_off(client);
- ipc_client_close(client);
+ int rc;
- return 0;
+ if (cmdline_opts->dry_run)
+ ipc_modem_log(modem_client->client,
+ "2",
+ "Starting modem_dummy_read_loop on %s client\n",
+ modem_client->name);
+ else
+ ipc_modem_log(modem_client->client,
+ "2",
+ "Starting modem_read_loop on %s client\n",
+ modem_client->name);
+
+ rc = pthread_attr_init(&modem_client->attr);
+ if (rc) {
+ ipc_modem_log(modem_client->client,
+ "2",
+ "%s pthread_attr_init failed with error %d\n",
+ modem_client->name, rc);
+ return rc;
+ }
+
+ if (rc) {
+ ipc_modem_log(modem_client->client,
+ MODEM_LOG_ERROR,
+ "%s pthread_attr_setdetachstate failed with error %d\n",
+ modem_client->name, rc);
+ return rc;
+ }
+
+ if (cmdline_opts->dry_run) {
+ rc = pthread_create(&modem_client->thread,
+ &modem_client->attr,
+ (void *) modem_dummy_read_loop,
+ (void *) modem_client);
+ }
+ else
+ rc = pthread_create(&modem_client->thread,
+ &modem_client->attr,
+ (void *) modem_read_loop,
+ (void *) modem_client);
+ if (rc) {
+ ipc_modem_log(modem_client->client,
+ MODEM_LOG_ERROR,
+ "%s pthread_create failed with error %d\n",
+ modem_client->name, rc);
+ return rc;
+ }
+
+ return rc;
}
void print_help(void)
@@ -560,22 +672,59 @@ void print_help(void)
"\t--help print this help message\n"
"\t--log-target=[stdout|syslog] "
"direct logs to stdout or syslog\n"
- "\t--pin=[PIN] provide SIM card PIN\n");
+ "\t--pin=[PIN] provide SIM card PIN\n"
+ "\t--rfs enable RFS client in addition to FMT client\n");
}
-int handle_command(struct ipc_client *client,
- struct cmdline_opts *cmdline_opts)
+int create_client(struct ipc_client **client, int client_type,
+ struct cmdline_opts *cmdline_opts)
+{
+ if (cmdline_opts->dry_run)
+ client_type = IPC_CLIENT_TYPE_DUMMY;
+
+ *client = ipc_client_create(client_type);
+ if (*client == 0) {
+ printf("[E] Could not create IPC %s client; aborting ...\n",
+ ipc_client_type_string(client_type));
+ return -1;
+ }
+
+ if (cmdline_opts->debug)
+ ipc_client_log_callback_register(*client, modem_log_handler,
+ NULL);
+ else
+ ipc_client_log_callback_register(*client,
+ modem_log_handler_quiet, NULL);
+ return 0;
+}
+
+int handle_command(struct cmdline_opts *cmdline_opts,
+ struct ipc_client *dummy_client,
+ struct ipc_modem_client *modem_client_fmt,
+ struct ipc_modem_client *modem_client_rfs)
{
int rc = 0;
+ modem_client_fmt->name = "FMT";
+ modem_client_rfs->name = "RFS";
+
+ rc = create_client(&modem_client_fmt->client, IPC_CLIENT_TYPE_FMT,
+ cmdline_opts);
+ if (rc)
+ goto modem_quit;
+
+ if (cmdline_opts->rfs)
+ rc = create_client(&modem_client_rfs->client, IPC_CLIENT_TYPE_RFS,
+ cmdline_opts);
+
switch (cmdline_opts->command) {
case CMD_POWER_ON:
if (cmdline_opts->dry_run)
break;
- rc = ipc_client_power_on(client);
+ rc = ipc_client_power_on(modem_client_fmt->client);
if (rc < 0)
- ipc_modem_log(client, "[E]",
+ ipc_modem_log(dummy_client, "[E]",
"[E] Something went wrong "
"while powering modem on\n");
goto modem_quit;
@@ -583,9 +732,9 @@ int handle_command(struct ipc_client *client,
if (cmdline_opts->dry_run)
break;
- rc = ipc_client_power_off(client);
+ rc = ipc_client_power_off(modem_client_fmt->client);
if (rc < 0)
- ipc_modem_log(client,
+ ipc_modem_log(dummy_client,
MODEM_LOG_ERROR,
"Something went wrong "
"while powering modem off\n");
@@ -594,45 +743,72 @@ int handle_command(struct ipc_client *client,
if (cmdline_opts->dry_run)
break;
- rc = ipc_client_boot(client);
+ rc = ipc_client_boot(modem_client_fmt->client);
if (rc < 0)
- ipc_modem_log(client,
+ ipc_modem_log(dummy_client,
MODEM_LOG_ERROR,
"Something went wrong "
"while bootstrapping modem\n");
break;
case CMD_START:
- if (cmdline_opts->dry_run) {
- ipc_modem_log(
- client,
- "1",
- "Starting dummy modem_read_loop on %s client\n",
- "FMT");
- modem_dummy_read_loop(client);
- break;
+ ipc_modem_log(modem_client_fmt->client,
+ "0",
+ "Starting modem FMT client\n");
+ if (!cmdline_opts->dry_run) {
+ rc = modem_start(modem_client_fmt->client, modem_client_rfs->client);
+ if (rc < 0) {
+ ipc_modem_log(dummy_client,
+ MODEM_LOG_ERROR,
+ "Something went wrong "
+ "starting FMT client\n");
+ modem_stop(modem_client_fmt->client, modem_client_rfs->client);
+ return 1;
+ }
}
- ipc_modem_log(client,
- "0", "Starting modem on FMT client\n");
+ if (cmdline_opts->rfs) {
+ ipc_modem_log(dummy_client, "1", "Starting modem RFS thread\n");
+ rc = modem_create_channel_thread(modem_client_rfs,
+ cmdline_opts);
+ if (rc)
+ return rc;
+ } else {
+ ipc_modem_log(dummy_client, "1", "Skipping modem RFS client start\n");
+ }
- rc = modem_start(client);
- if (rc < 0) {
- ipc_modem_log(client,
- MODEM_LOG_ERROR,
- "Something went wrong\n");
- modem_stop(client);
- return 1;
+ ipc_modem_log(dummy_client, "1", "Starting modem FMT thread\n");
+ rc = modem_create_channel_thread(modem_client_fmt, cmdline_opts);
+
+ while (true) {
+ int *thread_rc;
+
+ ipc_modem_log(dummy_client, MODEM_LOG_INFO, "Checking threads\n");
+
+ if (0 && cmdline_opts->rfs) {
+ rc = pthread_join(modem_client_rfs->thread, (void**)&thread_rc);
+ if (rc != EINVAL)
+ ipc_modem_log(dummy_client,
+ MODEM_LOG_ERROR,
+ "%s Thread exited with error: %d\n",
+ modem_client_rfs->name,
+ *thread_rc);
+ }
+
+ rc = pthread_join(modem_client_fmt->thread, (void**)&thread_rc);
+ if (!rc) {
+ ipc_modem_log(dummy_client,
+ MODEM_LOG_ERROR,
+ "%s: pthread_join = %d\n",
+ modem_client_fmt->name,
+ thread_rc);
+ }
+ sleep(1);
}
- ipc_modem_log(client,
- "1",
- "Starting modem_read_loop on FMT client\n");
- modem_read_loop(client);
- modem_stop(client);
break;
default:
/* We should handle all commands */
- ipc_modem_log(client,
+ ipc_modem_log(dummy_client,
MODEM_LOG_ERROR,
"%s: Unknown command %d\n", __func__,
cmdline_opts->command);
@@ -641,8 +817,12 @@ int handle_command(struct ipc_client *client,
}
modem_quit:
- if (client != 0)
- ipc_client_destroy(client);
+ if (modem_client_fmt->client != 0)
+ ipc_client_destroy(modem_client_fmt->client);
+ if (modem_client_rfs->client != 0)
+ ipc_client_destroy(modem_client_rfs->client);
+ if (dummy_client != 0)
+ ipc_client_destroy(dummy_client);
return rc;
}
@@ -660,7 +840,9 @@ void print_cmdline_opts(struct ipc_client *client,
int main(int argc, char *argv[])
{
struct cmdline_opts cmdline_opts;
- struct ipc_client *client;
+ struct ipc_client *dummy_client;
+ struct ipc_modem_client modem_client_fmt;
+ struct ipc_modem_client modem_client_rfs;
int c = 0;
int opt_i = 0;
@@ -671,10 +853,13 @@ int main(int argc, char *argv[])
{"help", no_argument, 0, 0 },
{"log-target", required_argument, 0, 0 },
{"pin", required_argument, 0, 0 },
+ {"rfs", no_argument, 0, 0 },
{0, 0, 0, 0 }
};
- bzero((void *)&cmdline_opts, sizeof(cmdline_opts));
+ bzero((void*)&modem_client_fmt, sizeof(modem_client_fmt));
+ bzero((void*)&modem_client_rfs, sizeof(modem_client_rfs));
+ bzero((void*)&cmdline_opts, sizeof(cmdline_opts));
if (argc < 2) {
print_help();
@@ -698,6 +883,9 @@ int main(int argc, char *argv[])
"Call number is too long!\n");
return 1;
}
+ } else if (strcmp(opt_l[opt_i].name, "rfs") == 0) {
+ cmdline_opts.rfs = true;
+ printf("[I] RFS enabled\n");
}
} else if ((strcmp(opt_l[opt_i].name, "log-target") == 0)) {
if (optarg && !strcmp(optarg, "syslog")) {
@@ -728,22 +916,19 @@ int main(int argc, char *argv[])
}
}
- if (cmdline_opts.dry_run)
- client = ipc_client_create(IPC_CLIENT_TYPE_DUMMY);
- else
- client = ipc_client_create(IPC_CLIENT_TYPE_FMT);
+ dummy_client = ipc_client_create(IPC_CLIENT_TYPE_DUMMY);
- if (client == 0) {
- printf("[E] Could not create IPC client; aborting ...\n");
+ if (dummy_client == 0) {
+ printf("[E] Could not create dummy IPC client; aborting ...\n");
return 1;
}
if (cmdline_opts.debug == 0)
- ipc_client_log_callback_register(client,
+ ipc_client_log_callback_register(dummy_client,
modem_log_handler_quiet,
NULL);
else
- ipc_client_log_callback_register(client,
+ ipc_client_log_callback_register(dummy_client,
modem_log_handler,
NULL);
@@ -761,7 +946,7 @@ int main(int argc, char *argv[])
cmdline_opts.command = CMD_START;
break;
} else {
- ipc_modem_log(client,
+ ipc_modem_log(dummy_client,
MODEM_LOG_ERROR,
"Unknown argument: '%s'\n",
argv[optind]);
@@ -781,7 +966,10 @@ int main(int argc, char *argv[])
return 1;
}
- print_cmdline_opts(client, &cmdline_opts);
+ print_cmdline_opts(dummy_client, &cmdline_opts);
- return handle_command(client, &cmdline_opts);
+ return handle_command(&cmdline_opts,
+ dummy_client,
+ &modem_client_fmt,
+ &modem_client_rfs);
}