inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, u8 flags, u16 reason, u16 precedence) { u8 ie_data[6]; ie_data[0] = ttl; ie_data[1] = flags; RTW_PUT_LE16((u8*)&ie_data[2], reason); RTW_PUT_LE16((u8*)&ie_data[4], precedence); return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len); }
inline uint8_t *rtw_set_ie_mesh_ch_switch_parm(uint8_t *buf, uint32_t *buf_len, uint8_t ttl, uint8_t flags, u16 reason, u16 precedence) { uint8_t ie_data[6]; ie_data[0] = ttl; ie_data[1] = flags; RTW_PUT_LE16((uint8_t *)&ie_data[2], reason); RTW_PUT_LE16((uint8_t *)&ie_data[4], precedence); return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len); }
u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr) { u32 a_len; *pbuf = attr_id; //*(u16*)(pbuf + 1) = cpu_to_le16(attr_len); RTW_PUT_LE16(pbuf + 1, attr_len); if(pdata_attr) _rtw_memcpy(pbuf + 3, pdata_attr, attr_len); a_len = attr_len + 3; return a_len; }
u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr ) { u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; u32 len=0, p2pielen = 0; // P2P OUI p2pielen = 0; p2pie[ p2pielen++ ] = 0x50; p2pie[ p2pielen++ ] = 0x6F; p2pie[ p2pielen++ ] = 0x9A; p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 // Commented by Albert 20110301 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes // 1. P2P Capability // 2. Device Info // 3. Group ID ( When joining an operating P2P Group ) // P2P Capability ATTR // Type: p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; // Length: //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); RTW_PUT_LE16(p2pie + p2pielen, 0x0002); p2pielen += 2; // Value: // Device Capability Bitmap, 1 byte // Be able to participate in additional P2P Groups and // support the P2P Invitation Procedure p2pie[ p2pielen++ ] = P2P_DEVCAP_INVITATION_PROC; // Group Capability Bitmap, 1 byte p2pie[ p2pielen++ ] = 0x00; // Device Info ATTR // Type: p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO; // Length: // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); p2pielen += 2; // Value: // P2P Device Address _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); p2pielen += ETH_ALEN; // Config Method // This field should be big endian. Noted by P2P specification. if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC ) { //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC ); RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC); } else { //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY ); RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY); } p2pielen += 2; // Primary Device Type // Category ID //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI ); RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_RTK_WIDI); p2pielen += 2; // OUI //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); p2pielen += 4; // Sub Category ID //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP ); RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_RTK_DMP); p2pielen += 2; // Number of Secondary Device Types p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List // Device Name // Type: //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); p2pielen += 2; // Length: //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); p2pielen += 2; // Value: _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len ); p2pielen += pwdinfo->device_name_len; if ( pwdinfo->role == P2P_ROLE_CLIENT ) { // Added by Albert 2011/05/19 // In this case, the pdev_raddr is the device address of the group owner. // P2P Group ID ATTR // Type: p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID; // Length: //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + ussidlen ); RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen); p2pielen += 2; // Value: _rtw_memcpy( p2pie + p2pielen, pdev_raddr, ETH_ALEN ); p2pielen += ETH_ALEN; _rtw_memcpy( p2pie + p2pielen, pssid, ussidlen ); p2pielen += ussidlen; } pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); return len; }
u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) { u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; u32 len=0, p2pielen = 0; // P2P OUI p2pielen = 0; p2pie[ p2pielen++ ] = 0x50; p2pie[ p2pielen++ ] = 0x6F; p2pie[ p2pielen++ ] = 0x9A; p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 // Commented by Albert 20100907 // According to the P2P Specification, the probe response frame should contain 5 P2P attributes // 1. P2P Capability // 2. Extended Listen Timing // 3. Notice of Absence ( NOA ) ( Only GO needs this ) // 4. Device Info // 5. Group Info ( Only GO need this ) // P2P Capability ATTR // Type: p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; // Length: //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); RTW_PUT_LE16(p2pie + p2pielen, 0x0002); p2pielen += 2; // Value: // Device Capability Bitmap, 1 byte // Be able to participate in additional P2P Groups and // support the P2P Invitation Procedure p2pie[ p2pielen++ ] = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY; // Group Capability Bitmap, 1 byte if(pwdinfo->role == P2P_ROLE_GO) { p2pie[ p2pielen ] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS); if(pwdinfo->p2p_state == P2P_STATE_PROVISIONING_ING) p2pie[ p2pielen ] |= P2P_GRPCAP_GROUP_FORMATION; p2pielen++; } else if ( pwdinfo->role == P2P_ROLE_DEVICE ) { // Group Capability Bitmap, 1 byte p2pie[ p2pielen++ ] = 0x00; } // Extended Listen Timing ATTR // Type: p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; // Length: //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); RTW_PUT_LE16(p2pie + p2pielen, 0x0004); p2pielen += 2; // Value: // Availability Period //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); p2pielen += 2; // Availability Interval //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); p2pielen += 2; // Notice of Absence ATTR // Type: // Length: // Value: if(pwdinfo->role == P2P_ROLE_GO) { //go_add_noa_attr(pwdinfo); } // Device Info ATTR // Type: p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO; // Length: // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); p2pielen += 2; // Value: // P2P Device Address _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); p2pielen += ETH_ALEN; // Config Method // This field should be big endian. Noted by P2P specification. //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm ); RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm); p2pielen += 2; // Primary Device Type // Category ID //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI ); RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_RTK_WIDI); p2pielen += 2; // OUI //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); p2pielen += 4; // Sub Category ID //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP ); RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_RTK_DMP); p2pielen += 2; // Number of Secondary Device Types p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List // Device Name // Type: //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); p2pielen += 2; // Length: //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); p2pielen += 2; // Value: _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len ); p2pielen += pwdinfo->device_name_len; // Group Info ATTR // Type: // Length: // Value: if(pwdinfo->role == P2P_ROLE_GO) { p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen); } pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); return len; }