s32 wilc_parse_network_info(u8 *msg_buffer, struct network_info **ret_network_info) { struct network_info *network_info = NULL; u8 msg_type = 0; u8 msg_id = 0; u16 msg_len = 0; u16 wid_id = (u16)WID_NIL; u16 wid_len = 0; u8 *wid_val = NULL; msg_type = msg_buffer[0]; if ('N' != msg_type) return -EFAULT; msg_id = msg_buffer[1]; msg_len = MAKE_WORD16(msg_buffer[2], msg_buffer[3]); wid_id = MAKE_WORD16(msg_buffer[4], msg_buffer[5]); wid_len = MAKE_WORD16(msg_buffer[6], msg_buffer[7]); wid_val = &msg_buffer[8]; { u8 *msa = NULL; u16 rx_len = 0; u8 *tim_elm = NULL; u8 *ies = NULL; u16 ies_len = 0; u8 index = 0; u32 tsf_lo; u32 tsf_hi; network_info = kzalloc(sizeof(*network_info), GFP_KERNEL); if (!network_info) return -ENOMEM; network_info->rssi = wid_val[0]; msa = &wid_val[1]; rx_len = wid_len - 1; network_info->cap_info = get_cap_info(msa); network_info->tsf_lo = get_beacon_timestamp_lo(msa); tsf_lo = get_beacon_timestamp_lo(msa); tsf_hi = get_beacon_timestamp_hi(msa); network_info->tsf_hi = tsf_lo | ((u64)tsf_hi << 32); get_ssid(msa, network_info->ssid, &network_info->ssid_len); get_BSSID(msa, network_info->bssid); network_info->ch = get_current_channel_802_11n(msa, rx_len + FCS_LEN); index = MAC_HDR_LEN + TIME_STAMP_LEN; network_info->beacon_period = get_beacon_period(msa + index); index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; tim_elm = get_tim_elm(msa, rx_len + FCS_LEN, index); if (tim_elm) network_info->dtim_period = tim_elm[3]; ies = &msa[TAG_PARAM_OFFSET]; ies_len = rx_len - TAG_PARAM_OFFSET; if (ies_len > 0) { network_info->ies = kmemdup(ies, ies_len, GFP_KERNEL); if (!network_info->ies) { kfree(network_info); return -ENOMEM; } } network_info->ies_len = ies_len; } *ret_network_info = network_info; return 0; }
/** * @brief parses the received 'N' message * @details * @param[in] pu8MsgBuffer The message to be parsed * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info * @return Error code indicating success/failure * @note * @author mabubakr * @date 1 Mar 2012 * @version 1.0 */ s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) { tstrNetworkInfo *pstrNetworkInfo = NULL; u8 u8MsgType = 0; u8 u8MsgID = 0; u16 u16MsgLen = 0; u16 u16WidID = (u16)WID_NIL; u16 u16WidLen = 0; u8 *pu8WidVal = NULL; u8MsgType = pu8MsgBuffer[0]; /* Check whether the received message type is 'N' */ if ('N' != u8MsgType) { PRINT_ER("Received Message format incorrect.\n"); return -EFAULT; } /* Extract message ID */ u8MsgID = pu8MsgBuffer[1]; /* Extract message Length */ u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]); /* Extract WID ID */ u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]); /* Extract WID Length */ u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]); /* Assign a pointer to the WID value */ pu8WidVal = &pu8MsgBuffer[8]; /* parse the WID value of the WID "WID_NEWORK_INFO" */ { u8 *pu8msa = NULL; u16 u16RxLen = 0; u8 *pu8TimElm = NULL; u8 *pu8IEs = NULL; u16 u16IEsLen = 0; u8 u8index = 0; u32 u32Tsf_Lo; u32 u32Tsf_Hi; pstrNetworkInfo = kzalloc(sizeof(tstrNetworkInfo), GFP_KERNEL); if (!pstrNetworkInfo) return -ENOMEM; pstrNetworkInfo->s8rssi = pu8WidVal[0]; /* Assign a pointer to msa "Mac Header Start Address" */ pu8msa = &pu8WidVal[1]; u16RxLen = u16WidLen - 1; /* parse msa*/ /* Get the cap_info */ pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa); /* Get time-stamp [Low only 32 bit] */ pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa); PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf); /* Get full time-stamp [Low and High 64 bit] */ u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa); u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa); pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((u64)u32Tsf_Hi << 32); /* Get SSID */ get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &pstrNetworkInfo->u8SsidLen); /* Get BSSID */ get_BSSID(pu8msa, pstrNetworkInfo->au8bssid); /* * Extract current channel information from * the beacon/probe response frame */ pstrNetworkInfo->u8channel = get_current_channel_802_11n(pu8msa, u16RxLen + FCS_LEN); /* Get beacon period */ u8index = MAC_HDR_LEN + TIME_STAMP_LEN; pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index); u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; /* Get DTIM Period */ pu8TimElm = get_tim_elm(pu8msa, u16RxLen + FCS_LEN, u8index); if (pu8TimElm != NULL) pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); if (u16IEsLen > 0) { pstrNetworkInfo->pu8IEs = kmemdup(pu8IEs, u16IEsLen, GFP_KERNEL); if (!pstrNetworkInfo->pu8IEs) return -ENOMEM; } pstrNetworkInfo->u16IEsLen = u16IEsLen; } *ppstrNetworkInfo = pstrNetworkInfo; return 0; }