summaryrefslogtreecommitdiffstats
path: root/gatchat/gatppp.c
diff options
context:
space:
mode:
authorGuillaume Zajac <guillaume.zajac@linux.intel.com>2011-06-29 10:20:23 +0200
committerDenis Kenzior <denkenz@gmail.com>2011-06-29 00:22:25 -0500
commit84ccc874dad70dfa4464ae5a1b295373211882ca (patch)
treeb7e75460af0ec4fe028afc55bf9f9d346cdc6daf /gatchat/gatppp.c
parent00bd7f8735d05e7965704b0679518c274a71e5bb (diff)
downloadofono-84ccc874dad70dfa4464ae5a1b295373211882ca.tar.bz2
GAtPPP: Add ACFC option support
Diffstat (limited to 'gatchat/gatppp.c')
-rw-r--r--gatchat/gatppp.c96
1 files changed, 73 insertions, 23 deletions
diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index 5fb41461..42b32246 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -83,6 +83,7 @@ struct _GAtPPP {
int fd;
guint guard_timeout_source;
gboolean suspended;
+ gboolean xmit_acfc;
};
void ppp_debug(GAtPPP *ppp, const char *str)
@@ -168,8 +169,19 @@ static inline gboolean ppp_drop_packet(GAtPPP *ppp, guint16 protocol)
static void ppp_receive(const unsigned char *buf, gsize len, void *data)
{
GAtPPP *ppp = data;
- guint16 protocol = ppp_proto(buf);
- const guint8 *packet = ppp_info(buf);
+ struct ppp_header *header = (struct ppp_header *) buf;
+ gboolean acfc_frame = (header->address != PPP_ADDR_FIELD
+ || header->control != PPP_CTRL);
+ guint16 protocol;
+ const guint8 *packet;
+
+ if (acfc_frame) {
+ protocol = ppp_acfc_proto(buf);
+ packet = ppp_acfc_info(buf);
+ } else {
+ protocol = ppp_proto(buf);
+ packet = ppp_info(buf);
+ }
if (ppp_drop_packet(ppp, protocol))
return;
@@ -196,37 +208,29 @@ static void ppp_receive(const unsigned char *buf, gsize len, void *data)
};
}
-/*
- * transmit out through the lower layer interface
- *
- * infolen - length of the information part of the packet
- */
-void ppp_transmit(GAtPPP *ppp, guint8 *packet, guint infolen)
+static void ppp_send_lcp_frame(GAtPPP *ppp, guint8 *packet, guint infolen)
{
struct ppp_header *header = (struct ppp_header *) packet;
- guint16 proto = ppp_proto(packet);
guint8 code;
- gboolean lcp = (proto == LCP_PROTOCOL);
guint32 xmit_accm = 0;
gboolean sta = FALSE;
+ gboolean lcp;
/*
* all LCP Link Configuration, Link Termination, and Code-Reject
* packets must be sent with the default sending ACCM
*/
- if (lcp) {
- code = pppcp_get_code(packet);
- lcp = code > 0 && code < 8;
-
- /*
- * If we're going down, we try to make sure to send the final
- * ack before informing the upper layers via the ppp_disconnect
- * function. Once we enter PPP_DEAD phase, no further packets
- * will be sent
- */
- if (code == PPPCP_CODE_TYPE_TERMINATE_ACK)
- sta = TRUE;
- }
+ code = pppcp_get_code(packet);
+ lcp = code > 0 && code < 8;
+
+ /*
+ * If we're going down, we try to make sure to send the final
+ * ack before informing the upper layers via the ppp_disconnect
+ * function. Once we enter PPP_DEAD phase, no further packets
+ * will be sent
+ */
+ if (code == PPPCP_CODE_TYPE_TERMINATE_ACK)
+ sta = TRUE;
if (lcp) {
xmit_accm = g_at_hdlc_get_xmit_accm(ppp->hdlc);
@@ -251,6 +255,42 @@ void ppp_transmit(GAtPPP *ppp, guint8 *packet, guint infolen)
g_at_hdlc_set_xmit_accm(ppp->hdlc, xmit_accm);
}
+static void ppp_send_acfc_frame(GAtPPP *ppp, guint8 *packet,
+ guint infolen)
+{
+ struct ppp_header *header = (struct ppp_header *) packet;
+ guint offset = 0;
+
+ if (ppp->xmit_acfc)
+ offset = 2;
+
+ if (g_at_hdlc_send(ppp->hdlc, packet + offset,
+ infolen + sizeof(*header) - offset)
+ == FALSE)
+ DBG(ppp, "Failed to send a frame\n");
+}
+
+/*
+ * transmit out through the lower layer interface
+ *
+ * infolen - length of the information part of the packet
+ */
+void ppp_transmit(GAtPPP *ppp, guint8 *packet, guint infolen)
+{
+ guint16 proto = ppp_proto(packet);
+
+ switch (proto) {
+ case LCP_PROTOCOL:
+ ppp_send_lcp_frame(ppp, packet, infolen);
+ break;
+ case CHAP_PROTOCOL:
+ case IPCP_PROTO:
+ case PPP_IP_PROTO:
+ ppp_send_acfc_frame(ppp, packet, infolen);
+ break;
+ }
+}
+
static inline void ppp_enter_phase(GAtPPP *ppp, enum ppp_phase phase)
{
DBG(ppp, "%d", phase);
@@ -390,6 +430,11 @@ void ppp_set_mtu(GAtPPP *ppp, const guint8 *data)
ppp->mtu = mtu;
}
+void ppp_set_xmit_acfc(GAtPPP *ppp, gboolean acfc)
+{
+ ppp->xmit_acfc = acfc;
+}
+
static void io_disconnect(gpointer user_data)
{
GAtPPP *ppp = user_data;
@@ -658,6 +703,11 @@ void g_at_ppp_set_server_info(GAtPPP *ppp, const char *remote,
ipcp_set_server_info(ppp->ipcp, r, d1, d2);
}
+void g_at_ppp_set_acfc_enabled(GAtPPP *ppp, gboolean enabled)
+{
+ lcp_set_acfc_enabled(ppp->lcp, enabled);
+}
+
static GAtPPP *ppp_init_common(gboolean is_server, guint32 ip)
{
GAtPPP *ppp;