gatppp: Add new contructor to use external fd
authorGuillaume Zajac <guillaume.zajac@linux.intel.com>
Thu, 19 May 2011 09:58:28 +0000 (11:58 +0200)
committerDenis Kenzior <denkenz@gmail.com>
Tue, 24 May 2011 17:10:22 +0000 (12:10 -0500)
gatchat/gatppp.c
gatchat/gatppp.h
gatchat/ppp.h
gatchat/ppp_net.c

index f2f2484..6d27dd6 100644 (file)
@@ -78,6 +78,7 @@ struct _GAtPPP {
        guint ppp_dead_source;
        GAtSuspendFunc suspend_func;
        gpointer suspend_data;
+       int fd;
 };
 
 void ppp_debug(GAtPPP *ppp, const char *str)
@@ -290,7 +291,7 @@ void ppp_auth_notify(GAtPPP *ppp, gboolean success)
 void ppp_ipcp_up_notify(GAtPPP *ppp, const char *local, const char *peer,
                                        const char *dns1, const char *dns2)
 {
-       ppp->net = ppp_net_new(ppp);
+       ppp->net = ppp_net_new(ppp, ppp->fd);
 
        if (ppp->net == NULL) {
                ppp->disconnect_reason = G_AT_PPP_REASON_NET_FAIL;
@@ -316,6 +317,7 @@ void ppp_ipcp_down_notify(GAtPPP *ppp)
                return;
 
        ppp_net_free(ppp->net);
+       ppp->fd = -1;
        ppp->net = NULL;
 }
 
@@ -522,6 +524,8 @@ void g_at_ppp_unref(GAtPPP *ppp)
 
        if (ppp->net)
                ppp_net_free(ppp->net);
+       else if (ppp->fd >= 0)
+               close(ppp->fd);
 
        if (ppp->chap)
                ppp_chap_free(ppp->chap);
@@ -565,6 +569,8 @@ static GAtPPP *ppp_init_common(GAtHDLC *hdlc, gboolean is_server, guint32 ip)
 
        ppp->ref_count = 1;
 
+       ppp->fd = -1;
+
        /* set options to defaults */
        ppp->mru = DEFAULT_MRU;
        ppp->mtu = DEFAULT_MTU;
@@ -657,3 +663,28 @@ GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local)
 
        return ppp;
 }
+
+GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd)
+{
+       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);
+
+       /* Set the fd value returned by ConnMan */
+       ppp->fd = fd;
+
+       g_at_hdlc_unref(hdlc);
+
+       return ppp;
+}
index 9464ffd..365123a 100644 (file)
@@ -54,6 +54,7 @@ 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);
+GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd);
 
 void g_at_ppp_open(GAtPPP *ppp);
 void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback,
index 22809d8..f866944 100644 (file)
@@ -102,7 +102,7 @@ void ppp_chap_free(struct ppp_chap *chap);
 void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet);
 
 /* TUN / Network related functions */
-struct ppp_net *ppp_net_new(GAtPPP *ppp);
+struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd);
 const char *ppp_net_get_interface(struct ppp_net *net);
 void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet);
 void ppp_net_free(struct ppp_net *net);
index 25bcfa4..52b3554 100644 (file)
@@ -123,35 +123,52 @@ const char *ppp_net_get_interface(struct ppp_net *net)
        return net->if_name;
 }
 
-struct ppp_net *ppp_net_new(GAtPPP *ppp)
+struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd)
 {
        struct ppp_net *net;
        GIOChannel *channel = NULL;
        struct ifreq ifr;
-       int fd, err;
+       int err;
 
        net = g_try_new0(struct ppp_net, 1);
-       if (net == NULL)
+       if (net == NULL) {
+               if (fd >= 0)
+                       close(fd);
+
                return NULL;
+       }
 
        net->ppp_packet = ppp_packet_new(MAX_PACKET, PPP_IP_PROTO);
        if (net->ppp_packet == NULL) {
+               if (fd >= 0)
+                       close(fd);
+
                g_free(net);
                return NULL;
        }
 
-       /* open a tun interface */
-       fd = open("/dev/net/tun", O_RDWR);
-       if (fd < 0)
-               goto error;
-
-       memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
-       strcpy(ifr.ifr_name, "ppp%d");
-
-       err = ioctl(fd, TUNSETIFF, (void *) &ifr);
-       if (err < 0)
-               goto error;
+       /*
+        * If the fd value is still the default one,
+        * open the tun interface and configure it.
+        */
+       if (fd < 0) {
+               /* open a tun interface */
+               fd = open("/dev/net/tun", O_RDWR);
+               if (fd < 0)
+                       goto error;
+
+               memset(&ifr, 0, sizeof(ifr));
+               ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+               strcpy(ifr.ifr_name, "ppp%d");
+
+               err = ioctl(fd, TUNSETIFF, (void *) &ifr);
+               if (err < 0)
+                       goto error;
+       } else {
+               err = ioctl(fd, TUNGETIFF, (void *) &ifr);
+               if (err < 0)
+                       goto error;
+       }
 
        net->if_name = strdup(ifr.ifr_name);