From 5d72c3af411ccdaa29a92beded4e5661d9807daf Mon Sep 17 00:00:00 2001 From: Ajit Vaishya Date: Sat, 15 Jul 2017 20:22:10 +0530 Subject: [PATCH] qsap: Add APIs to control and manage bridge interface. This adds APIs to trigger create, delete, interface up and interface down commands on bridge interface. It uses following IOCTLs for sending command to linux kernel: Add bridge iface: SIOCBRADDBR Remove bridge iface: SIOCBRDELBR Mark iface up/down: SIOCGIFFLAGS CRs-Fixed: 2080924 Change-Id: I3d34dc16e9ca82dc4b550cbc83fa4120c80ad54c --- softap/sdk/qsap_api.c | 81 +++++++++++++++++++++++++++++++++++++++++++ softap/sdk/qsap_api.h | 1 + 2 files changed, 82 insertions(+) diff --git a/softap/sdk/qsap_api.c b/softap/sdk/qsap_api.c index 4e65dbc..f16272d 100755 --- a/softap/sdk/qsap_api.c +++ b/softap/sdk/qsap_api.c @@ -3330,6 +3330,87 @@ void qsap_set_ini_filename(void) return; } +// IOCTL command to create and delete bridge interface // +#ifndef SIOCBRADDBR +#define SIOCBRADDBR 0x89a0 +#endif +#ifndef SIOCBRDELBR +#define SIOCBRDELBR 0x89a1 +#endif + +static int linux_set_iface_flags(int sock, const char *ifname, int dev_up) +{ + struct ifreq ifr; + int ret; + + if (sock < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) { + ret = errno ? -errno : -999; + ALOGE("Could not read interface %s flags: %s", + ifname, strerror(errno)); + return ret; + } + + if (dev_up) { + if (ifr.ifr_flags & IFF_UP) + return 0; + ifr.ifr_flags |= IFF_UP; + } else { + if (!(ifr.ifr_flags & IFF_UP)) + return 0; + ifr.ifr_flags &= ~IFF_UP; + } + + if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) { + ret = errno ? -errno : -999; + ALOGE("Could not set interface %s flags (%s): %s", + ifname, dev_up ? "UP" : "DOWN", strerror(errno)); + return ret; + } + return 0; +} + +int qsap_control_bridge(int argc, char ** argv) +{ + int br_socket; + + if (argc < 4) { + ALOGE("Command not supported"); + return -1; + } + + br_socket = socket(PF_INET, SOCK_DGRAM, 0); + if (br_socket < 0) { + ALOGE("socket(PF_INET,SOCK_DGRAM): %s",strerror(errno)); + return -1; + } + if (!strncmp(argv[2],"create",6)) { + if (ioctl(br_socket, SIOCBRADDBR, argv[3]) < 0) { + ALOGE("Could not add bridge %s: %s", argv[3], strerror(errno)); + return -1; + } + } else if (!strncmp(argv[2],"remove",6)) { + if (ioctl(br_socket, SIOCBRDELBR, argv[3]) < 0) { + ALOGE("Could not add remove %s: %s", argv[3], strerror(errno)); + return -1; + } + } else if (!strncmp(argv[2],"up",2)) { + return linux_set_iface_flags(br_socket, argv[3], 1); + } else if (!strncmp(argv[2],"down",4)) { + return linux_set_iface_flags(br_socket, argv[3], 0); + } else { + ALOGE("Command %s not handled.", argv[2]); + return -1; + } + + return 0; +} + int qsap_add_or_remove_interface(const char *newIface , int createIface) { const char *wlanIface = "wlan0"; diff --git a/softap/sdk/qsap_api.h b/softap/sdk/qsap_api.h index f5e4c23..2a1fb44 100755 --- a/softap/sdk/qsap_api.h +++ b/softap/sdk/qsap_api.h @@ -603,6 +603,7 @@ int qsap_get_mode(s32 *pmode); int qsap_prepare_softap(void); int qsap_unprepare_softap(void); int qsap_is_fst_enabled(void); +int qsap_control_bridge(int argc, char ** argv); #if __cplusplus }; // extern "C"