Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[mms-engine] Fixed offline mode behavior
Any network related task now fails immediately in offline mode.
  • Loading branch information
monich committed Jul 5, 2014
1 parent ee15da2 commit 23e0e96
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 27 deletions.
9 changes: 7 additions & 2 deletions mms-lib/src/mms_dispatcher.c
Expand Up @@ -291,7 +291,7 @@ mms_dispatcher_pick_next_task(
g_queue_delete_link(disp->tasks, entry);
return task;
} else {
mms_task_network_unavailable(task);
mms_task_network_unavailable(task, FALSE);
}
}
}
Expand Down Expand Up @@ -374,6 +374,11 @@ mms_dispatcher_run(
}

if (!mms_dispatcher_is_active(disp)) {
/* Cancel pending runs */
if (disp->next_run_id) {
g_source_remove(disp->next_run_id);
disp->next_run_id = 0;
}
/* Report to delegate that we are done */
if (disp->delegate && disp->delegate->fn_done) {
disp->delegate->fn_done(disp->delegate, disp);
Expand Down Expand Up @@ -566,7 +571,7 @@ mms_dispatcher_delegate_connection_state_changed(
case MMS_TASK_STATE_NEED_USER_CONNECTION:
case MMS_TASK_STATE_TRANSMITTING:
if (!strcmp(conn->imsi, task->imsi)) {
mms_task_network_unavailable(task);
mms_task_network_unavailable(task, TRUE);
}
default:
break;
Expand Down
15 changes: 10 additions & 5 deletions mms-lib/src/mms_task.c
Expand Up @@ -218,13 +218,14 @@ mms_task_transmit(

void
mms_task_network_unavailable(
MMSTask* task)
MMSTask* task,
gboolean can_retry)
{
if (task->state != MMS_TASK_STATE_DONE) {
MMS_ASSERT(task->state == MMS_TASK_STATE_NEED_CONNECTION ||
task->state == MMS_TASK_STATE_NEED_USER_CONNECTION ||
task->state == MMS_TASK_STATE_TRANSMITTING);
MMS_TASK_GET_CLASS(task)->fn_network_unavailable(task);
MMS_TASK_GET_CLASS(task)->fn_network_unavailable(task, can_retry);
MMS_ASSERT(task->state != MMS_TASK_STATE_NEED_CONNECTION &&
task->state != MMS_TASK_STATE_NEED_USER_CONNECTION &&
task->state != MMS_TASK_STATE_TRANSMITTING);
Expand Down Expand Up @@ -253,12 +254,16 @@ mms_task_set_state(
const unsigned int secs = task_config(task)->retry_secs;
if (!mms_task_schedule_wakeup(task, secs)) {
MMS_DEBUG("%s SLEEP -> DONE (no time left)", task->name);
MMS_TASK_GET_CLASS(task)->fn_cancel(task);
state = MMS_TASK_STATE_DONE;
}
}
task->state = state;
if (task->delegate && task->delegate->fn_task_state_changed) {
task->delegate->fn_task_state_changed(task->delegate, task);
/* Canceling the task may change the state so check it again */
if (task->state != state) {
task->state = state;
if (task->delegate && task->delegate->fn_task_state_changed) {
task->delegate->fn_task_state_changed(task->delegate, task);
}
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions mms-lib/src/mms_task.h
Expand Up @@ -77,7 +77,7 @@ typedef struct mms_task_class {
/* Invoked in NEED_[USER_]CONNECTION state */
void (*fn_transmit)(MMSTask* task, MMSConnection* conn);
/* Invoked in NEED_[USER_]CONNECTION or TRANSMITTING state */
void (*fn_network_unavailable)(MMSTask* task);
void (*fn_network_unavailable)(MMSTask* task, gboolean can_retry);
/* May be invoked in any state */
void (*fn_cancel)(MMSTask* task);
} MMSTaskClass;
Expand Down Expand Up @@ -115,7 +115,8 @@ mms_task_transmit(

void
mms_task_network_unavailable(
MMSTask* task);
MMSTask* task,
gboolean can_retry);

void
mms_task_cancel(
Expand Down
11 changes: 8 additions & 3 deletions mms-lib/src/mms_task_http.c
Expand Up @@ -504,10 +504,15 @@ mms_task_http_run(
static
void
mms_task_http_network_unavailable(
MMSTask* task)
MMSTask* task,
gboolean can_retry)
{
mms_task_http_finish_transfer(MMS_TASK_HTTP(task));
mms_task_set_state(task, MMS_TASK_STATE_SLEEP);
if (can_retry) {
mms_task_http_finish_transfer(MMS_TASK_HTTP(task));
mms_task_set_state(task, MMS_TASK_STATE_SLEEP);
} else {
mms_task_cancel(task);
}
}

static
Expand Down
15 changes: 12 additions & 3 deletions mms-lib/test/common/test_connman.c
Expand Up @@ -27,6 +27,7 @@ typedef struct mms_connman_test {
unsigned short port;
gboolean proxy;
char* default_imsi;
gboolean offline;
mms_connman_test_connect_fn connect_fn;
void* connect_param;
} MMSConnManTest;
Expand All @@ -47,6 +48,14 @@ mms_connman_test_set_port(
test->proxy = proxy;
}

void
mms_connman_test_set_offline(
MMSConnMan* cm,
gboolean offline)
{
MMS_CONNMAN_TEST(cm)->offline = offline;
}

void
mms_connman_test_set_default_imsi(
MMSConnMan* cm,
Expand Down Expand Up @@ -98,12 +107,12 @@ mms_connman_test_open_connection(
{
MMSConnManTest* test = MMS_CONNMAN_TEST(cm);
mms_connman_test_close_connection(cm);
if (test->port) {
if (test->offline) {
return NULL;
} else {
test->conn = mms_connection_test_new(imsi, test->port, test->proxy);
if (test->connect_fn) test->connect_fn(test->connect_param);
return mms_connection_ref(test->conn);
} else {
return NULL;
}
}

Expand Down
5 changes: 5 additions & 0 deletions mms-lib/test/common/test_connman.h
Expand Up @@ -31,6 +31,11 @@ mms_connman_test_set_port(
unsigned short port,
gboolean proxy);

void
mms_connman_test_set_offline(
MMSConnMan* cm,
gboolean offline);

void
mms_connman_test_set_default_imsi(
MMSConnMan* cm,
Expand Down
2 changes: 1 addition & 1 deletion mms-lib/test/common/test_http.c
Expand Up @@ -85,7 +85,7 @@ GBytes*
test_http_get_post_data(
TestHttp* http)
{
return http->req_bytes;
return http ? http->req_bytes : NULL;
}

void
Expand Down
Binary file not shown.
Binary file not shown.
54 changes: 47 additions & 7 deletions mms-lib/test/retrieve/test_retrieve.c
Expand Up @@ -56,6 +56,8 @@ typedef struct test_desc {
#define TEST_PUSH_HANDLING_FAILURE_OK (0x01)
#define TEST_DEFER_RECEIVE (0x02)
#define TEST_REJECT_RECEIVE (0x04)
#define TEST_CONNECTION_FAILURE (0x08)
#define TEST_OFFLINE (0x10)

} TestDesc;

Expand Down Expand Up @@ -199,6 +201,30 @@ static const TestDesc retrieve_tests[] = {
MMS_MESSAGE_TYPE_NONE,
TEST_PARTS_NONE,
0
},{
"Offline",
NULL,
"m-notification.ind",
NULL,
0,
NULL,
NULL,
MMS_RECEIVE_STATE_DOWNLOAD_ERROR,
MMS_MESSAGE_TYPE_NONE,
TEST_PARTS_NONE,
TEST_OFFLINE
},{
"Timeout",
NULL,
"m-notification.ind",
NULL,
0,
NULL,
NULL,
MMS_RECEIVE_STATE_DOWNLOAD_ERROR,
MMS_MESSAGE_TYPE_NONE,
TEST_PARTS_NONE,
TEST_CONNECTION_FAILURE
},{
"NotAllowed",
NULL,
Expand Down Expand Up @@ -445,13 +471,13 @@ test_init(
char* ni = g_strconcat(DATA_DIR, dir, "/", desc->ni_file, NULL);
char* rc = desc->rc_file ? g_strconcat(DATA_DIR, dir, "/",
desc->rc_file, NULL) : NULL;
MMS_DEBUG(">>>>>>>>>> %s <<<<<<<<<<", desc->name);
memset(test, 0, sizeof(*test));
test->config = config;
test->notification_ind = g_mapped_file_new(ni, FALSE, &error);
if (test->notification_ind) {
if (rc) test->retrieve_conf = g_mapped_file_new(rc, FALSE, &error);
if (test->retrieve_conf || !rc) {
guint port;
MMSSettings* settings = mms_settings_default_new(config);
g_mapped_file_ref(test->notification_ind);
test->desc = desc;
Expand All @@ -462,10 +488,15 @@ test_init(
test->timeout_id = g_timeout_add_seconds(10, test_timeout, test);
test->delegate.fn_done = test_done;
mms_dispatcher_set_delegate(test->disp, &test->delegate);
test->http = test_http_new(test->retrieve_conf,
test->desc->content_type, test->desc->status);
port = test_http_get_port(test->http);
mms_connman_test_set_port(test->cm, port, TRUE);
if (!(desc->flags & TEST_CONNECTION_FAILURE)) {
test->http = test_http_new(test->retrieve_conf,
test->desc->content_type, test->desc->status);
mms_connman_test_set_port(test->cm,
test_http_get_port(test->http), TRUE);
}
if (desc->flags & TEST_OFFLINE) {
mms_connman_test_set_offline(test->cm, TRUE);
}
if (desc->flags & TEST_REJECT_RECEIVE) {
mms_handler_test_reject_receive(test->handler);
}
Expand Down Expand Up @@ -593,7 +624,7 @@ int main(int argc, char* argv[])
mms_lib_init(argv[0]);
options = g_option_context_new("[TEST] - MMS retrieve test");
g_option_context_add_main_entries(options, entries, NULL);
if (g_option_context_parse(options, &argc, &argv, &error) && argc < 3) {
if (g_option_context_parse(options, &argc, &argv, &error)) {
MMSConfig config;
const char* test_name = (argc == 2) ? argv[1] : NULL;
char* tmpd = g_mkdtemp(g_strdup("/tmp/test_retrieve_XXXXXX"));
Expand All @@ -617,7 +648,16 @@ int main(int argc, char* argv[])
mms_log_stdout_timestamp = FALSE;
}

ret = test_retrieve(&config, test_name);
if (argc < 2) {
ret = test_retrieve(&config, test_name);
} else {
int i;
for (i=1, ret = RET_OK; i<argc; i++) {
int test_status = test_retrieve(&config, argv[i]);
if (ret == RET_OK && test_status != RET_OK) ret = test_status;
}
}

remove(tmpd);
g_free(tmpd);
} else {
Expand Down
13 changes: 9 additions & 4 deletions mms-ofono/src/mms_ofono_connman.c
Expand Up @@ -57,7 +57,8 @@ mms_ofono_connman_default_imsi(

/**
* Creates a new connection or returns the reference to an aready active one.
* The caller must release the reference.
* The caller must release the reference. Returns NULL if the modem is offline
* and the network task should fail immediately.
*/
static
MMSConnection*
Expand All @@ -68,7 +69,11 @@ mms_ofono_connman_open_connection(
{
MMSOfonoConnMan* ofono = MMS_OFONO_CONNMAN(cm);
MMSOfonoModem* modem = mms_ofono_manager_modem_for_imsi(ofono->man, imsi);
if (modem) {
if (!modem) {
MMS_INFO("SIM %s is not avialable", imsi);
} else if (!modem->online) {
MMS_INFO("SIM %s is offline", imsi);
} else {
MMSOfonoContext* mms = modem->mms_context;
if (mms) {
if (!mms->connection) {
Expand All @@ -78,9 +83,9 @@ mms_ofono_connman_open_connection(
mms_ofono_context_set_active(mms, TRUE);
}
return mms_connection_ref(&mms->connection->connection);
} else {
MMS_WARN("SIM %s has no MMS context", imsi);
}
} else {
MMS_DEBUG("SIM %s is not avialable", imsi);
}
return NULL;
}
Expand Down
12 changes: 12 additions & 0 deletions mms-ofono/src/mms_ofono_modem.c
Expand Up @@ -329,6 +329,12 @@ mms_ofono_modem_property_changed(
GVariant* value = g_variant_get_variant(variant);
mms_ofono_modem_scan_interfaces(modem, value);
g_variant_unref(value);
} else if (!strcmp(key, OFONO_MODEM_PROPERTY_ONLINE)) {
GVariant* value = g_variant_get_variant(variant);
modem->online = g_variant_get_boolean(value);
MMS_DEBUG("Modem %s is %sline", modem->path,
modem->online? "on" : "off");
g_variant_unref(value);
}
}

Expand All @@ -345,6 +351,8 @@ mms_ofono_modem_new(
if (proxy) {
GVariant* interfaces = g_variant_lookup_value(properties,
OFONO_MODEM_PROPERTY_INTERFACES, G_VARIANT_TYPE_STRING_ARRAY);
GVariant* online = g_variant_lookup_value(properties,
OFONO_MODEM_PROPERTY_ONLINE, G_VARIANT_TYPE_BOOLEAN);
modem = g_new0(MMSOfonoModem, 1);
MMS_DEBUG("Modem path '%s'", path);
MMS_VERBOSE_("%p '%s'", modem, path);
Expand All @@ -356,6 +364,10 @@ mms_ofono_modem_new(
mms_ofono_modem_scan_interfaces(modem, interfaces);
g_variant_unref(interfaces);

modem->online = g_variant_get_boolean(online);
MMS_DEBUG("Modem %s is %sline", path, modem->online ? "on" : "off");
g_variant_unref(online);

/* Register to receive PropertyChanged notifications */
modem->property_change_signal_id = g_signal_connect(
proxy, "property-changed",
Expand Down
1 change: 1 addition & 0 deletions mms-ofono/src/mms_ofono_modem.h
Expand Up @@ -20,6 +20,7 @@
struct mms_ofono_modem {
GDBusConnection* bus;
char* path;
gboolean online;

struct _OrgOfonoModem* proxy;
gulong property_change_signal_id;
Expand Down
1 change: 1 addition & 0 deletions mms-ofono/src/mms_ofono_names.h
Expand Up @@ -23,6 +23,7 @@
#define OFONO_GPRS_INTERFACE OFONO_SERVICE ".ConnectionManager"
#define OFONO_CONTEXT_INTERFACE OFONO_SERVICE ".ConnectionContext"

#define OFONO_MODEM_PROPERTY_ONLINE "Online"
#define OFONO_MODEM_PROPERTY_INTERFACES "Interfaces"
#define OFONO_SIM_PROPERTY_SUBSCRIBER_IDENTITY "SubscriberIdentity"

Expand Down

0 comments on commit 23e0e96

Please sign in to comment.