static wifi_error wifi_init_user_sock(hal_info *info) { struct nl_sock *user_sock = wifi_create_nl_socket(WIFI_HAL_USER_SOCK_PORT, NETLINK_USERSOCK); if (user_sock == NULL) { ALOGE("Could not create diag sock"); return WIFI_ERROR_UNKNOWN; } /* Set the socket buffer size */ if (nl_socket_set_buffer_size(user_sock, (256*1024), 0) < 0) { ALOGE("Could not set size for user_sock: %s", strerror(errno)); /* continue anyway with the default (smaller) buffer */ } else { ALOGV("nl_socket_set_buffer_size successful for user_sock"); } struct nl_cb *cb = nl_socket_get_cb(user_sock); if (cb == NULL) { ALOGE("Could not get cb"); return WIFI_ERROR_UNKNOWN; } info->user_sock_arg = 1; nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->user_sock_arg); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->user_sock_arg); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->user_sock_arg); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, user_sock_message_handler, info); nl_cb_put(cb); int ret = nl_socket_add_membership(user_sock, 1); if (ret < 0) { ALOGE("Could not add membership"); return WIFI_ERROR_UNKNOWN; } info->user_sock = user_sock; ALOGV("Initiialized diag sock successfully"); return WIFI_SUCCESS; }
wifi_error wifi_initialize(wifi_handle *handle) { int err = 0; srand(getpid()); ALOGI("Initializing wifi"); hal_info *info = (hal_info *)malloc(sizeof(hal_info)); if (info == NULL) { ALOGE("Could not allocate hal_info"); return WIFI_ERROR_UNKNOWN; } memset(info, 0, sizeof(*info)); ALOGI("Creating socket"); struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT); if (cmd_sock == NULL) { ALOGE("Could not create handle"); return WIFI_ERROR_UNKNOWN; } struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT); if (event_sock == NULL) { ALOGE("Could not create handle"); nl_socket_free(cmd_sock); return WIFI_ERROR_UNKNOWN; } struct nl_cb *cb = nl_socket_get_cb(event_sock); if (cb == NULL) { ALOGE("Could not create handle"); return WIFI_ERROR_UNKNOWN; } err = 1; nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info); nl_cb_put(cb); info->cmd_sock = cmd_sock; info->event_sock = event_sock; info->clean_up = false; info->in_event_loop = false; info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE); info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE; info->num_event_cb = 0; info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE); info->alloc_cmd = DEFAULT_CMD_SIZE; info->num_cmd = 0; info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211"); if (info->nl80211_family_id < 0) { ALOGE("Could not resolve nl80211 familty id"); nl_socket_free(cmd_sock); nl_socket_free(event_sock); free(info); return WIFI_ERROR_UNKNOWN; } ALOGI("%s: family_id:%d", __func__, info->nl80211_family_id); *handle = (wifi_handle) info; wifi_add_membership(*handle, "scan"); wifi_add_membership(*handle, "mlme"); wifi_add_membership(*handle, "regulatory"); wifi_add_membership(*handle, "vendor"); wifi_init_interfaces(*handle); // ALOGI("Found %d interfaces", info->num_interfaces); ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d handle %p", NL80211_CMD_VENDOR , *handle); return WIFI_SUCCESS; }
wifi_error wifi_initialize(wifi_handle *handle) { int err = 0; wifi_error ret = WIFI_SUCCESS; wifi_interface_handle iface_handle; struct nl_sock *cmd_sock = NULL; struct nl_sock *event_sock = NULL; struct nl_cb *cb = NULL; int status = 0; ALOGI("Initializing wifi"); hal_info *info = (hal_info *)malloc(sizeof(hal_info)); if (info == NULL) { ALOGE("Could not allocate hal_info"); return WIFI_ERROR_OUT_OF_MEMORY; } memset(info, 0, sizeof(*info)); cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT, NETLINK_GENERIC); if (cmd_sock == NULL) { ALOGE("Failed to create command socket port"); ret = WIFI_ERROR_UNKNOWN; goto unload; } /* Set the socket buffer size */ if (nl_socket_set_buffer_size(cmd_sock, (256*1024), 0) < 0) { ALOGE("Could not set nl_socket RX buffer size for cmd_sock: %s", strerror(errno)); /* continue anyway with the default (smaller) buffer */ } event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT, NETLINK_GENERIC); if (event_sock == NULL) { ALOGE("Failed to create event socket port"); ret = WIFI_ERROR_UNKNOWN; goto unload; } /* Set the socket buffer size */ if (nl_socket_set_buffer_size(event_sock, (256*1024), 0) < 0) { ALOGE("Could not set nl_socket RX buffer size for event_sock: %s", strerror(errno)); /* continue anyway with the default (smaller) buffer */ } cb = nl_socket_get_cb(event_sock); if (cb == NULL) { ALOGE("Failed to get NL control block for event socket port"); ret = WIFI_ERROR_UNKNOWN; goto unload; } err = 1; nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info); nl_cb_put(cb); info->cmd_sock = cmd_sock; info->event_sock = event_sock; info->clean_up = false; info->in_event_loop = false; info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE); if (info->event_cb == NULL) { ALOGE("Could not allocate event_cb"); ret = WIFI_ERROR_OUT_OF_MEMORY; goto unload; } info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE; info->num_event_cb = 0; info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE); if (info->cmd == NULL) { ALOGE("Could not allocate cmd info"); ret = WIFI_ERROR_OUT_OF_MEMORY; goto unload; } info->alloc_cmd = DEFAULT_CMD_SIZE; info->num_cmd = 0; info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211"); if (info->nl80211_family_id < 0) { ALOGE("Could not resolve nl80211 familty id"); ret = WIFI_ERROR_UNKNOWN; goto unload; } pthread_mutex_init(&info->cb_lock, NULL); pthread_mutex_init(&info->pkt_fate_stats_lock, NULL); *handle = (wifi_handle) info; wifi_add_membership(*handle, "scan"); wifi_add_membership(*handle, "mlme"); wifi_add_membership(*handle, "regulatory"); wifi_add_membership(*handle, "vendor"); info->cldctx = cld80211_init(); if (info->cldctx != NULL) { info->user_sock = info->cldctx->sock; ret = wifi_init_cld80211_sock_cb(info); if (ret != WIFI_SUCCESS) { ALOGE("Could not set cb for CLD80211 family"); goto cld80211_cleanup; } status = cld80211_add_mcast_group(info->cldctx, "host_logs"); if (status) { ALOGE("Failed to add mcast group host_logs :%d", status); goto cld80211_cleanup; } status = cld80211_add_mcast_group(info->cldctx, "fw_logs"); if (status) { ALOGE("Failed to add mcast group fw_logs :%d", status); goto cld80211_cleanup; } status = cld80211_add_mcast_group(info->cldctx, "per_pkt_stats"); if (status) { ALOGE("Failed to add mcast group per_pkt_stats :%d", status); goto cld80211_cleanup; } status = cld80211_add_mcast_group(info->cldctx, "diag_events"); if (status) { ALOGE("Failed to add mcast group diag_events :%d", status); goto cld80211_cleanup; } status = cld80211_add_mcast_group(info->cldctx, "fatal_events"); if (status) { ALOGE("Failed to add mcast group fatal_events :%d", status); goto cld80211_cleanup; } } else { ret = wifi_init_user_sock(info); if (ret != WIFI_SUCCESS) { ALOGE("Failed to alloc user socket"); goto unload; } } ret = wifi_init_interfaces(*handle); if (ret != WIFI_SUCCESS) { ALOGE("Failed to init interfaces"); goto unload; } if (info->num_interfaces == 0) { ALOGE("No interfaces found"); ret = WIFI_ERROR_UNINITIALIZED; goto unload; } iface_handle = wifi_get_iface_handle((info->interfaces[0])->handle, (info->interfaces[0])->name); if (iface_handle == NULL) { int i; for (i = 0; i < info->num_interfaces; i++) { free(info->interfaces[i]); } ALOGE("%s no iface with %s\n", __func__, info->interfaces[0]->name); goto unload; } ret = acquire_supported_features(iface_handle, &info->supported_feature_set); if (ret != WIFI_SUCCESS) { ALOGI("Failed to get supported feature set : %d", ret); //acquire_supported_features failure is acceptable condition as legacy //drivers might not support the required vendor command. So, do not //consider it as failure of wifi_initialize ret = WIFI_SUCCESS; } ret = get_firmware_bus_max_size_supported(iface_handle); if (ret != WIFI_SUCCESS) { ALOGE("Failed to get supported bus size, error : %d", ret); info->firmware_bus_max_size = 1520; } ret = wifi_logger_ring_buffers_init(info); if (ret != WIFI_SUCCESS) { ALOGE("Wifi Logger Ring Initialization Failed"); goto unload; } ret = wifi_get_capabilities(iface_handle); if (ret != WIFI_SUCCESS) ALOGE("Failed to get wifi Capabilities, error: %d", ret); info->pkt_stats = (struct pkt_stats_s *)malloc(sizeof(struct pkt_stats_s)); if (!info->pkt_stats) { ALOGE("%s: malloc Failed for size: %zu", __FUNCTION__, sizeof(struct pkt_stats_s)); ret = WIFI_ERROR_OUT_OF_MEMORY; goto unload; } info->rx_buf_size_allocated = MAX_RXMPDUS_PER_AMPDU * MAX_MSDUS_PER_MPDU * PKT_STATS_BUF_SIZE; info->rx_aggr_pkts = (wifi_ring_buffer_entry *)malloc(info->rx_buf_size_allocated); if (!info->rx_aggr_pkts) { ALOGE("%s: malloc Failed for size: %d", __FUNCTION__, info->rx_buf_size_allocated); ret = WIFI_ERROR_OUT_OF_MEMORY; info->rx_buf_size_allocated = 0; goto unload; } memset(info->rx_aggr_pkts, 0, info->rx_buf_size_allocated); info->exit_sockets[0] = -1; info->exit_sockets[1] = -1; if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->exit_sockets) == -1) { ALOGE("Failed to create exit socket pair"); ret = WIFI_ERROR_UNKNOWN; goto unload; } ALOGV("Initializing Gscan Event Handlers"); ret = initializeGscanHandlers(info); if (ret != WIFI_SUCCESS) { ALOGE("Initializing Gscan Event Handlers Failed"); goto unload; } ret = initializeRSSIMonitorHandler(info); if (ret != WIFI_SUCCESS) { ALOGE("Initializing RSSI Event Handler Failed"); goto unload; } ALOGV("Initialized Wifi HAL Successfully; vendor cmd = %d Supported" " features : %x", NL80211_CMD_VENDOR, info->supported_feature_set); cld80211_cleanup: if (status != 0 || ret != WIFI_SUCCESS) { ret = WIFI_ERROR_UNKNOWN; cld80211lib_cleanup(info); } unload: if (ret != WIFI_SUCCESS) { if (cmd_sock) nl_socket_free(cmd_sock); if (event_sock) nl_socket_free(event_sock); if (info) { if (info->cmd) free(info->cmd); if (info->event_cb) free(info->event_cb); if (info->cldctx) { cld80211lib_cleanup(info); } else if (info->user_sock) { nl_socket_free(info->user_sock); } if (info->pkt_stats) free(info->pkt_stats); if (info->rx_aggr_pkts) free(info->rx_aggr_pkts); cleanupGscanHandlers(info); cleanupRSSIMonitorHandler(info); free(info); } } return ret; }
wifi_error wifi_initialize(wifi_handle *handle) { int err = 0; bool driver_loaded = false; wifi_error ret = WIFI_SUCCESS; wifi_interface_handle iface_handle; srand(getpid()); ALOGI("Initializing wifi"); hal_info *info = (hal_info *)malloc(sizeof(hal_info)); if (info == NULL) { ALOGE("Could not allocate hal_info"); return WIFI_ERROR_UNKNOWN; } memset(info, 0, sizeof(*info)); ALOGI("Creating socket"); struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT); if (cmd_sock == NULL) { ALOGE("Could not create handle"); return WIFI_ERROR_UNKNOWN; } struct nl_sock *event_sock = wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT); if (event_sock == NULL) { ALOGE("Could not create handle"); nl_socket_free(cmd_sock); return WIFI_ERROR_UNKNOWN; } struct nl_cb *cb = nl_socket_get_cb(event_sock); if (cb == NULL) { ALOGE("Could not create handle"); return WIFI_ERROR_UNKNOWN; } err = 1; nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, info); nl_cb_put(cb); info->cmd_sock = cmd_sock; info->event_sock = event_sock; info->clean_up = false; info->in_event_loop = false; info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE); info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE; info->num_event_cb = 0; info->cmd = (cmd_info *)malloc(sizeof(cmd_info) * DEFAULT_CMD_SIZE); info->alloc_cmd = DEFAULT_CMD_SIZE; info->num_cmd = 0; info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211"); if (info->nl80211_family_id < 0) { ALOGE("Could not resolve nl80211 familty id"); nl_socket_free(cmd_sock); nl_socket_free(event_sock); free(info); return WIFI_ERROR_UNKNOWN; } ALOGI("%s: family_id:%d", __func__, info->nl80211_family_id); *handle = (wifi_handle) info; wifi_add_membership(*handle, "scan"); wifi_add_membership(*handle, "mlme"); wifi_add_membership(*handle, "regulatory"); wifi_add_membership(*handle, "vendor"); if (!is_wifi_driver_loaded()) { ret = (wifi_error)wifi_load_driver(); if(ret != WIFI_SUCCESS) { ALOGE("%s Failed to load driver : %d\n", __func__, ret); return WIFI_ERROR_UNKNOWN; } driver_loaded = true; } ret = wifi_init_interfaces(*handle); if (ret != WIFI_SUCCESS) { ALOGI("Failed to init interfaces"); goto unload; } if (info->num_interfaces == 0) { ALOGI("No interfaces found"); ret = WIFI_ERROR_UNINITIALIZED; goto unload; } iface_handle = wifi_get_iface_handle((info->interfaces[0])->handle, (info->interfaces[0])->name); if (iface_handle == NULL) { int i; for (i = 0; i < info->num_interfaces; i++) { free(info->interfaces[i]); } ALOGE("%s no iface with %s\n", __func__, info->interfaces[0]->name); return WIFI_ERROR_UNKNOWN; } ret = acquire_supported_features(iface_handle, &info->supported_feature_set); if (ret != WIFI_SUCCESS) { ALOGI("Failed to get supported feature set : %d", ret); //acquire_supported_features failure is acceptable condition as legacy //drivers might not support the required vendor command. So, do not //consider it as failure of wifi_initialize ret = WIFI_SUCCESS; } ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d Supported" " features : %x", NL80211_CMD_VENDOR, info->supported_feature_set); unload: if (driver_loaded) wifi_unload_driver(); return ret; }