static wifi_error wifi_get_capabilities(wifi_interface_handle handle) { wifi_error ret; int requestId; WifihalGeneric *wifihalGeneric; wifi_handle wifiHandle = getWifiHandle(handle); hal_info *info = getHalInfo(wifiHandle); if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { ALOGE("%s: GSCAN is not supported by driver", __FUNCTION__); return WIFI_ERROR_NOT_SUPPORTED; } /* No request id from caller, so generate one and pass it on to the driver. * Generate it randomly. */ requestId = get_requestid(); wifihalGeneric = new WifihalGeneric( wifiHandle, requestId, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES); if (!wifihalGeneric) { ALOGE("%s: Failed to create object of WifihalGeneric class", __FUNCTION__); return WIFI_ERROR_UNKNOWN; } ret = wifihalGeneric->wifiGetCapabilities(handle); delete wifihalGeneric; return ret; }
/* Run event handler */ void wifi_event_loop(wifi_handle handle) { hal_info *info = getHalInfo(handle); if (info->in_event_loop) { return; } else { info->in_event_loop = true; } pollfd pfd; memset(&pfd, 0, sizeof(pfd)); pfd.fd = nl_socket_get_fd(info->event_sock); pfd.events = POLLIN; /* TODO: Add support for timeouts */ do { int timeout = -1; /* Infinite timeout */ pfd.revents = 0; //ALOGI("Polling socket"); int result = poll(&pfd, 1, -1); ALOGI("Poll result = %0x", result); if (result < 0) { ALOGE("Error polling socket"); } else if (pfd.revents & (POLLIN | POLLHUP | POLLERR)) { internal_event_handler(handle, pfd.revents); } } while (!info->clean_up); ALOGI("Cleaning up"); internal_cleaned_up_handler(handle); }
static int internal_pollin_handler(wifi_handle handle) { hal_info *info = getHalInfo(handle); struct nl_cb *cb = nl_socket_get_cb(info->event_sock); int res = nl_recvmsgs(info->event_sock, cb); nl_cb_put(cb); return res; }
void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) { hal_info *info = getHalInfo(handle); info->cleaned_up_handler = handler; info->clean_up = true; ALOGI("Wifi cleanup completed"); }
static int user_sock_message_handler(nl_msg *msg, void *arg) { wifi_handle handle = (wifi_handle)arg; hal_info *info = getHalInfo(handle); diag_message_handler(info, msg); return NL_OK; }
static int internal_pollin_handler(wifi_handle handle) { hal_info *info = getHalInfo(handle); struct nl_cb *cb = nl_socket_get_cb(info->event_sock); int res = nl_recvmsgs(info->event_sock, cb); if(res) ALOGE("Error :%d while reading nl msg", res); nl_cb_put(cb); return res; }
static int internal_valid_message_handler(nl_msg *msg, void *arg) { wifi_handle handle = (wifi_handle)arg; hal_info *info = getHalInfo(handle); WifiEvent event(msg); int res = event.parse(); if (res < 0) { ALOGE("Failed to parse event: %d", res); return NL_SKIP; } int cmd = event.get_cmd(); uint32_t vendor_id = 0; int subcmd = 0; if (cmd == NL80211_CMD_VENDOR) { vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); ALOGV("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", event.get_cmdString(), vendor_id, subcmd); } else { ALOGV("event received %s", event.get_cmdString()); } ALOGV("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id); // event.log(); bool dispatched = false; for (int i = 0; i < info->num_event_cb; i++) { if (cmd == info->event_cb[i].nl_cmd) { if (cmd == NL80211_CMD_VENDOR && ((vendor_id != info->event_cb[i].vendor_id) || (subcmd != info->event_cb[i].vendor_subcmd))) { /* event for a different vendor, ignore it */ continue; } cb_info *cbi = &(info->event_cb[i]); (*(cbi->cb_func))(msg, cbi->cb_arg); dispatched = true; } } if (!dispatched) { ALOGV("event ignored!!"); } return NL_OK; }
void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) { if (!handle) { ALOGE("Handle is null"); return; } hal_info *info = getHalInfo(handle); info->cleaned_up_handler = handler; info->clean_up = true; TEMP_FAILURE_RETRY(write(info->exit_sockets[0], "E", 1)); ALOGI("Sent msg on exit sock to unblock poll()"); }
static void internal_cleaned_up_handler(wifi_handle handle) { hal_info *info = getHalInfo(handle); wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler; if (info->cmd_sock != 0) { nl_socket_free(info->cmd_sock); nl_socket_free(info->event_sock); info->cmd_sock = NULL; info->event_sock = NULL; } if (info->cldctx != NULL) { cld80211lib_cleanup(info); } else if (info->user_sock != 0) { nl_socket_free(info->user_sock); info->user_sock = NULL; } if (info->pkt_stats) free(info->pkt_stats); if (info->rx_aggr_pkts) free(info->rx_aggr_pkts); wifi_logger_ring_buffers_deinit(info); cleanupGscanHandlers(info); cleanupRSSIMonitorHandler(info); if (info->exit_sockets[0] >= 0) { close(info->exit_sockets[0]); info->exit_sockets[0] = -1; } if (info->exit_sockets[1] >= 0) { close(info->exit_sockets[1]); info->exit_sockets[1] = -1; } if (info->pkt_fate_stats) { free(info->pkt_fate_stats); info->pkt_fate_stats = NULL; } (*cleaned_up_handler)(handle); pthread_mutex_destroy(&info->cb_lock); pthread_mutex_destroy(&info->pkt_fate_stats_lock); free(info); }
static void internal_cleaned_up_handler(wifi_handle handle) { hal_info *info = getHalInfo(handle); wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler; if (info->cmd_sock != 0) { nl_socket_free(info->cmd_sock); nl_socket_free(info->event_sock); info->cmd_sock = NULL; info->event_sock = NULL; } (*cleaned_up_handler)(handle); free(info); ALOGI("Internal cleanup completed"); }
static int wifi_add_membership(wifi_handle handle, const char *group) { hal_info *info = getHalInfo(handle); int id = wifi_get_multicast_id(handle, "nl80211", group); if (id < 0) { ALOGE("Could not find group %s", group); return id; } int ret = nl_socket_add_membership(info->event_sock, id); if (ret < 0) { ALOGE("Could not add membership to group %s", group); } return ret; }
/* Run event handler */ void wifi_event_loop(wifi_handle handle) { hal_info *info = getHalInfo(handle); if (info->in_event_loop) { return; } else { info->in_event_loop = true; } pollfd pfd; memset(&pfd, 0, sizeof(pfd)); pfd.fd = nl_socket_get_fd(info->event_sock); pfd.events = POLLIN; /* TODO: Add support for timeouts */ do { int timeout = -1; /* Infinite timeout */ pfd.revents = 0; // ALOGI("Polling socket"); int result = poll(&pfd, 1, -1); if (result < 0) { ALOGE("Error polling socket"); } else if (pfd.revents & POLLERR) { ALOGE("POLL Error; error no = %d", errno); char buf[2048]; int result2 = read(pfd.fd, buf, sizeof(buf)); ALOGE("Read after POLL returned %d, error no = %d", result2, errno); } else if (pfd.revents & POLLHUP) { ALOGE("Remote side hung up"); break; } else if (pfd.revents & POLLIN) { // ALOGI("Found some events!!!"); internal_pollin_handler(handle); } else { ALOGE("Unknown event - %0x", pfd.revents); } } while (!info->clean_up); ALOGI("Cleaning up"); internal_cleaned_up_handler(handle); }
/* Run event handler */ void wifi_event_loop(wifi_handle handle) { hal_info *info = getHalInfo(handle); if (info->in_event_loop) { return; } else { info->in_event_loop = true; } pollfd pfd[3]; memset(&pfd, 0, 3*sizeof(pfd[0])); pfd[0].fd = nl_socket_get_fd(info->event_sock); pfd[0].events = POLLIN; pfd[1].fd = nl_socket_get_fd(info->user_sock); pfd[1].events = POLLIN; pfd[2].fd = info->exit_sockets[1]; pfd[2].events = POLLIN; /* TODO: Add support for timeouts */ do { pfd[0].revents = 0; pfd[1].revents = 0; pfd[2].revents = 0; //ALOGI("Polling sockets"); int result = poll(pfd, 3, -1); if (result < 0) { ALOGE("Error polling socket"); } else { if (pfd[0].revents & (POLLIN | POLLHUP | POLLERR)) { internal_event_handler(handle, pfd[0].revents, info->event_sock); } if (pfd[1].revents & (POLLIN | POLLHUP | POLLERR)) { internal_event_handler(handle, pfd[1].revents, info->user_sock); } } rb_timerhandler(info); } while (!info->clean_up); internal_cleaned_up_handler(handle); }
static int internal_valid_message_handler(nl_msg *msg, void *arg) { wifi_handle handle = (wifi_handle)arg; hal_info *info = getHalInfo(handle); WifiEvent event(msg); int res = event.parse(); if (res < 0) { ALOGE("Failed to parse event: %d", res); return NL_SKIP; } int cmd = event.get_cmd(); uint32_t vendor_id = 0; int subcmd = 0; if (cmd == NL80211_CMD_VENDOR) { vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", event.get_cmdString(), vendor_id, subcmd); } else { // ALOGI("event received %s", event.get_cmdString()); } // ALOGI("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id); // event.log(); bool dispatched = false; pthread_mutex_lock(&info->cb_lock); for (int i = 0; i < info->num_event_cb; i++) { if (cmd == info->event_cb[i].nl_cmd) { if (cmd == NL80211_CMD_VENDOR && ((vendor_id != info->event_cb[i].vendor_id) || (subcmd != info->event_cb[i].vendor_subcmd))) { /* event for a different vendor, ignore it */ continue; } cb_info *cbi = &(info->event_cb[i]); nl_recvmsg_msg_cb_t cb_func = cbi->cb_func; void *cb_arg = cbi->cb_arg; WifiCommand *cmd = (WifiCommand *)cbi->cb_arg; if (cmd != NULL) { cmd->addRef(); } pthread_mutex_unlock(&info->cb_lock); (*cb_func)(msg, cb_arg); if (cmd != NULL) { cmd->releaseRef(); } return NL_OK; } } pthread_mutex_unlock(&info->cb_lock); return NL_OK; }
static int internal_valid_message_handler(nl_msg *msg, void *arg) { wifi_handle handle = (wifi_handle)arg; hal_info *info = getHalInfo(handle); WifiEvent event(msg); int res = event.parse(); if (res < 0) { ALOGE("Failed to parse event: %d", res); return NL_SKIP; } int cmd = event.get_cmd(); uint32_t vendor_id = 0; int subcmd = 0; if (cmd == NL80211_CMD_VENDOR) { vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); /* Restrict printing GSCAN_FULL_RESULT which is causing lot of logs in bug report */ if (subcmd != QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) { ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", event.get_cmdString(), vendor_id, subcmd); } } else { ALOGV("event received %s", event.get_cmdString()); } // event.log(); bool dispatched = false; pthread_mutex_lock(&info->cb_lock); for (int i = 0; i < info->num_event_cb; i++) { if (cmd == info->event_cb[i].nl_cmd) { if (cmd == NL80211_CMD_VENDOR && ((vendor_id != info->event_cb[i].vendor_id) || (subcmd != info->event_cb[i].vendor_subcmd))) { /* event for a different vendor, ignore it */ continue; } cb_info *cbi = &(info->event_cb[i]); pthread_mutex_unlock(&info->cb_lock); if (cbi->cb_func) { (*(cbi->cb_func))(msg, cbi->cb_arg); dispatched = true; } return NL_OK; } } #ifdef QC_HAL_DEBUG if (!dispatched) { ALOGI("event ignored!!"); } #endif pthread_mutex_unlock(&info->cb_lock); return NL_OK; }