Commit 8d59369a authored by Ulrich Mohr's avatar Ulrich Mohr
Browse files

mbimcli: Add sms functionality

This adds a new group for sms functionality with three new functions:
 - --sms-delete
 - --sms-delete-all
 - --sms-read-all
parent 6e6352eb
Pipeline #646980 passed with stages
in 2 minutes and 20 seconds
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* mbimcli -- Command line interface to control MBIM devices
*
* Copyright (C) 2014 NVIDIA CORPORATION
* Copyright (C) 2014 Aleksander Morgado <aleksander@aleksander.es>
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <gio/gio.h>
#include <libmbim-glib.h>
#include "mbimcli.h"
#include "mbimcli-helpers.h"
/* Context */
typedef struct {
MbimDevice *device;
GCancellable *cancellable;
} Context;
static Context *ctx;
/* Options */
static gchar *delete_all_str = NULL;
static gchar *delete_str = NULL;
static gchar *read_all_str = NULL;
static GOptionEntry entries[] = {
{ "sms-delete-all", 0, 0, G_OPTION_ARG_STRING, &delete_all_str,
"Delete all SMS matching a given filter",
"[(all|new|old|sent|draft)]"
},
{ "sms-delete", 0, 0, G_OPTION_ARG_STRING, &delete_str,
"Delete one specific sms",
"[index]"
},
{ "sms-read-all", 0, 0, G_OPTION_ARG_STRING, &read_all_str,
"Reaf all SMS matching a given filter",
"[(all|new|old|sent|draft)]"
},
{ NULL }
};
GOptionGroup *
mbimcli_sms_get_option_group (void)
{
GOptionGroup *group;
group = g_option_group_new ("sms",
"Simple message service options:",
"Show SMS service options",
NULL,
NULL);
g_option_group_add_entries (group, entries);
return group;
}
gboolean
mbimcli_sms_options_enabled (void)
{
static guint n_actions = 0;
static gboolean checked = FALSE;
if (checked)
return !!n_actions;
n_actions = (!!delete_str +
!!delete_all_str +
!!read_all_str);
if (n_actions > 1) {
g_printerr ("error: too many SIM actions requested\n");
exit (EXIT_FAILURE);
}
checked = TRUE;
return !!n_actions;
}
static void
context_free (Context *context)
{
if (!context)
return;
if (context->cancellable)
g_object_unref (context->cancellable);
if (context->device)
g_object_unref (context->device);
g_slice_free (Context, context);
}
static void
shutdown (gboolean operation_status)
{
/* Cleanup context and finish async operation */
context_free (ctx);
mbimcli_async_operation_done (operation_status);
}
static void
delete_sms_ready (MbimDevice *device,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(MbimMessage) response = NULL;
g_autoptr(GError) error = NULL;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
g_printerr ("error: operation failed: %s\n", error->message);
shutdown (FALSE);
return;
}
if (!mbim_message_sms_delete_response_parse (response, &error)) {
g_printerr ("error: couldn't parse response message: %s\n", error->message);
shutdown (FALSE);
return;
}
g_print ("Successfully deleted sms\n");
shutdown (TRUE);
return;
}
static void
delete_all_sms_ready (MbimDevice *device,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(MbimMessage) response = NULL;
g_autoptr(GError) error = NULL;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
g_printerr ("error: operation failed: %s\n", error->message);
shutdown (FALSE);
return;
}
if (!mbim_message_sms_delete_response_parse (response, &error)) {
g_printerr ("error: couldn't parse response message: %s\n", error->message);
shutdown (FALSE);
return;
}
g_print ("Successfully deleted all sms\n");
shutdown (TRUE);
return;
}
static const char *
get_message_status_string (guint32 status)
{
switch (status) {
case 0: return "new";
case 1: return "old";
case 2: return "draft";
case 3: return "sent";
default: return "";
}
}
static void
read_all_sms_ready (MbimDevice *device,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(MbimMessage) response = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(MbimSmsPduReadRecordArray) pdu_messages = NULL;
guint32 num_messages = 0;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
g_printerr ("error: operation failed: %s\n", error->message);
shutdown (FALSE);
return;
}
if (!mbim_message_sms_read_response_parse (response, NULL, &num_messages, &pdu_messages, NULL, &error)) {
g_printerr ("error: couldn't parse response message: %s\n", error->message);
shutdown (FALSE);
return;
}
g_print ("Successfully read all sms\n");
if (num_messages && pdu_messages) {
guint32 i = 0;
g_print ("Got %d messages\n", num_messages);
while (pdu_messages[i]) {
g_print (" Message on index %d, status %s\n", pdu_messages[i]->message_index, get_message_status_string(pdu_messages[i]->message_status));
i++;
}
} else
g_print (" No messages found\n");
shutdown (TRUE);
return;
}
static gboolean
op_all_parse (const gchar *str,
MbimSmsFlag *filter)
{
gboolean status = TRUE;
g_assert (filter != NULL);
if (g_ascii_strcasecmp (str, "all") == 0)
*filter = MBIM_SMS_FLAG_ALL;
else if (g_ascii_strcasecmp (str, "new") == 0)
*filter = MBIM_SMS_FLAG_NEW;
else if (g_ascii_strcasecmp (str, "old") == 0)
*filter = MBIM_SMS_FLAG_OLD;
else if (g_ascii_strcasecmp (str, "sent") == 0)
*filter = MBIM_SMS_FLAG_SENT;
else if (g_ascii_strcasecmp (str, "draft") == 0)
*filter = MBIM_SMS_FLAG_DRAFT;
else {
g_printerr ("error: couldn't parse filter flag, invalid value given\n");
status = FALSE;
}
return status;
}
static gboolean
delete_parse (const gchar *str,
guint32 *index)
{
gboolean status = FALSE;
g_assert (index != NULL);
if (!mbimcli_read_uint_from_string (str, index))
g_printerr ("error: couldn't parse sms index, should be a number\n");
else
status = TRUE;
return status;
}
void
mbimcli_sms_run (MbimDevice *device,
GCancellable *cancellable)
{
g_autoptr(MbimMessage) request = NULL;
g_autoptr(GError) error = NULL;
/* Initialize context */
ctx = g_slice_new (Context);
ctx->device = g_object_ref (device);
ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
if (delete_all_str) {
MbimSmsFlag filter;
if (!op_all_parse (delete_all_str, &filter)) {
shutdown (FALSE);
return;
}
request = mbim_message_sms_delete_set_new (filter, 0, &error);
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
shutdown (FALSE);
return;
}
mbim_device_command (ctx->device,
request,
10,
ctx->cancellable,
(GAsyncReadyCallback)delete_all_sms_ready,
NULL);
return;
}
if (read_all_str) {
MbimSmsFlag filter;
if (!op_all_parse (read_all_str, &filter)) {
shutdown (FALSE);
return;
}
request = mbim_message_sms_read_query_new (MBIM_SMS_FORMAT_PDU, filter, 0, &error);
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
shutdown (FALSE);
return;
}
mbim_device_command (ctx->device,
request,
10,
ctx->cancellable,
(GAsyncReadyCallback)read_all_sms_ready,
NULL);
return;
}
if (delete_str) {
guint32 index;
if (!delete_parse (delete_str, &index)) {
shutdown (FALSE);
return;
}
request = mbim_message_sms_delete_set_new (MBIM_SMS_FLAG_INDEX,
index,
&error);
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
shutdown (FALSE);
return;
}
mbim_device_command (ctx->device,
request,
10,
ctx->cancellable,
(GAsyncReadyCallback)delete_sms_ready,
NULL);
return;
}
g_warn_if_reached ();
}
......@@ -309,6 +309,8 @@ device_open_ready (MbimDevice *dev,
mbimcli_ms_voice_extensions_run (dev, cancellable);
return;
case MBIM_SERVICE_SMS:
mbimcli_sms_run (dev, cancellable);
return;
case MBIM_SERVICE_USSD:
case MBIM_SERVICE_STK:
case MBIM_SERVICE_AUTH:
......@@ -440,6 +442,11 @@ parse_actions (void)
actions_enabled++;
}
if (mbimcli_sms_options_enabled()) {
service = MBIM_SERVICE_SMS;
actions_enabled++;
}
/* Noop */
if (noop_flag)
actions_enabled++;
......@@ -487,6 +494,7 @@ int main (int argc, char **argv)
g_option_context_add_group (context, mbimcli_link_management_get_option_group ());
g_option_context_add_group (context, mbimcli_intel_thermal_rf_get_option_group ());
g_option_context_add_group (context, mbimcli_ms_voice_extensions_get_option_group ());
g_option_context_add_group (context, mbimcli_sms_get_option_group ());
g_option_context_add_main_entries (context, main_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error)) {
g_printerr ("error: %s\n", error->message);
......
......@@ -29,6 +29,7 @@ GOptionGroup *mbimcli_ms_basic_connect_extensions_get_option_group (void);
GOptionGroup *mbimcli_quectel_get_option_group (void);
GOptionGroup *mbimcli_intel_thermal_rf_get_option_group (void);
GOptionGroup *mbimcli_ms_voice_extensions_get_option_group (void);
GOptionGroup *mbimcli_sms_get_option_group (void);
gboolean mbimcli_basic_connect_options_enabled (void);
gboolean mbimcli_phonebook_options_enabled (void);
......@@ -42,6 +43,7 @@ gboolean mbimcli_ms_basic_connect_extensions_options_enabled (void);
gboolean mbimcli_quectel_options_enabled (void);
gboolean mbimcli_intel_thermal_rf_options_enabled (void);
gboolean mbimcli_ms_voice_extensions_options_enabled (void);
gboolean mbimcli_sms_options_enabled (void);
void mbimcli_basic_connect_run (MbimDevice *device,
GCancellable *cancellable);
......@@ -67,7 +69,8 @@ void mbimcli_intel_thermal_rf_run (MbimDevice *device,
GCancellable *cancellable);
void mbimcli_ms_voice_extensions_run (MbimDevice *device,
GCancellable *cancellable);
void mbimcli_sms_run (MbimDevice *device,
GCancellable *cancellable);
/* link management */
GOptionGroup *mbimcli_link_management_get_option_group (void);
......
......@@ -15,6 +15,7 @@ mbimcli_sources = files(
'mbimcli-ms-voice-extensions.c',
'mbimcli-phonebook.c',
'mbimcli-quectel.c',
'mbimcli-sms.c'
)
sources = mbimcli_sources + files(
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment