summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2010-03-03 13:14:30 -0800
committerDmitry Shmidt <dimitrysh@google.com>2010-03-03 13:14:30 -0800
commit84c65a62fe7b053fed7f20274ca7379627a87b79 (patch)
treeb94a6103e3a2feb076a97d93814c24e88823cef7
parente7b9422f0dc7a18041536c63efe74c7095496258 (diff)
downloadnetd-84c65a62fe7b053fed7f20274ca7379627a87b79.tar.gz
softap: Add basic functionality directly through WEXT
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--SoftapController.cpp130
-rw-r--r--SoftapController.h8
2 files changed, 130 insertions, 8 deletions
diff --git a/SoftapController.cpp b/SoftapController.cpp
index 88bae5c4..66310b1b 100644
--- a/SoftapController.cpp
+++ b/SoftapController.cpp
@@ -26,6 +26,8 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <linux/wireless.h>
+
#define LOG_TAG "SoftapController"
#include <cutils/log.h>
@@ -33,13 +35,47 @@
SoftapController::SoftapController() {
mPid = 0;
+ mSock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (mSock < 0)
+ LOGE("Failed to open socket");
+ memset(mIface, 0, sizeof(mIface));
}
SoftapController::~SoftapController() {
+ if (mSock >= 0)
+ close(mSock);
+}
+
+int SoftapController::getPrivFuncNum(char *iface, const char *fname) {
+ struct iwreq wrq;
+ struct iw_priv_args *priv_ptr;
+ int i, ret;
+
+ strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name));
+ wrq.u.data.pointer = mBuf;
+ wrq.u.data.length = sizeof(mBuf) / sizeof(struct iw_priv_args);
+ wrq.u.data.flags = 0;
+ if ((ret = ioctl(mSock, SIOCGIWPRIV, &wrq)) < 0) {
+ LOGE("SIOCGIPRIV failed: %d", ret);
+ return ret;
+ }
+ priv_ptr = (struct iw_priv_args *)wrq.u.data.pointer;
+#if 0
+ for(i=0;(i < wrq.u.data.length);i++) {
+ LOGE("%s: [%x] %s\n", __func__, priv_ptr[i].cmd, priv_ptr[i].name);
+ }
+#endif
+ for(i=0;(i < wrq.u.data.length);i++) {
+ if (strcmp(priv_ptr[i].name, fname) == 0)
+ return priv_ptr[i].cmd;
+ }
+ return -1;
}
int SoftapController::startSoftap() {
+ struct iwreq wrq;
pid_t pid = 1;
+ int fnum, ret = 0;
LOGD("Softap start");
if (mPid) {
@@ -47,43 +83,123 @@ int SoftapController::startSoftap() {
errno = EBUSY;
return -1;
}
+ if (mSock < 0) {
+ LOGE("Failed to open socket");
+ return -1;
+ }
#if 0
if ((pid = fork()) < 0) {
LOGE("fork failed (%s)", strerror(errno));
return -1;
}
#endif
+ /* system("iwpriv wl0.1 AP_BSS_START"); */
if (!pid) {
- LOGE("Softap Started");
- return 0;
+ /* start hostapd */
+ return ret;
} else {
- mPid = pid;
+ LOGD("Softap Started: %s", mIface);
+ fnum = getPrivFuncNum(mIface, "AP_BSS_START");
+ if (fnum < 0) {
+ LOGE("Softap start - function not supported");
+ return -1;
+ }
+ strncpy(wrq.ifr_name, mIface, sizeof(wrq.ifr_name));
+ wrq.u.data.length = 0;
+ wrq.u.data.pointer = mBuf;
+ wrq.u.data.flags = 0;
+ ret = ioctl(mSock, fnum, &wrq);
+ if (ret) {
+ LOGE("Softap start - failed: %d", ret);
+ }
+ else {
+ mPid = pid;
+ LOGD("Softap start - Ok");
+ }
}
- return 0;
+ return ret;
}
int SoftapController::stopSoftap() {
+ struct iwreq wrq;
+ int fnum, ret;
+
LOGD("Softap stop");
if (mPid == 0) {
LOGE("Softap already stopped");
return 0;
}
+ if (mSock < 0) {
+ LOGE("Failed to open socket");
+ return -1;
+ }
+ fnum = getPrivFuncNum(mIface, "WL_AP_STOP");
+ if (fnum < 0) {
+ LOGE("Softap stop - function not supported");
+ return -1;
+ }
+ strncpy(wrq.ifr_name, mIface, sizeof(wrq.ifr_name));
+ wrq.u.data.length = 0;
+ wrq.u.data.pointer = mBuf;
+ wrq.u.data.flags = 0;
+ ret = ioctl(mSock, fnum, &wrq);
#if 0
LOGD("Stopping Softap service");
kill(mPid, SIGTERM);
waitpid(mPid, NULL, 0);
#endif
mPid = 0;
- LOGD("Softap service stopped");
- return 0;
+ LOGD("Softap service stopped: %d", ret);
+ return ret;
}
bool SoftapController::isSoftapStarted() {
return (mPid != 0 ? true : false);
}
+/*
+ * Arguments:
+ * argv[2] - wlan interface
+ * argv[3] - softap interface
+ * argv[4] - command line
+ */
int SoftapController::setSoftap(int argc, char *argv[]) {
+ struct iwreq wrq;
+ int fnum, ret;
+
LOGD("Softap set");
- return 0;
+ if (mSock < 0) {
+ LOGE("Failed to open socket");
+ return -1;
+ }
+ if (argc < 4) {
+ LOGE("Missing arguments");
+ return -1;
+ }
+
+ fnum = getPrivFuncNum(argv[2], "WL_AP_CFG");
+ if (fnum < 0) {
+ LOGE("Softap set - function not supported");
+ return -1;
+ }
+
+ strncpy(mIface, argv[3], sizeof(mIface));
+ strncpy(wrq.ifr_name, argv[2], sizeof(wrq.ifr_name));
+ if (argc >= 4) {
+ strncpy(mBuf, argv[4], sizeof(mBuf));
+ }
+
+ wrq.u.data.length = strlen(mBuf) + 1;
+ wrq.u.data.pointer = mBuf;
+ wrq.u.data.flags = 0;
+ /* system("iwpriv eth0 WL_AP_CFG ASCII_CMD=AP_CFG,SSID=\"AndroidAP\",SEC=\"open\",KEY=12345,CHANNEL=1,PREAMBLE=0,MAX_SCB=8,END"); */
+ ret = ioctl(mSock, fnum, &wrq);
+ if (ret) {
+ LOGE("Softap set - failed: %d", ret);
+ }
+ else {
+ LOGD("Softap set - Ok");
+ }
+ return ret;
}
diff --git a/SoftapController.h b/SoftapController.h
index 1af113dc..dc8936ad 100644
--- a/SoftapController.h
+++ b/SoftapController.h
@@ -18,12 +18,18 @@
#define _SOFTAP_CONTROLLER_H
#include <linux/in.h>
-
+#include <net/if.h>
#include <utils/List.h>
+#define SOFTAP_MAX_BUFFER_SIZE 4096
+
class SoftapController {
+ char mBuf[SOFTAP_MAX_BUFFER_SIZE];
+ char mIface[IFNAMSIZ];
pid_t mPid;
+ int mSock;
+ int getPrivFuncNum(char *iface, const char *fname);
public:
SoftapController();
virtual ~SoftapController();