InterfaceController.cpp revision 2eab1f762badb7ba46b95716e62ea4548a979903
12eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/* 22eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Copyright (C) 2012 The Android Open Source Project 32eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 42eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License"); 52eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * you may not use this file except in compliance with the License. 62eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * You may obtain a copy of the License at 72eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 82eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * http://www.apache.org/licenses/LICENSE-2.0 92eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 102eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software 112eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS, 122eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * See the License for the specific language governing permissions and 142eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * limitations under the License. 152eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */ 162eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 172eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <stdlib.h> 182eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <errno.h> 192eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <fcntl.h> 202eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <string.h> 212eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 222eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/socket.h> 232eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/stat.h> 242eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/ioctl.h> 252eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/types.h> 262eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 272eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <netinet/in.h> 282eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <arpa/inet.h> 292eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 302eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#define LOG_TAG "InterfaceController" 312eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <cutils/log.h> 322eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <netutils/ifc.h> 332eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <private/android_filesystem_config.h> 342eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 352eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include "InterfaceController.h" 362eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 372eab1f762badb7ba46b95716e62ea4548a979903Dmitry ShmidtInterfaceController::InterfaceController() { 382eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt iSock = socket(AF_INET, SOCK_DGRAM, 0); 392eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (iSock < 0) 402eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt ALOGE("Failed to open socket"); 412eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt iBuf = (char *)malloc(INTERFACE_MAX_BUFFER_SIZE); 422eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (!iBuf) 432eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt ALOGE("Failed to allocate buffer"); 442eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 452eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 462eab1f762badb7ba46b95716e62ea4548a979903Dmitry ShmidtInterfaceController::~InterfaceController() { 472eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (iSock >= 0) 482eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt close(iSock); 492eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (iBuf) 502eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt free(iBuf); 512eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 522eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 532eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidtint InterfaceController::sendCommand(char *iface, char *cmd, char *buf, int buf_len) { 542eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt struct ifreq ifr; 552eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt android_wifi_priv_cmd priv_cmd; 562eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt int ret; 572eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 582eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (!iface || !cmd) 592eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt return -1; 602eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 612eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt memset(&ifr, 0, sizeof(ifr)); 622eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt memset(&priv_cmd, 0, sizeof(priv_cmd)); 632eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt strncpy(ifr.ifr_name, iface, IFNAMSIZ); 642eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt memcpy(buf, cmd, strlen(cmd) + 1); 652eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 662eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt priv_cmd.buf = buf; 672eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt priv_cmd.used_len = buf_len; 682eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt priv_cmd.total_len = buf_len; 692eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt ifr.ifr_data = &priv_cmd; 702eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 712eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if ((ret = ioctl(iSock, SIOCDEVPRIVATE + 1, &ifr)) < 0) { 722eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt ALOGE("Failed to execute command: %s", cmd); 732eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt } else { 742eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (buf[0] == '\0') { 752eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt snprintf(buf, buf_len, "OK"); 762eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt } 772eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt } 782eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt return ret; 792eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 802eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 812eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/* 822eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Arguments: 832eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * argv[2] - wlan interface 842eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * argv[3] - command 852eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * argv[4] - argument 862eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * rbuf - returned buffer 872eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */ 882eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidtint InterfaceController::interfaceCommand(int argc, char *argv[], char **rbuf) { 892eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt char cmd[INTERFACE_MAX_BUFFER_SIZE]; 902eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt unsigned int bc = 0; 912eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt int ret; 922eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt int i; 932eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 942eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if ((iSock < 0) || !iBuf || (argc < 4)) 952eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt return -1; 962eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 972eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt for (i=3; i < argc; i++) { 982eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt bc += snprintf(&cmd[bc], sizeof(cmd) - bc, "%s ", argv[i]); 992eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt } 1002eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (bc >= sizeof(cmd)) 1012eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt bc = sizeof(cmd) - 1; 1022eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt cmd[bc] = '\0'; 1032eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt ret = sendCommand(argv[2], cmd, iBuf, INTERFACE_MAX_BUFFER_SIZE); 1042eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt if (rbuf) 1052eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *rbuf = iBuf; 1062eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt return ret; 1072eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 108