diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c index e7a9f19a..1d41ded6 100644 --- a/gatchat/gatppp.c +++ b/gatchat/gatppp.c @@ -479,7 +479,7 @@ void g_at_ppp_set_server_info(GAtPPP *ppp, const char *remote, ipcp_set_server_info(ppp->ipcp, r, d1, d2); } -static GAtPPP *ppp_init_common(GAtHDLC *hdlc) +static GAtPPP *ppp_init_common(GAtHDLC *hdlc, gboolean is_server, guint32 ip) { GAtPPP *ppp; @@ -496,15 +496,18 @@ static GAtPPP *ppp_init_common(GAtHDLC *hdlc) ppp->mtu = DEFAULT_MTU; /* initialize the lcp state */ - ppp->lcp = lcp_new(ppp); + ppp->lcp = lcp_new(ppp, is_server); /* initialize IPCP state */ - ppp->ipcp = ipcp_new(ppp); + ppp->ipcp = ipcp_new(ppp, is_server, ip); g_at_hdlc_set_receive(ppp->hdlc, ppp_receive, ppp); g_at_io_set_disconnect_function(g_at_hdlc_get_io(ppp->hdlc), io_disconnect, ppp); + if (is_server) + ppp_enter_phase(ppp, PPP_PHASE_ESTABLISHMENT); + return ppp; } @@ -517,7 +520,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem) if (hdlc == NULL) return NULL; - ppp = ppp_init_common(hdlc); + ppp = ppp_init_common(hdlc, FALSE, 0); g_at_hdlc_unref(hdlc); return ppp; @@ -532,7 +535,49 @@ GAtPPP *g_at_ppp_new_from_io(GAtIO *io) if (hdlc == NULL) return NULL; - ppp = ppp_init_common(hdlc); + ppp = ppp_init_common(hdlc, FALSE, 0); + g_at_hdlc_unref(hdlc); + + return ppp; +} + +GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local) +{ + GAtHDLC *hdlc; + GAtPPP *ppp; + guint32 ip; + + if (local == NULL) + ip = 0; + else if (inet_pton(AF_INET, local, &ip) != 1) + return NULL; + + hdlc = g_at_hdlc_new(modem); + if (hdlc == NULL) + return NULL; + + ppp = ppp_init_common(hdlc, TRUE, ip); + g_at_hdlc_unref(hdlc); + + return ppp; +} + +GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local) +{ + GAtHDLC *hdlc; + GAtPPP *ppp; + guint32 ip; + + if (local == NULL) + ip = 0; + else if (inet_pton(AF_INET, local, &ip) != 1) + return NULL; + + hdlc = g_at_hdlc_new_from_io(io); + if (hdlc == NULL) + return NULL; + + ppp = ppp_init_common(hdlc, TRUE, ip); g_at_hdlc_unref(hdlc); return ppp; diff --git a/gatchat/gatppp.h b/gatchat/gatppp.h index 450a26df..fb5de4c3 100644 --- a/gatchat/gatppp.h +++ b/gatchat/gatppp.h @@ -52,6 +52,9 @@ typedef void (*GAtPPPDisconnectFunc)(GAtPPPDisconnectReason reason, GAtPPP *g_at_ppp_new(GIOChannel *modem); GAtPPP *g_at_ppp_new_from_io(GAtIO *io); +GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local); +GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local); + void g_at_ppp_open(GAtPPP *ppp); void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback, gpointer user_data); diff --git a/gatchat/ppp.h b/gatchat/ppp.h index d815b9fa..01ab8e03 100644 --- a/gatchat/ppp.h +++ b/gatchat/ppp.h @@ -79,12 +79,12 @@ static inline void __put_unaligned_short(void *p, guint16 val) (get_host_short(packet + 2)) /* LCP related functions */ -struct pppcp_data *lcp_new(GAtPPP *ppp); +struct pppcp_data *lcp_new(GAtPPP *ppp, gboolean dormant); void lcp_free(struct pppcp_data *lcp); void lcp_protocol_reject(struct pppcp_data *lcp, guint8 *packet, gsize len); /* IPCP related functions */ -struct pppcp_data *ipcp_new(GAtPPP *ppp); +struct pppcp_data *ipcp_new(GAtPPP *ppp, gboolean is_server, guint32 ip); void ipcp_free(struct pppcp_data *data); void ipcp_set_server_info(struct pppcp_data *ipcp, guint32 peer_addr, guint32 dns1, guint32 dns2); diff --git a/gatchat/ppp_cp.c b/gatchat/ppp_cp.c index b0a18aac..647e241e 100644 --- a/gatchat/ppp_cp.c +++ b/gatchat/ppp_cp.c @@ -996,7 +996,8 @@ void pppcp_set_local_options(struct pppcp_data *pppcp, pppcp->local_options_len = len; } -struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto) +struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto, + gboolean dormant) { struct pppcp_data *data; @@ -1004,7 +1005,11 @@ struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto) if (!data) return NULL; - data->state = INITIAL; + if (dormant) + data->state = STOPPED; + else + data->state = INITIAL; + data->config_timer_data.restart_interval = INITIAL_RESTART_TIMEOUT; data->terminate_timer_data.restart_interval = INITIAL_RESTART_TIMEOUT; data->config_timer_data.max_counter = MAX_CONFIGURE; diff --git a/gatchat/ppp_cp.h b/gatchat/ppp_cp.h index 4dbc86e2..56a20e04 100644 --- a/gatchat/ppp_cp.h +++ b/gatchat/ppp_cp.h @@ -103,7 +103,8 @@ guint8 ppp_option_iter_get_type(struct ppp_option_iter *iter); guint8 ppp_option_iter_get_length(struct ppp_option_iter *iter); const guint8 *ppp_option_iter_get_data(struct ppp_option_iter *iter); -struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto); +struct pppcp_data *pppcp_new(GAtPPP *ppp, const struct pppcp_proto *proto, + gboolean dormant); void pppcp_free(struct pppcp_data *data); void pppcp_set_data(struct pppcp_data *pppcp, gpointer data); diff --git a/gatchat/ppp_ipcp.c b/gatchat/ppp_ipcp.c index 7d59a4bb..f3456070 100644 --- a/gatchat/ppp_ipcp.c +++ b/gatchat/ppp_ipcp.c @@ -316,7 +316,7 @@ static enum rcr_result ipcp_server_rcr(struct ipcp_data *ipcp, struct ppp_option_iter iter; guint8 nak_options[MAX_CONFIG_OPTION_SIZE]; guint16 len = 0; - guint8 *rej_options; + guint8 *rej_options = NULL; guint16 rej_len = 0; guint32 addr; @@ -462,7 +462,7 @@ struct pppcp_proto ipcp_proto = { .rcr = ipcp_rcr, }; -struct pppcp_data *ipcp_new(GAtPPP *ppp) +struct pppcp_data *ipcp_new(GAtPPP *ppp, gboolean is_server, guint32 ip) { struct ipcp_data *ipcp; struct pppcp_data *pppcp; @@ -471,7 +471,7 @@ struct pppcp_data *ipcp_new(GAtPPP *ppp) if (!ipcp) return NULL; - pppcp = pppcp_new(ppp, &ipcp_proto); + pppcp = pppcp_new(ppp, &ipcp_proto, FALSE); if (!pppcp) { g_printerr("Failed to allocate PPPCP struct\n"); g_free(ipcp); @@ -479,7 +479,14 @@ struct pppcp_data *ipcp_new(GAtPPP *ppp) } pppcp_set_data(pppcp, ipcp); - ipcp_reset_client_config_options(ipcp); + ipcp->is_server = is_server; + + if (is_server) { + ipcp->local_addr = ip; + ipcp_reset_server_config_options(ipcp); + } else + ipcp_reset_client_config_options(ipcp); + pppcp_set_local_options(pppcp, ipcp->options, ipcp->options_len); return pppcp; diff --git a/gatchat/ppp_lcp.c b/gatchat/ppp_lcp.c index 2a5370b9..3cfab5c7 100644 --- a/gatchat/ppp_lcp.c +++ b/gatchat/ppp_lcp.c @@ -304,7 +304,7 @@ void lcp_free(struct pppcp_data *pppcp) pppcp_free(pppcp); } -struct pppcp_data *lcp_new(GAtPPP *ppp) +struct pppcp_data *lcp_new(GAtPPP *ppp, gboolean is_server) { struct pppcp_data *pppcp; struct lcp_data *lcp; @@ -313,7 +313,7 @@ struct pppcp_data *lcp_new(GAtPPP *ppp) if (!lcp) return NULL; - pppcp = pppcp_new(ppp, &lcp_proto); + pppcp = pppcp_new(ppp, &lcp_proto, is_server); if (!pppcp) { g_free(lcp); return NULL;