static wifi_error get_firmware_bus_max_size_supported( wifi_interface_handle iface) { int ret = 0; interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); hal_info *info = (hal_info *)handle; WifihalGeneric busSizeSupported(handle, 0, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE); /* create the message */ ret = busSizeSupported.create(); if (ret < 0) goto cleanup; ret = busSizeSupported.set_iface_id(iinfo->name); if (ret < 0) goto cleanup; ret = busSizeSupported.requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); goto cleanup; } info->firmware_bus_max_size = busSizeSupported.getBusSize(); cleanup: return mapErrorKernelToWifiHAL(ret); }
static wifi_error acquire_supported_features(wifi_interface_handle iface, feature_set *set) { int ret = 0; interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); *set = 0; WifihalGeneric supportedFeatures(handle, 0, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES); /* create the message */ ret = supportedFeatures.create(); if (ret < 0) goto cleanup; ret = supportedFeatures.set_iface_id(iinfo->name); if (ret < 0) goto cleanup; ret = supportedFeatures.requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__func__, ret); goto cleanup; } supportedFeatures.getResponseparams(set); cleanup: return mapErrorKernelToWifiHAL(ret); }
//Implementation of the functions exposed in linklayer.h wifi_error wifi_set_link_stats(wifi_interface_handle iface, wifi_link_layer_params params) { int ret = 0; LLStatsCommand *LLCommand; struct nlattr *nl_data; interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); LLCommand = LLStatsCommand::instance(handle); if (LLCommand == NULL) { ALOGE("%s: Error LLStatsCommand NULL", __func__); return WIFI_ERROR_UNKNOWN; } LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET); /* create the message */ ret = LLCommand->create(); if (ret < 0) goto cleanup; ret = LLCommand->set_iface_id(iinfo->name); if (ret < 0) goto cleanup; /*add the attributes*/ nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA); if (!nl_data) goto cleanup; /**/ ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD, params.mpdu_size_threshold); if (ret < 0) goto cleanup; /**/ ret = LLCommand->put_u32( QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING, params.aggressive_statistics_gathering); if (ret < 0) goto cleanup; LLCommand->attr_end(nl_data); ret = LLCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__func__, ret); } cleanup: return (wifi_error)ret; }
/* * Function: CreateInterfaceEntry * * Arguments: dev - A pointer to the device name * regLifetime - The maximum registration lifetime that * are willing to accept. * advertiseOnBcast - Whether we will advertise on the * broadcast address. * minInterval - The minimum interval between adv. * maxInterval - The maximum interval between adv. * advLifetime - The maximum advertisement lifetime * lifetime that we will advertise on this * interface. * advSeqNum - The sequence number that we will * initially advertise. * servicesFlags - The flags that we will advertise * on the interface. * prefixFlags - determines whether we will advertise * the prefix length extension. * reverseTunnelAllowed - are we going to allow MN's to * request the reverse tunnel, and thereby send * FA_REVERSE_TUNNEL_UNAVAILABLE errors to MN's * requesting a reverse tunnel? Note, this is set to * RT_NONE, RT_FA, RT_HA, or RT_BOTH depending on which * of our agents is allowing the reverse tunnel. * reverseTunnelRequired - are we going to require MN's to * request the reverse tunnel, and thereby send * FA_REVERSE_TUNNEL_REQUIRED errors to MN's not * requesting a reverse tunnel? Note, this is set to * RT_NONE, RT_FA, RT_HA, or RT_BOTH depending on which * of our agents is requiring the reverse tunnel. * advInterval - Advertisement interval for this interface * * Description: This function will create an interface entry, * and will add it to the hash table. We will * directly retrieve the interface's IP address and * MAC address. * * Returns: int, 0 if successful. * * Comment: This function takes too many arguments. If this function * ever needs a major change, passing a structure with all * arguments should be considered. * */ int CreateInterfaceEntry(char *dev, int regLifetime, boolean_t advertiseOnBcast, int minInterval, int maxInterval, int advLifetime, uint16_t advSeqNum, int servicesFlags, boolean_t prefixFlags, uint8_t reverseTunnelAllowed, uint8_t reverseTunnelRequired, boolean_t advLimitUnsolicited, uint8_t advInitCount, uint32_t advInterval, boolean_t isDynamic) { MaAdvConfigEntry *entry; char *cp; /* If a virtual network interface is specified, warn the user */ if (dev != NULL) { if ((strncmp(dev, VNI, VNISTRLEN) == 0)) { cp = dev + VNISTRLEN; cp += strspn(cp, "0123456789"); if (*cp == '\0' || *cp == ':' || *cp == '*') syslog(LOG_WARNING, "%s specified. vni is a" " virtual interface that does not transmit" " or receive packets. See vni(7D)", dev); } } /* Let's check for dynamic interface entry */ if (strchr(dev, '*') == NULL) { entry = (MaAdvConfigEntry *) calloc(1, sizeof (MaAdvConfigEntry)); if (entry == NULL) { syslog(LOG_CRIT, "FATAL: Unable to allocate " "AdvConfigEntry"); return (-2); } } else { int len; DynamicIfaceTypeEntry *dyn_entry; DynamicIfaceTypeEntry *save_entry; /* * Since devicename contains '*', it must be an entry * for dynamic interface.For dynamic interface entry * in the config file, we do not create entry in the * MaAdvConfigEntry[], rather we keep a linked list * of dynamic interface types. For each type of dynamic * interface entry, the attributes will be common and * saved in DynamicIfaceTypeEntry data structure. * When mipagent detects one new interface that matches * with the same type and that is not an exisisting one * that went through down-up cycle, then it creates a new * entry and attaches to the MaAdvConfigEntry list */ len = strlen(dev); if (len > 0 && dev[len - 1] != '*') { syslog(LOG_ERR, "Invalid dynamic interface %s in mipagent.conf", dev); return (-1); } /* Replace '*' with null character */ dev[len -1] = '\0'; mipverbose(("CreateInterfaceEntry: dynamic device %s\n", dev)); if (dynamicIfaceHead == NULL) { dynamicIfaceHead = (DynamicIfaceTypeEntry *) calloc(1, sizeof (DynamicIfaceTypeEntry)); dyn_entry = dynamicIfaceHead; } else { /* search if this type exists already */ dyn_entry = dynamicIfaceHead; while (dyn_entry != NULL) { if (strcmp(dyn_entry->dynamicIfcetype, dev) == 0) { mipverbose(("CreateInterfaceEntry:" " Dynamic Entry already exists" " %s\n", dev)); return (0); } save_entry = dyn_entry; dyn_entry = dyn_entry->next; } dyn_entry = (DynamicIfaceTypeEntry *) calloc(1, sizeof (DynamicIfaceTypeEntry)); if (dyn_entry != NULL) { /* Link to the dynamicEntry list */ save_entry->next = dyn_entry; } } /* Fill in the structure with the parameter values */ (void) strncpy(dyn_entry->dynamicIfcetype, dev, LIFNAMSIZ); dyn_entry->AdvLimitUnsolicited = advLimitUnsolicited; dyn_entry->AdvInitCount = advInitCount; dyn_entry->AdvInterval = advInterval; dyn_entry->AdvServiceflag = servicesFlags; dyn_entry->AdvPrefixflag = prefixFlags; dyn_entry->RevtunReqd = reverseTunnelRequired; dyn_entry->RevtunAllowed = reverseTunnelAllowed; dyn_entry->RegLifetime = regLifetime; dyn_entry->AdvLifetime = advLifetime; dyn_entry->advertiseOnBcast = advertiseOnBcast; dyn_entry->next = NULL; /* Set the global variable DynamicInterface */ DynamicInterface = _B_TRUE; return (0); } /* else dynamic entry */ /* Now add our interface values */ (void) strncpy(entry->maIfaceName, dev, (LIFNAMSIZ -1)); /* * Simplify the configuration effort, read IP address, netmask * and hardware address directly from the interface. */ if (getIfaceInfo(entry->maIfaceName, &entry->maIfaceAddr, &entry->maIfaceNetmask, &entry->maIfaceFlags, &entry->maIfindex)) { free(entry); syslog(LOG_ERR, "Unable to get interface information: %m"); return (-1); } /* * Save the first address usable for registering with the * SNMP master. */ if (subagent_addr != 0) subagent_addr = entry->maIfaceAddr; /* * Don't attempt to get the hardware address if it's a point-to-point * interface. */ if ((entry->maIfaceFlags & IFF_POINTOPOINT) == 0) { if (getEthernetAddr(entry->maIfaceName, entry->maIfaceHWaddr)) { syslog(LOG_ERR, "Unable to get interface address " "information on %s (%s)", dev, strerror(errno)); mipverbose(("Unable to get interface address " "information on %s (%s)\n", dev, strerror(errno))); free(entry); return (-1); } } entry->maAdvMaxRegLifetime = regLifetime; /* * TODO: Under Solaris, pkts for LINK_BCAST_ADDR seem to * be sent on all of a host's interfaces. Don't know if this * can be controlled using some options similar to * IP_MULTICAST_IF. */ if (advertiseOnBcast == 1) { entry->maAdvAddr = inet_addr(LINK_BCAST_ADDR); } else { entry->maAdvAddr = inet_addr(LINK_MCAST_ADV_ADDR); } entry->maAdvMaxInterval = maxInterval; entry->maAdvMinInterval = minInterval; entry->maAdvMaxAdvLifetime = advLifetime; entry->maAdvSeqNum = advSeqNum; entry->maAdvServiceFlags = (char)servicesFlags; entry->maAdvPrefixLenInclusion = prefixFlags; entry->maReverseTunnelAllowed = reverseTunnelAllowed; entry->maReverseTunnelRequired = reverseTunnelRequired; entry->maAdvLimitUnsolicited = advLimitUnsolicited; if (advLimitUnsolicited == _B_FALSE) entry->maAdvInitCount = 1; else entry->maAdvInitCount = advInitCount; entry->maAdvInterval = advInterval; /* Set maNextAdvTime in getAndDispatchNetwork */ entry->maNextAdvTime = LONG_MAX; /* The follwoing is always set false in this routine */ entry->maAdvDynamicInterface = isDynamic; if (rwlock_init(&entry->maIfaceNodeLock, USYNC_THREAD, NULL)) { syslog(LOG_ERR, "Unable to initialize read/write lock"); free(entry); return (NULL); } /* * Ok, this is just a temp hack, but we need to save the * local address of the interface. Otherwise we will need to * configure the home agent for each Mobile Node, which is * just too much config for everybody. Given that we really * only work with one interface, this is not a big deal, but * this DOES need to be cleaned up. */ haAddr = entry->maIfaceAddr; /* * We do not request that the node be locked in this case since * we do not need the pointer to be returned. We are just calling * and ensuring that a pointer was in fact returned. */ if (linkHashTableEntryUint(&maAdvConfigHash, entry->maIfaceAddr, entry, LOCK_NONE)) { syslog(LOG_ERR, "Unable to add interface entry to hash table"); (void) rwlock_destroy(&entry->maIfaceNodeLock); free(entry); return (-1); } return (0); }
//Implementation of the functions exposed in LLStats.h wifi_error wifi_get_link_stats(wifi_request_id id, wifi_interface_handle iface, wifi_stats_result_handler handler) { int ret = 0; LLStatsCommand *LLCommand; struct nlattr *nl_data; interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); pthread_t tid; LLCommand = LLStatsCommand::instance(handle); if (LLCommand == NULL) { ALOGE("%s: Error LLStatsCommand NULL", __func__); return WIFI_ERROR_UNKNOWN; } LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET); LLCommand->initGetContext(id); LLStatsCallbackHandler callbackHandler = { .on_link_stats_results = handler.on_link_stats_results }; /* create the message */ ret = LLCommand->create(); if (ret < 0) goto cleanup; ret = LLCommand->set_iface_id(iinfo->name); if (ret < 0) goto cleanup; /*add the attributes*/ nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA); if (!nl_data) goto cleanup; ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID, id); if (ret < 0) goto cleanup; ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK, 7); if (ret < 0) goto cleanup; /**/ LLCommand->attr_end(nl_data); ret = LLCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__func__, ret); } if (ret < 0) goto cleanup; ret = LLCommand->setCallbackHandler(callbackHandler, QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS); if (ret < 0) goto cleanup; ret = LLCommand->setCallbackHandler(callbackHandler, QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS); if (ret < 0) goto cleanup; ret = LLCommand->setCallbackHandler(callbackHandler, QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS); if (ret < 0) goto cleanup; cleanup: return (wifi_error)ret; } //Implementation of the functions exposed in LLStats.h wifi_error wifi_clear_link_stats(wifi_interface_handle iface, u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp) { int ret = 0; LLStatsCommand *LLCommand; struct nlattr *nl_data; interface_info *iinfo = getIfaceInfo(iface); wifi_handle handle = getWifiHandle(iface); LLCommand = LLStatsCommand::instance(handle); if (LLCommand == NULL) { ALOGE("%s: Error LLStatsCommand NULL", __func__); return WIFI_ERROR_UNKNOWN; } LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR); /* create the message */ ret = LLCommand->create(); if (ret < 0) goto cleanup; ret = LLCommand->set_iface_id(iinfo->name); if (ret < 0) goto cleanup; /*add the attributes*/ nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA); if (!nl_data) goto cleanup; /**/ ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK, stats_clear_req_mask); if (ret < 0) goto cleanup; /**/ ret = LLCommand->put_u8(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ, stop_req); if (ret < 0) goto cleanup; LLCommand->attr_end(nl_data); ret = LLCommand->requestResponse(); if (ret != 0) { ALOGE("%s: requestResponse Error:%d",__func__, ret); } LLCommand->getClearRspParams(stats_clear_rsp_mask, stop_rsp); cleanup: LLCommand->unregisterHandler(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS); LLCommand->unregisterHandler(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS); LLCommand->unregisterHandler(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS); delete LLCommand; return (wifi_error)ret; }