Home | History | Annotate | Download | only in nexus
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <fcntl.h>
     21 #include <unistd.h>
     22 #include <malloc.h>
     23 #include <errno.h>
     24 #include <sys/types.h>
     25 #include <sys/stat.h>
     26 #include <unistd.h>
     27 
     28 #define LOG_TAG "Controller"
     29 
     30 #include <cutils/log.h>
     31 
     32 #include "Controller.h"
     33 #include "InterfaceConfig.h"
     34 
     35 extern "C" int init_module(void *, unsigned int, const char *);
     36 extern "C" int delete_module(const char *, unsigned int);
     37 
     38 Controller::Controller(const char *name, PropertyManager *propMngr,
     39                        IControllerHandler *handlers) {
     40     mPropMngr = propMngr;
     41     mName = strdup(name);
     42     mHandlers = handlers;
     43     mBoundInterface = NULL;
     44 }
     45 
     46 Controller::~Controller() {
     47     if (mBoundInterface)
     48         free(mBoundInterface);
     49     if (mName)
     50         free(mName);
     51 }
     52 
     53 int Controller::start() {
     54     return 0;
     55 }
     56 
     57 int Controller::stop() {
     58     return 0;
     59 }
     60 
     61 int Controller::loadKernelModule(char *modpath, const char *args) {
     62     void *module;
     63     unsigned int size;
     64 
     65     module = loadFile(modpath, &size);
     66     if (!module) {
     67         errno = -EIO;
     68         return -1;
     69     }
     70 
     71     int rc = init_module(module, size, args);
     72     free (module);
     73     return rc;
     74 }
     75 
     76 int Controller::unloadKernelModule(const char *modtag) {
     77     int rc = -1;
     78     int retries = 10;
     79 
     80     while (retries--) {
     81         rc = delete_module(modtag, O_NONBLOCK | O_EXCL);
     82         if (rc < 0 && errno == EAGAIN)
     83             usleep(1000*500);
     84         else
     85             break;
     86     }
     87 
     88     if (rc != 0) {
     89         LOGW("Unable to unload kernel driver '%s' (%s)", modtag,
     90              strerror(errno));
     91     }
     92     return rc;
     93 }
     94 
     95 bool Controller::isKernelModuleLoaded(const char *modtag) {
     96     FILE *fp = fopen("/proc/modules", "r");
     97 
     98     if (!fp) {
     99         LOGE("Unable to open /proc/modules (%s)", strerror(errno));
    100         return false;
    101     }
    102 
    103     char line[255];
    104     while(fgets(line, sizeof(line), fp)) {
    105         char *endTag = strchr(line, ' ');
    106 
    107         if (!endTag) {
    108             LOGW("Unable to find tag for line '%s'", line);
    109             continue;
    110         }
    111         if (!strncmp(line, modtag, (endTag - line))) {
    112             fclose(fp);
    113             return true;
    114         }
    115     }
    116 
    117     fclose(fp);
    118     return false;
    119 }
    120 
    121 void *Controller::loadFile(char *filename, unsigned int *_size)
    122 {
    123 	int ret, fd;
    124 	struct stat sb;
    125 	ssize_t size;
    126 	void *buffer = NULL;
    127 
    128 	/* open the file */
    129 	fd = open(filename, O_RDONLY);
    130 	if (fd < 0)
    131 		return NULL;
    132 
    133 	/* find out how big it is */
    134 	if (fstat(fd, &sb) < 0)
    135 		goto bail;
    136 	size = sb.st_size;
    137 
    138 	/* allocate memory for it to be read into */
    139 	buffer = malloc(size);
    140 	if (!buffer)
    141 		goto bail;
    142 
    143 	/* slurp it into our buffer */
    144 	ret = read(fd, buffer, size);
    145 	if (ret != size)
    146 		goto bail;
    147 
    148 	/* let the caller know how big it is */
    149 	*_size = size;
    150 
    151 bail:
    152 	close(fd);
    153 	return buffer;
    154 }
    155 
    156 int Controller::bindInterface(const char *ifname) {
    157     mBoundInterface = strdup(ifname);
    158     return 0;
    159 }
    160 
    161 int Controller::unbindInterface(const char *ifname) {
    162     free(mBoundInterface);
    163     mBoundInterface = NULL;
    164     return 0;
    165 }
    166