summaryrefslogtreecommitdiffstats
path: root/src/emulator.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-02-18 14:27:34 -0300
committerDenis Kenzior <denkenz@gmail.com>2011-02-18 13:20:29 -0600
commit19e09511b295aa9f6f0ce7c74877f5b40e533347 (patch)
treefc46feca6ae9b9b374b598a27ad76fb455d8fc70 /src/emulator.c
parente8553f53376a33504dd18c4d7bb6d6f309973e0a (diff)
downloadofono-19e09511b295aa9f6f0ce7c74877f5b40e533347.tar.bz2
emulator: add dialing support
It handles client ATD*99# request and then initiate the PPP negotiation. IP forward through the new ppp interface is not done yet. Initially based on patches from Zhenhua Zhang <zhenhua.zhang@intel.com>
Diffstat (limited to 'src/emulator.c')
-rw-r--r--src/emulator.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/emulator.c b/src/emulator.c
index 101b33d9..cb9e88f0 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -29,11 +29,19 @@
#include "ofono.h"
#include "gatserver.h"
+#include "gatppp.h"
+
+#define DUN_SERVER_ADDRESS "192.168.1.1"
+#define DUN_PEER_ADDRESS "192.168.1.2"
+#define DUN_DNS_SERVER_1 "10.10.10.10"
+#define DUN_DNS_SERVER_2 "10.10.10.11"
struct ofono_emulator {
struct ofono_atom *atom;
enum ofono_emulator_type type;
GAtServer *server;
+ GAtPPP *ppp;
+ guint source;
};
static void emulator_debug(const char *str, void *data)
@@ -50,12 +58,122 @@ static void emulator_disconnect(gpointer user_data)
ofono_emulator_remove(em);
}
+static void ppp_connect(const char *iface, const char *local,
+ const char *remote,
+ const char *dns1, const char *dns2,
+ gpointer user_data)
+{
+ DBG("Network Device: %s\n", iface);
+ DBG("IP Address: %s\n", local);
+ DBG("Remote IP Address: %s\n", remote);
+ DBG("Primary DNS Server: %s\n", dns1);
+ DBG("Secondary DNS Server: %s\n", dns2);
+}
+
+static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+
+ DBG("");
+
+ g_at_ppp_unref(em->ppp);
+ em->ppp = NULL;
+
+ if (em->server == NULL)
+ return;
+
+ g_at_server_resume(em->server);
+}
+
+static gboolean setup_ppp(gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtIO *io;
+
+ DBG("");
+
+ em->source = 0;
+
+ io = g_at_server_get_io(em->server);
+
+ g_at_server_suspend(em->server);
+
+ em->ppp = g_at_ppp_server_new_from_io(io, DUN_SERVER_ADDRESS);
+ if (em->ppp == NULL) {
+ g_at_server_resume(em->server);
+ return FALSE;
+ }
+
+ g_at_ppp_set_server_info(em->ppp, DUN_PEER_ADDRESS,
+ DUN_DNS_SERVER_1, DUN_DNS_SERVER_2);
+
+ g_at_ppp_set_credentials(em->ppp, "", "");
+ g_at_ppp_set_debug(em->ppp, emulator_debug, "PPP");
+
+ g_at_ppp_set_connect_function(em->ppp, ppp_connect, em);
+ g_at_ppp_set_disconnect_function(em->ppp, ppp_disconnect, em);
+
+ return FALSE;
+}
+
+static gboolean dial_call(struct ofono_emulator *em, const char *dial_str)
+{
+ char c = *dial_str;
+
+ DBG("dial call %s", dial_str);
+
+ if (c == '*' || c == '#' || c == 'T' || c == 't') {
+ g_at_server_send_intermediate(em->server, "CONNECT");
+ em->source = g_idle_add(setup_ppp, em);
+ }
+
+ return TRUE;
+}
+
+static void dial_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ const char *dial_str;
+
+ DBG("");
+
+ if (type != G_AT_SERVER_REQUEST_TYPE_SET)
+ goto error;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, ""))
+ goto error;
+
+ dial_str = g_at_result_iter_raw_line(&iter);
+ if (!dial_str)
+ goto error;
+
+ if (em->ppp)
+ goto error;
+
+ if (!dial_call(em, dial_str))
+ goto error;
+
+ return;
+
+error:
+ g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
+}
+
static void emulator_unregister(struct ofono_atom *atom)
{
struct ofono_emulator *em = __ofono_atom_get_data(atom);
DBG("%p", em);
+ if (em->source) {
+ g_source_remove(em->source);
+ em->source = 0;
+ }
+
g_at_server_unref(em->server);
em->server = NULL;
}
@@ -82,6 +200,9 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
emulator_disconnect, em);
__ofono_atom_register(em->atom, emulator_unregister);
+
+ if (em->type == OFONO_EMULATOR_TYPE_DUN)
+ g_at_server_register(em->server, "D", dial_cb, em, NULL);
}
static void emulator_remove(struct ofono_atom *atom)