3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
37 #include <gatchat/gatserver.h>
39 #include "unit/stk-test-data.h"
41 #define OFONO_SERVICE "org.ofono"
42 #define STKTEST_PATH "/stktest"
43 #define STKTEST_ERROR "org.ofono.stktest.Error"
44 #define OFONO_ERROR "org.ofono.Error"
45 #define OFONO_MANAGER_INTERFACE OFONO_SERVICE ".Manager"
46 #define OFONO_MODEM_INTERFACE OFONO_SERVICE ".Modem"
47 #define OFONO_STK_INTERFACE OFONO_SERVICE ".SimToolkit"
48 #define OFONO_STKAGENT_INTERFACE OFONO_SERVICE ".SimToolkitAgent"
50 #define LISTEN_PORT 12765
53 TEST_STATE_POWERING_UP = 1,
54 TEST_STATE_REGISTERING_AGENT,
56 TEST_STATE_POWERING_DOWN,
60 TEST_RESULT_NOT_RUN = 0,
65 typedef DBusMessage *(*display_text_cb_t)(DBusMessage *msg, const char *text,
66 unsigned char icon_id,
68 typedef void (*terminal_response_func)(const unsigned char *pdu,
74 unsigned char *req_pdu;
76 unsigned char *rsp_pdu;
79 terminal_response_func tr_func;
80 enum test_result result;
83 static GMainLoop *main_loop = NULL;
84 static volatile sig_atomic_t __terminated = 0;
86 GList *cur_test = NULL;
89 static DBusConnection *conn;
90 static gboolean ofono_running = FALSE;
91 static guint modem_changed_watch;
92 enum test_state state;
93 DBusMessage *pending = NULL;
96 static guint server_watch;
97 static GAtServer *emulator;
99 /* Emulated modem state variables */
100 static int modem_mode = 0;
102 void __stktest_test_next();
103 void __stktest_test_finish(gboolean successful);
104 static gboolean create_tcp(void);
106 #define STKTEST_AGENT_ASSERT(expr) \
109 g_printerr("Assertion Failed %s:%d %s\n", \
110 __FILE__, __LINE__, #expr); \
111 __stktest_test_finish(FALSE); \
112 return stktest_error_failed(msg); \
116 #define STKTEST_RESPONSE_ASSERT(expect_pdu, expect_pdu_len, \
117 got_pdu, got_pdu_len) \
119 if ((expect_pdu_len) != (got_pdu_len)) { \
120 g_printerr("Assertion Failed %s:%d" \
121 " Wrong response len" \
122 " want: %d, got: %d\n", \
123 __FILE__, __LINE__, \
124 expect_pdu_len, got_pdu_len); \
125 __stktest_test_finish(FALSE); \
129 if (memcmp(expect_pdu, got_pdu, expect_pdu_len) != 0) { \
130 g_printerr("Assertion Failed %s:%d" \
131 "Wrong response\n", \
132 __FILE__, __LINE__); \
133 __stktest_test_finish(FALSE); \
138 static const char *to_hex(const unsigned char *data, unsigned int len)
140 static char buf[512+1];
143 for (i = 0; i < len; i++)
144 sprintf(buf + i * 2, "%02hhX", data[i]);
151 static void send_proactive_command(const unsigned char *pdu, unsigned int len)
155 sprintf(buf, "+CUSATP: %s", to_hex(pdu, len));
156 g_at_server_send_unsolicited(emulator, buf);
159 static DBusMessage *stktest_error_invalid_args(DBusMessage *msg)
161 return g_dbus_create_error(msg, STKTEST_ERROR ".InvalidArguments",
162 "Invalid arguments provided");
165 static DBusMessage *stktest_error_failed(DBusMessage *msg)
167 return g_dbus_create_error(msg, STKTEST_ERROR ".Failed",
171 static DBusMessage *stktest_error_end_session(DBusMessage *msg)
173 return g_dbus_create_error(msg, OFONO_ERROR ".EndSession",
174 "End Session Request");
177 static DBusMessage *stktest_error_go_back(DBusMessage *msg)
179 return g_dbus_create_error(msg, OFONO_ERROR ".GoBack",
183 static DBusMessage *stktest_error_busy(DBusMessage *msg)
185 return g_dbus_create_error(msg, OFONO_ERROR ".Busy",
189 static DBusMessage *agent_release(DBusConnection *conn, DBusMessage *msg,
192 g_print("Got Release\n");
195 dbus_message_unref(pending);
199 return dbus_message_new_method_return(msg);
202 static DBusMessage *agent_cancel(DBusConnection *conn, DBusMessage *msg,
206 dbus_message_unref(pending);
213 static DBusMessage *agent_display_text(DBusConnection *conn, DBusMessage *msg,
217 unsigned char icon_id;
220 display_text_cb_t func;
222 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &text,
223 DBUS_TYPE_BYTE, &icon_id,
224 DBUS_TYPE_BOOLEAN, &urgent,
225 DBUS_TYPE_INVALID) == FALSE)
226 return stktest_error_invalid_args(msg);
228 if (cur_test == NULL)
229 return stktest_error_failed(msg);
231 test = cur_test->data;
232 func = test->agent_func;
234 if (strcmp(test->method, "DisplayText")) {
235 g_printerr("Wrong method called!\n");
236 __stktest_test_finish(FALSE);
237 return stktest_error_failed(msg);
241 g_printerr("DisplayText not expected to be called");
242 __stktest_test_finish(FALSE);
243 return stktest_error_failed(msg);
246 return func(msg, text, icon_id, urgent);
249 static void server_debug(const char *str, void *data)
251 g_print("%s: %s\n", (char *) data, str);
254 static void cgmi_cb(GAtServer *server, GAtServerRequestType type,
255 GAtResult *cmd, gpointer user)
258 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
259 g_at_server_send_info(server, "oFono", TRUE);
260 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
262 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
263 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
266 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
270 static void cgmm_cb(GAtServer *server, GAtServerRequestType type,
271 GAtResult *cmd, gpointer user)
274 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
275 g_at_server_send_info(server, "oFono pre-1.0", TRUE);
276 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
278 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
279 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
282 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
286 static void cgmr_cb(GAtServer *server, GAtServerRequestType type,
287 GAtResult *cmd, gpointer user)
292 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
293 sprintf(buf, "oFono pre-1.0 version: %s", VERSION);
294 g_at_server_send_info(server, buf, TRUE);
295 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
297 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
298 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
301 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
305 static void cgsn_cb(GAtServer *server, GAtServerRequestType type,
306 GAtResult *cmd, gpointer user)
309 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
310 g_at_server_send_info(server, "123456789", TRUE);
311 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
313 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
314 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
317 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
321 static gboolean send_ok(gpointer user)
323 GAtServer *server = user;
325 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
330 static void cfun_cb(GAtServer *server, GAtServerRequestType type,
331 GAtResult *cmd, gpointer user)
336 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
337 g_at_server_send_info(server, "+CFUN: (0-1,4)", TRUE);
338 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
340 case G_AT_SERVER_REQUEST_TYPE_QUERY:
341 snprintf(buf, sizeof(buf), "+CFUN: %d", modem_mode);
342 g_at_server_send_info(server, buf, TRUE);
343 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
345 case G_AT_SERVER_REQUEST_TYPE_SET:
350 g_at_result_iter_init(&iter, cmd);
351 g_at_result_iter_next(&iter, "");
353 if (g_at_result_iter_next_number(&iter, &mode) == FALSE)
356 if (mode != 0 && mode != 1)
359 if (modem_mode == mode) {
360 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
365 g_timeout_add_seconds(1, send_ok, server);
375 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
378 static void cusatt_cb(GAtServer *server, GAtServerRequestType type,
379 GAtResult *cmd, gpointer user)
382 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
383 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
385 case G_AT_SERVER_REQUEST_TYPE_QUERY:
386 g_at_server_send_ext_final(server, "+CME ERROR: 4");
388 case G_AT_SERVER_REQUEST_TYPE_SET:
391 const unsigned char *pdu;
394 terminal_response_func func;
396 g_at_result_iter_init(&iter, cmd);
397 g_at_result_iter_next(&iter, "");
399 if (g_at_result_iter_next_hexstring(&iter, &pdu, &len) == FALSE)
402 if (cur_test == NULL)
405 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
407 test = cur_test->data;
408 func = test->tr_func;
419 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
422 static void listen_again(gpointer user_data)
424 g_at_server_unref(emulator);
427 if (create_tcp() == TRUE)
430 g_print("Error listening to socket\n");
431 g_main_loop_quit(main_loop);
434 static void setup_emulator(GAtServer *server)
436 g_at_server_set_debug(server, server_debug, "Server");
438 g_at_server_register(server, "+CGMI", cgmi_cb, NULL, NULL);
439 g_at_server_register(server, "+CGMM", cgmm_cb, NULL, NULL);
440 g_at_server_register(server, "+CGMR", cgmr_cb, NULL, NULL);
441 g_at_server_register(server, "+CGSN", cgsn_cb, NULL, NULL);
442 g_at_server_register(server, "+CFUN", cfun_cb, NULL, NULL);
443 g_at_server_register(server, "+CUSATT", cusatt_cb, NULL, NULL);
445 g_at_server_set_disconnect_function(server, listen_again, NULL);
448 static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
451 struct sockaddr saddr;
452 unsigned int len = sizeof(saddr);
454 GIOChannel *client_io = NULL;
459 fd = accept(g_io_channel_unix_get_fd(chan), &saddr, &len);
463 client_io = g_io_channel_unix_new(fd);
465 emulator = g_at_server_new(client_io);
466 g_at_server_set_echo(emulator, FALSE);
467 g_io_channel_unref(client_io);
469 if (emulator == NULL)
472 setup_emulator(emulator);
479 static gboolean create_tcp(void)
481 struct sockaddr_in addr;
484 GIOChannel *server_io;
486 sk = socket(PF_INET, SOCK_STREAM, 0);
488 g_print("Can't create tcp/ip socket: %s (%d)\n",
489 strerror(errno), errno);
493 memset(&addr, 0, sizeof(addr));
495 addr.sin_family = AF_INET;
496 addr.sin_addr.s_addr = INADDR_ANY;
497 addr.sin_port = htons(LISTEN_PORT);
499 setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
500 if (bind(sk, (struct sockaddr *) &addr, sizeof(struct sockaddr)) < 0) {
501 g_print("Can't bind socket: %s (%d)", strerror(errno), errno);
506 if (listen(sk, 1) < 0) {
507 g_print("Can't listen on socket: %s (%d)",
508 strerror(errno), errno);
513 g_print("new tcp is created at tcp port %d\n", LISTEN_PORT);
515 server_io = g_io_channel_unix_new(sk);
516 g_io_channel_set_close_on_unref(server_io, TRUE);
518 server_watch = g_io_add_watch_full(server_io,
520 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
521 on_socket_connected, NULL, NULL);
523 g_io_channel_unref(server_io);
528 static gboolean has_stk_interface(DBusMessageIter *iter)
530 DBusMessageIter entry;
532 dbus_message_iter_recurse(iter, &entry);
534 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
535 const char *interface;
537 dbus_message_iter_get_basic(&entry, &interface);
539 if (g_str_equal(interface, OFONO_STK_INTERFACE) == TRUE)
542 dbus_message_iter_next(&entry);
548 static int send_with_reply(const char *path, const char *interface,
549 const char *method, DBusPendingCall **call,
550 DBusPendingCallNotifyFunction cb,
551 void *user_data, DBusFreeFunction free_func,
552 int timeout, int type, ...)
559 msg = dbus_message_new_method_call(OFONO_SERVICE, path,
562 g_printerr("Unable to allocate new D-Bus %s message\n", method);
567 va_start(args, type);
569 if (!dbus_message_append_args_valist(msg, type, args)) {
580 if (!dbus_connection_send_with_reply(conn, msg, &c, timeout)) {
581 g_printerr("Sending %s failed\n", method);
589 dbus_pending_call_set_notify(c, cb, user_data, free_func);
590 dbus_pending_call_unref(c);
592 dbus_message_unref(msg);
597 if (free_func && user_data)
598 free_func(user_data);
601 dbus_message_unref(msg);
606 static void set_property_reply(DBusPendingCall *call, void *user_data)
608 DBusMessage *reply = dbus_pending_call_steal_reply(call);
611 dbus_error_init(&err);
613 if (dbus_set_error_from_message(&err, reply) == TRUE) {
614 g_printerr("%s: %s\n", err.name, err.message);
615 dbus_error_free(&err);
618 dbus_message_unref(reply);
621 static int set_property(const char *path, const char *interface,
622 const char *key, int type, const void *val,
623 DBusPendingCallNotifyFunction notify,
625 DBusFreeFunction destroy)
628 DBusMessageIter iter, value;
629 DBusPendingCall *call;
630 const char *signature;
632 msg = dbus_message_new_method_call(OFONO_SERVICE, path, interface,
637 dbus_message_set_auto_start(msg, FALSE);
639 dbus_message_iter_init_append(msg, &iter);
641 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
644 case DBUS_TYPE_BOOLEAN:
645 signature = DBUS_TYPE_BOOLEAN_AS_STRING;
648 dbus_message_unref(msg);
652 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
654 dbus_message_iter_append_basic(&value, type, val);
655 dbus_message_iter_close_container(&iter, &value);
657 if (dbus_connection_send_with_reply(conn, msg, &call, -1) == FALSE) {
658 dbus_message_unref(msg);
662 dbus_message_unref(msg);
667 dbus_pending_call_set_notify(call, notify, user_data, destroy);
669 dbus_pending_call_unref(call);
674 static void register_agent_reply(DBusPendingCall *call, void *user_data)
676 DBusMessage *reply = dbus_pending_call_steal_reply(call);
680 dbus_error_init(&err);
682 if (dbus_set_error_from_message(&err, reply) == TRUE) {
683 g_printerr("%s: %s\n", err.name, err.message);
684 dbus_error_free(&err);
687 dbus_message_unref(reply);
689 state = TEST_STATE_RUNNING;
690 test = cur_test->data;
691 send_proactive_command(test->req_pdu, test->req_len);
694 static void register_agent()
696 const char *path = "/default";
699 g_print("Gained STK interface, registering agent...\n");
701 status = send_with_reply(STKTEST_PATH, OFONO_STK_INTERFACE,
702 "RegisterAgent", NULL,
703 register_agent_reply, NULL, NULL, 1,
704 DBUS_TYPE_OBJECT_PATH, &path,
708 g_printerr("Unable to register agent with oFono\n");
709 g_main_loop_quit(main_loop);
713 state = TEST_STATE_REGISTERING_AGENT;
716 static gboolean modem_changed(DBusConnection *conn,
717 DBusMessage *msg, void *user_data)
719 DBusMessageIter iter, value;
720 const char *path, *key;
723 if (dbus_message_iter_init(msg, &iter) == FALSE)
726 path = dbus_message_get_path(msg);
728 if (g_str_equal(STKTEST_PATH, path) == FALSE)
731 dbus_message_iter_get_basic(&iter, &key);
733 dbus_message_iter_next(&iter);
734 dbus_message_iter_recurse(&iter, &value);
736 if (g_str_equal(key, "Interfaces") == FALSE)
739 has_stk = has_stk_interface(&value);
742 case TEST_STATE_POWERING_UP:
746 case TEST_STATE_REGISTERING_AGENT:
747 case TEST_STATE_RUNNING:
748 if (has_stk == FALSE)
749 g_printerr("Unexpectedly lost STK interface\n");
751 case TEST_STATE_POWERING_DOWN:
758 static void powerup(void)
760 dbus_bool_t powered = TRUE;
762 state = TEST_STATE_POWERING_UP;
763 set_property(STKTEST_PATH, OFONO_MODEM_INTERFACE, "Powered",
764 DBUS_TYPE_BOOLEAN, &powered,
765 set_property_reply, NULL, NULL);
768 static void get_modems_reply(DBusPendingCall *call, void *user_data)
770 DBusMessage *reply = dbus_pending_call_steal_reply(call);
771 DBusMessageIter iter, list;
773 gboolean found = FALSE;
775 dbus_error_init(&err);
777 if (dbus_set_error_from_message(&err, reply) == TRUE) {
778 g_printerr("%s: %s\n", err.name, err.message);
779 dbus_error_free(&err);
783 if (dbus_message_has_signature(reply, "a(oa{sv})") == FALSE)
786 if (dbus_message_iter_init(reply, &iter) == FALSE)
789 dbus_message_iter_recurse(&iter, &list);
791 while (dbus_message_iter_get_arg_type(&list) == DBUS_TYPE_STRUCT) {
792 DBusMessageIter entry;
795 dbus_message_iter_recurse(&list, &entry);
796 dbus_message_iter_get_basic(&entry, &path);
798 if (g_str_equal(path, STKTEST_PATH))
801 dbus_message_iter_next(&list);
805 dbus_message_unref(reply);
807 if (found == FALSE) {
808 g_printerr("STK Test modem not found\n");
809 g_main_loop_quit(main_loop);
813 g_print("Test modem found\n");
815 modem_changed_watch = g_dbus_add_signal_watch(conn, OFONO_SERVICE,
817 OFONO_MODEM_INTERFACE,
822 if (create_tcp() == FALSE) {
823 g_printerr("Unable to listen on modem emulator socket\n");
824 g_main_loop_quit(main_loop);
827 __stktest_test_next();
830 static int get_modems(DBusConnection *conn)
833 DBusPendingCall *call;
835 msg = dbus_message_new_method_call(OFONO_SERVICE, "/",
836 OFONO_MANAGER_INTERFACE, "GetModems");
840 dbus_message_set_auto_start(msg, FALSE);
842 g_print("getting modems\n");
844 if (dbus_connection_send_with_reply(conn, msg, &call, -1) == FALSE) {
845 dbus_message_unref(msg);
849 dbus_message_unref(msg);
854 dbus_pending_call_set_notify(call, get_modems_reply, conn, NULL);
856 dbus_pending_call_unref(call);
861 static const GDBusMethodTable agent_methods[] = {
862 { GDBUS_METHOD("Release", NULL, NULL, agent_release) },
863 { GDBUS_ASYNC_METHOD("DisplayText",
864 GDBUS_ARGS({ "text", "s" }, { "icon_id", "y" },
865 { "urgent", "b" }), NULL,
866 agent_display_text) },
867 { GDBUS_NOREPLY_METHOD("Cancel", NULL, NULL, agent_cancel) },
871 static void ofono_connect(DBusConnection *conn, void *user_data)
873 g_print("starting telephony interface\n");
875 if (!g_dbus_register_interface(conn, "/default",
876 OFONO_STKAGENT_INTERFACE,
877 agent_methods, NULL, NULL,
879 g_printerr("Unable to register local agent");
880 g_main_loop_quit(main_loop);
883 ofono_running = TRUE;
887 static void ofono_disconnect(DBusConnection *conn, void *user_data)
889 g_print("stopping telephony interface\n");
891 g_dbus_unregister_interface(conn, "/default", OFONO_STKAGENT_INTERFACE);
893 ofono_running = FALSE;
895 g_dbus_remove_watch(conn, modem_changed_watch);
896 modem_changed_watch = 0;
899 g_source_remove(server_watch);
903 g_at_server_unref(emulator);
907 static void sig_term(int sig)
909 if (__terminated > 0)
914 g_print("Terminating\n");
916 g_main_loop_quit(main_loop);
919 static void disconnect_callback(DBusConnection *conn, void *user_data)
921 g_printerr("D-Bus disconnect\n");
923 g_main_loop_quit(main_loop);
926 static gboolean end_session_and_finish(gpointer user_data)
928 g_at_server_send_unsolicited(emulator, "+CUSATEND");
929 __stktest_test_finish(TRUE);
934 static void expect_response(const unsigned char *pdu, unsigned int len)
936 struct test *test = cur_test->data;
938 STKTEST_RESPONSE_ASSERT(test->rsp_pdu, test->rsp_len, pdu, len);
940 g_idle_add(end_session_and_finish, NULL);
943 static DBusMessage *test_display_text_11(DBusMessage *msg,
945 unsigned char icon_id,
948 STKTEST_AGENT_ASSERT(g_str_equal(text, "Toolkit Test 1"));
949 STKTEST_AGENT_ASSERT(icon_id == 0);
950 STKTEST_AGENT_ASSERT(urgent == FALSE);
952 return dbus_message_new_method_return(msg);
955 static DBusMessage *test_display_text_12(DBusMessage *msg,
957 unsigned char icon_id,
960 STKTEST_AGENT_ASSERT(g_str_equal(text, "Toolkit Test 1"));
961 STKTEST_AGENT_ASSERT(icon_id == 0);
962 STKTEST_AGENT_ASSERT(urgent == FALSE);
964 return stktest_error_busy(msg);
967 static DBusMessage *test_display_text_13(DBusMessage *msg,
969 unsigned char icon_id,
972 STKTEST_AGENT_ASSERT(g_str_equal(text, "Toolkit Test 2"));
973 STKTEST_AGENT_ASSERT(icon_id == 0);
974 STKTEST_AGENT_ASSERT(urgent == TRUE);
976 return dbus_message_new_method_return(msg);
979 static DBusMessage *test_display_text_14(DBusMessage *msg,
981 unsigned char icon_id,
984 STKTEST_AGENT_ASSERT(g_str_equal(text, "Toolkit Test 3"));
985 STKTEST_AGENT_ASSERT(icon_id == 0);
986 STKTEST_AGENT_ASSERT(urgent == FALSE);
988 return dbus_message_new_method_return(msg);
991 static DBusMessage *test_display_text_15(DBusMessage *msg,
993 unsigned char icon_id,
996 STKTEST_AGENT_ASSERT(g_str_equal(text, "Toolkit Test 4"));
997 STKTEST_AGENT_ASSERT(icon_id == 0);
998 STKTEST_AGENT_ASSERT(urgent == FALSE);
1000 pending = dbus_message_ref(msg);
1005 static DBusMessage *test_display_text_16(DBusMessage *msg,
1007 unsigned char icon_id,
1010 STKTEST_AGENT_ASSERT(g_str_equal(text, "This command instructs the ME"
1011 " to display a text message. "
1012 "It allows the SIM to define "
1013 "the priority of that message, "
1014 "and the text string format. "
1015 "Two types of prio"));
1016 STKTEST_AGENT_ASSERT(icon_id == 0);
1017 STKTEST_AGENT_ASSERT(urgent == FALSE);
1019 return dbus_message_new_method_return(msg);
1022 static DBusMessage *test_display_text_17(DBusMessage *msg,
1024 unsigned char icon_id,
1027 /* oFono gives rich text formatting in HTML */
1028 STKTEST_AGENT_ASSERT(g_str_equal(text, "<GO-BACKWARDS>"));
1029 STKTEST_AGENT_ASSERT(icon_id == 0);
1030 STKTEST_AGENT_ASSERT(urgent == FALSE);
1032 return stktest_error_go_back(msg);
1035 static DBusMessage *test_display_text_18(DBusMessage *msg,
1037 unsigned char icon_id,
1040 /* oFono gives rich text formatting in HTML */
1041 STKTEST_AGENT_ASSERT(g_str_equal(text, "<ABORT>"));
1042 STKTEST_AGENT_ASSERT(icon_id == 0);
1043 STKTEST_AGENT_ASSERT(urgent == FALSE);
1045 return stktest_error_end_session(msg);
1048 static DBusMessage *test_display_text_21(DBusMessage *msg,
1050 unsigned char icon_id,
1053 STKTEST_AGENT_ASSERT(g_str_equal(text, "<TIME-OUT>"));
1054 STKTEST_AGENT_ASSERT(icon_id == 0);
1055 STKTEST_AGENT_ASSERT(urgent == FALSE);
1057 pending = dbus_message_ref(msg);
1062 static void power_down_reply(DBusPendingCall *call, void *user_data)
1064 __stktest_test_next();
1067 void __stktest_test_finish(gboolean successful)
1069 struct test *test = cur_test->data;
1070 dbus_bool_t powered = FALSE;
1072 test->result = successful ? TEST_RESULT_PASSED : TEST_RESULT_FAILED;
1074 state = TEST_STATE_POWERING_DOWN;
1075 set_property(STKTEST_PATH, OFONO_MODEM_INTERFACE, "Powered",
1076 DBUS_TYPE_BOOLEAN, &powered,
1077 power_down_reply, NULL, NULL);
1080 void __stktest_test_next()
1082 if (cur_test == NULL)
1085 cur_test = cur_test->next;
1087 if (cur_test == NULL)
1088 g_main_loop_quit(main_loop);
1093 static void stktest_add_test(const char *name, const char *method,
1094 const unsigned char *req, unsigned int req_len,
1095 const unsigned char *rsp, unsigned int rsp_len,
1097 terminal_response_func tr_func)
1099 struct test *test = g_new0(struct test, 1);
1101 test->name = g_strdup(name);
1102 test->method = g_strdup(method);
1103 test->req_pdu = g_memdup(req, req_len);
1104 test->req_len = req_len;
1105 test->rsp_pdu = g_memdup(rsp, rsp_len);
1106 test->rsp_len = rsp_len;
1107 test->agent_func = agent_func;
1108 test->tr_func = tr_func;
1110 tests = g_list_append(tests, test);
1113 static void __stktest_test_init(void)
1115 stktest_add_test("Display Text 1.1", "DisplayText",
1116 display_text_111, sizeof(display_text_111),
1117 display_text_response_111,
1118 sizeof(display_text_response_111),
1119 test_display_text_11, expect_response);
1120 stktest_add_test("Display Text 1.2", "DisplayText",
1121 display_text_111, sizeof(display_text_111),
1122 display_text_response_121,
1123 sizeof(display_text_response_121),
1124 test_display_text_12, expect_response);
1125 stktest_add_test("Display Text 1.3", "DisplayText",
1126 display_text_131, sizeof(display_text_131),
1127 display_text_response_131,
1128 sizeof(display_text_response_131),
1129 test_display_text_13, expect_response);
1130 stktest_add_test("Display Text 1.4", "DisplayText",
1131 display_text_141, sizeof(display_text_141),
1132 display_text_response_141,
1133 sizeof(display_text_response_141),
1134 test_display_text_14, expect_response);
1135 stktest_add_test("Display Text 1.5", "DisplayText",
1136 display_text_151, sizeof(display_text_151),
1137 display_text_response_151,
1138 sizeof(display_text_response_151),
1139 test_display_text_15, expect_response);
1140 stktest_add_test("Display Text 1.6", "DisplayText",
1141 display_text_161, sizeof(display_text_161),
1142 display_text_response_161,
1143 sizeof(display_text_response_161),
1144 test_display_text_16, expect_response);
1145 stktest_add_test("Display Text 1.7", "DisplayText",
1146 display_text_171, sizeof(display_text_171),
1147 display_text_response_171,
1148 sizeof(display_text_response_171),
1149 test_display_text_17, expect_response);
1150 stktest_add_test("Display Text 1.8", "DisplayText",
1151 display_text_181, sizeof(display_text_181),
1152 display_text_response_181,
1153 sizeof(display_text_response_181),
1154 test_display_text_18, expect_response);
1155 stktest_add_test("Display Text 1.9", "DisplayText",
1156 display_text_191, sizeof(display_text_191),
1157 display_text_response_191,
1158 sizeof(display_text_response_191),
1159 NULL, expect_response);
1160 stktest_add_test("Display Text 2.1", "DisplayText",
1161 display_text_211, sizeof(display_text_211),
1162 display_text_response_211,
1163 sizeof(display_text_response_211),
1164 test_display_text_21, expect_response);
1167 static void test_destroy(gpointer user_data)
1169 struct test *test = user_data;
1172 g_free(test->method);
1173 g_free(test->req_pdu);
1174 g_free(test->rsp_pdu);
1179 static void __stktest_test_summarize(void)
1183 g_print("\n\nTest Summary\n");
1184 g_print("============\n");
1186 for (l = tests; l; l = l->next) {
1187 struct test *test = l->data;
1189 g_print("%-60s", test->name);
1191 switch (test->result) {
1192 case TEST_RESULT_NOT_RUN:
1193 g_print("Not Run\n");
1195 case TEST_RESULT_PASSED:
1196 g_print("Passed\n");
1198 case TEST_RESULT_FAILED:
1199 g_print("Failed\n");
1205 static void __stktest_test_cleanup(void)
1207 g_list_free_full(tests, test_destroy);
1212 static gboolean option_version = FALSE;
1214 static GOptionEntry options[] = {
1215 { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
1216 "Show version information and exit" },
1220 int main(int argc, char **argv)
1222 GOptionContext *context;
1223 GError *error = NULL;
1226 struct sigaction sa;
1228 context = g_option_context_new(NULL);
1229 g_option_context_add_main_entries(context, options, NULL);
1231 if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
1232 if (error != NULL) {
1233 g_printerr("%s\n", error->message);
1234 g_error_free(error);
1236 g_printerr("An unknown error occurred\n");
1240 g_option_context_free(context);
1242 if (option_version == TRUE) {
1243 printf("%s\n", VERSION);
1247 __stktest_test_init();
1249 main_loop = g_main_loop_new(NULL, FALSE);
1251 dbus_error_init(&err);
1253 conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &err);
1255 if (dbus_error_is_set(&err) == TRUE) {
1256 fprintf(stderr, "%s\n", err.message);
1257 dbus_error_free(&err);
1259 fprintf(stderr, "Can't register with system bus\n");
1263 g_dbus_set_disconnect_function(conn, disconnect_callback, NULL, NULL);
1265 memset(&sa, 0, sizeof(sa));
1266 sa.sa_handler = sig_term;
1267 sigaction(SIGINT, &sa, NULL);
1268 sigaction(SIGTERM, &sa, NULL);
1270 watch = g_dbus_add_service_watch(conn, OFONO_SERVICE,
1271 ofono_connect, ofono_disconnect, NULL, NULL);
1273 g_main_loop_run(main_loop);
1275 g_dbus_remove_watch(conn, watch);
1277 if (ofono_running == TRUE)
1278 ofono_disconnect(conn, NULL);
1280 dbus_connection_unref(conn);
1282 g_main_loop_unref(main_loop);
1284 __stktest_test_summarize();
1285 __stktest_test_cleanup();