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