summaryrefslogtreecommitdiffstats
path: root/gatchat/gatppp.c
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2010-04-30 14:37:17 -0500
committerDenis Kenzior <denkenz@gmail.com>2010-04-30 14:37:17 -0500
commit9ae0dcb47d71803681a205c4708be82d27111443 (patch)
tree4ff9a2e97411c39d0c36e134c537579cc86cce9d /gatchat/gatppp.c
parentc7ef06f91e32c1fa07a5cf8cf6f6b487eee021a9 (diff)
downloadofono-9ae0dcb47d71803681a205c4708be82d27111443.tar.bz2
ppp: get rid of ppp_enter_phase
This function simply didn't have the context of why the phase was being entered. Instead have each protocol notify GAtPPP as to what is happening. We already had this more or less for IPCP and AUTH events, this just now formalizes it for LCP as well.
Diffstat (limited to 'gatchat/gatppp.c')
-rw-r--r--gatchat/gatppp.c114
1 files changed, 73 insertions, 41 deletions
diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index 4205a795..253b33fe 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -43,6 +43,15 @@
#define DEFAULT_MRU 1500
#define DEFAULT_MTU 1500
+enum ppp_phase {
+ PPP_PHASE_DEAD = 0, /* Link dead */
+ PPP_PHASE_ESTABLISHMENT, /* LCP started */
+ PPP_PHASE_AUTHENTICATION, /* Auth started */
+ PPP_PHASE_NETWORK, /* IPCP started */
+ PPP_PHASE_LINK_UP, /* IPCP negotiation succeded, link up */
+ PPP_PHASE_TERMINATION, /* LCP Terminate phase */
+};
+
struct _GAtPPP {
gint ref_count;
enum ppp_phase phase;
@@ -89,9 +98,12 @@ static inline gboolean ppp_drop_packet(GAtPPP *ppp, guint16 protocol)
case PPP_PHASE_DEAD:
return TRUE;
case PPP_PHASE_NETWORK:
- if (ppp->net == NULL && protocol == PPP_IP_PROTO)
+ if (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL &&
+ protocol != IPCP_PROTO)
return TRUE;
break;
+ case PPP_PHASE_LINK_UP:
+ break;
}
return FALSE;
@@ -168,43 +180,13 @@ static void ppp_dead(GAtPPP *ppp)
ppp->disconnect_cb(ppp->disconnect_data);
}
-void ppp_enter_phase(GAtPPP *ppp, enum ppp_phase phase)
+static inline void ppp_enter_phase(GAtPPP *ppp, enum ppp_phase phase)
{
- /* don't do anything if we're already there */
- if (ppp->phase == phase)
- return;
-
- /* set new phase */
- ppp->phase = phase;
-
g_print("Entering new phase: %d\n", phase);
+ ppp->phase = phase;
- switch (phase) {
- case PPP_PHASE_ESTABLISHMENT:
- /* send an UP & OPEN events to the lcp layer */
- pppcp_signal_up(ppp->lcp);
- pppcp_signal_open(ppp->lcp);
- break;
- case PPP_PHASE_AUTHENTICATION:
- /* If we don't expect auth, move on to network phase */
- if (ppp->chap == NULL)
- ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
-
- /* otherwise wait for the peer to send us a challenge */
- break;
- case PPP_PHASE_NETWORK:
- /* Send UP & OPEN events to the IPCP layer */
- pppcp_signal_open(ppp->ipcp);
- pppcp_signal_up(ppp->ipcp);
- break;
- case PPP_PHASE_TERMINATION:
- pppcp_signal_down(ppp->ipcp);
- pppcp_signal_close(ppp->ipcp);
- break;
- case PPP_PHASE_DEAD:
+ if (phase == PPP_PHASE_DEAD)
ppp_dead(ppp);
- break;
- }
}
void ppp_set_auth(GAtPPP *ppp, const guint8* auth_data)
@@ -226,13 +208,19 @@ void ppp_set_auth(GAtPPP *ppp, const guint8* auth_data)
void ppp_auth_notify(GAtPPP *ppp, gboolean success)
{
- if (success)
- ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
- else
- ppp_enter_phase(ppp, PPP_PHASE_TERMINATION);
+ if (success == FALSE) {
+ pppcp_signal_close(ppp->lcp);
+ return;
+ }
+
+ ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
+
+ /* Send UP & OPEN events to the IPCP layer */
+ pppcp_signal_open(ppp->ipcp);
+ pppcp_signal_up(ppp->ipcp);
}
-void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
+void ppp_ipcp_up_notify(GAtPPP *ppp, const char *ip,
const char *dns1, const char *dns2)
{
ppp->net = ppp_net_new(ppp);
@@ -240,6 +228,8 @@ void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
if (ppp_net_set_mtu(ppp->net, ppp->mtu) == FALSE)
g_printerr("Unable to set MTU\n");
+ ppp_enter_phase(ppp, PPP_PHASE_LINK_UP);
+
if (ppp->connect_cb == NULL)
return;
@@ -252,7 +242,7 @@ void ppp_net_up_notify(GAtPPP *ppp, const char *ip,
ip, dns1, dns2, ppp->connect_data);
}
-void ppp_net_down_notify(GAtPPP *ppp)
+void ppp_ipcp_down_notify(GAtPPP *ppp)
{
/* Most likely we failed to create the interface */
if (ppp->net == NULL)
@@ -262,6 +252,41 @@ void ppp_net_down_notify(GAtPPP *ppp)
ppp->net = NULL;
}
+void ppp_ipcp_finished_notify(GAtPPP *ppp)
+{
+ if (ppp->phase != PPP_PHASE_NETWORK)
+ return;
+
+ /* Our IPCP parameter negotiation failed */
+ pppcp_signal_close(ppp->ipcp);
+ pppcp_signal_close(ppp->lcp);
+}
+
+void ppp_lcp_up_notify(GAtPPP *ppp)
+{
+ /* Wait for the peer to send us a challenge if we expect auth */
+ if (ppp->chap != NULL) {
+ ppp_enter_phase(ppp, PPP_PHASE_AUTHENTICATION);
+ return;
+ }
+
+ /* Otherwise proceed as if auth succeeded */
+ ppp_auth_notify(ppp, TRUE);
+}
+
+void ppp_lcp_down_notify(GAtPPP *ppp)
+{
+ if (ppp->phase == PPP_PHASE_NETWORK || ppp->phase == PPP_PHASE_LINK_UP)
+ pppcp_signal_down(ppp->ipcp);
+
+ ppp_enter_phase(ppp, PPP_PHASE_TERMINATION);
+}
+
+void ppp_lcp_finished_notify(GAtPPP *ppp)
+{
+ ppp_dead(ppp);
+}
+
void ppp_set_recv_accm(GAtPPP *ppp, guint32 accm)
{
g_at_hdlc_set_recv_accm(ppp->hdlc, accm);
@@ -288,13 +313,17 @@ static void io_disconnect(gpointer user_data)
GAtPPP *ppp = user_data;
pppcp_signal_down(ppp->lcp);
- ppp_enter_phase(ppp, PPP_PHASE_DEAD);
+ pppcp_signal_close(ppp->lcp);
}
/* Administrative Open */
void g_at_ppp_open(GAtPPP *ppp)
{
ppp_enter_phase(ppp, PPP_PHASE_ESTABLISHMENT);
+
+ /* send an UP & OPEN events to the lcp layer */
+ pppcp_signal_up(ppp->lcp);
+ pppcp_signal_open(ppp->lcp);
}
gboolean g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
@@ -367,6 +396,9 @@ void g_at_ppp_set_debug(GAtPPP *ppp, GAtDebugFunc func, gpointer user_data)
void g_at_ppp_shutdown(GAtPPP *ppp)
{
+ if (ppp->phase == PPP_PHASE_DEAD || ppp->phase == PPP_PHASE_TERMINATION)
+ return;
+
pppcp_signal_close(ppp->lcp);
}