1718 lines
41 KiB
C
1718 lines
41 KiB
C
#include <wireless.h>
|
|
#include <wlan_intf.h>
|
|
#include "FreeRTOS.h"
|
|
#include <platform/platform_stdlib.h>
|
|
#include <wifi/wifi_conf.h>
|
|
#include <wifi/wifi_ind.h>
|
|
#include <osdep_service.h>
|
|
|
|
int iw_ioctl(const char * ifname, unsigned long request, struct iwreq * pwrq)
|
|
{
|
|
memcpy(pwrq->ifr_name, ifname, 5);
|
|
return rltk_wlan_control(request, (void *) pwrq);
|
|
}
|
|
|
|
int wext_get_ssid(const char *ifname, __u8 *ssid)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.essid.pointer = ssid;
|
|
iwr.u.essid.length = 32;
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWESSID, &iwr) < 0) {
|
|
#if defined(CONFIG_EXAMPLE_BT_CONFIG) && (CONFIG_EXAMPLE_BT_CONFIG!=1)
|
|
printf("\n\rioctl[SIOCGIWESSID] ssid = NULL, not connected"); //do not use perror
|
|
#endif
|
|
ret = -1;
|
|
} else {
|
|
ret = iwr.u.essid.length;
|
|
if (ret > 32)
|
|
ret = 32;
|
|
/* Some drivers include nul termination in the SSID, so let's
|
|
* remove it here before further processing. WE-21 changes this
|
|
* to explicitly require the length _not_ to include nul
|
|
* termination. */
|
|
if (ret > 0 && ssid[ret - 1] == '\0')
|
|
ret--;
|
|
ssid[ret] = '\0';
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.essid.pointer = (void *) ssid;
|
|
iwr.u.essid.length = ssid_len;
|
|
iwr.u.essid.flags = (ssid_len != 0);
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWESSID, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWESSID] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_bssid(const char *ifname, const __u8 *bssid)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
|
|
memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN);
|
|
|
|
if(bssid[ETH_ALEN]=='#' && bssid[ETH_ALEN + 1]=='@'){
|
|
memcpy(iwr.u.ap_addr.sa_data + ETH_ALEN, bssid + ETH_ALEN, 6);
|
|
}
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWAP, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWAP] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_bssid(const char*ifname, __u8 *bssid)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWAP, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWAP] error");
|
|
ret = -1;
|
|
} else {
|
|
memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int is_broadcast_ether_addr(const unsigned char *addr)
|
|
{
|
|
return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
|
|
}
|
|
|
|
int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.param.flags = idx & IW_AUTH_INDEX;
|
|
iwr.u.param.value = value;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWAUTH, &iwr) < 0) {
|
|
printf("\n\rWEXT: SIOCSIWAUTH(param %d value 0x%x) failed)", idx, value);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_mfp_support(const char *ifname, __u8 value)
|
|
{
|
|
int ret = 0;
|
|
struct iwreq iwr;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.param.value = value;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWMFP, &iwr) < 0) {
|
|
RTW_API_INFO(("\n\rWEXT: SIOCSIWMFP(value 0x%x) failed)", value));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#ifdef CONFIG_SAE_SUPPORT
|
|
int wext_set_group_id(const char *ifname, __u8 value)
|
|
{
|
|
int ret = 0;
|
|
struct iwreq iwr;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.param.value = value;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWGRPID, &iwr) < 0) {
|
|
RTW_API_INFO(("\n\rWEXT: SIOCSIWGRPID(value 0x%x) failed)", value));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
extern u8 rtw_cmd_tsk_spt_wap3;
|
|
|
|
int wext_set_support_wpa3(__u8 enable)
|
|
{
|
|
rtw_cmd_tsk_spt_wap3 = enable;
|
|
return 0;
|
|
}
|
|
|
|
__u8 wext_get_support_wpa3(void)
|
|
{
|
|
return rtw_cmd_tsk_spt_wap3;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_PMKSA_CACHING
|
|
int wext_set_pmk_cache_enable(const char *ifname, __u8 value)
|
|
{
|
|
int ret = 0;
|
|
struct iwreq iwr;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.param.value = value;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWPMKSA, &iwr) < 0) {
|
|
RTW_API_INFO(("\n\rWEXT: SIOCSIWPMKSA(value 0x%x) failed)", value));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
struct iw_encode_ext *ext;
|
|
|
|
ext = (struct iw_encode_ext *) malloc(sizeof(struct iw_encode_ext) + key_len);
|
|
if (ext == NULL)
|
|
return -1;
|
|
else
|
|
memset(ext, 0, sizeof(struct iw_encode_ext) + key_len);
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.encoding.flags = key_idx + 1;
|
|
iwr.u.encoding.flags |= IW_ENCODE_TEMP;
|
|
iwr.u.encoding.pointer = ext;
|
|
iwr.u.encoding.length = sizeof(struct iw_encode_ext) + key_len;
|
|
|
|
if (alg == IW_ENCODE_DISABLED)
|
|
iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
|
|
|
|
if (addr == NULL || is_broadcast_ether_addr(addr))
|
|
ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
|
|
|
|
if (set_tx)
|
|
ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;
|
|
|
|
ext->addr.sa_family = ARPHRD_ETHER;
|
|
|
|
if (addr)
|
|
memcpy(ext->addr.sa_data, addr, ETH_ALEN);
|
|
else
|
|
memset(ext->addr.sa_data, 0xff, ETH_ALEN);
|
|
|
|
if (key && key_len) {
|
|
memcpy(ext->key, key, key_len);
|
|
ext->key_len = key_len;
|
|
}
|
|
|
|
ext->alg = alg;
|
|
|
|
if (seq && seq_len) {
|
|
ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;
|
|
memcpy(ext->rx_seq, seq, seq_len);
|
|
}
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWENCODEEXT, &iwr) < 0) {
|
|
ret = -2;
|
|
printf("\n\rioctl[SIOCSIWENCODEEXT] set key fail");
|
|
}
|
|
|
|
free(ext);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_enc_ext(const char *ifname, __u16 *alg, __u8 *key_idx, __u8 *passphrase)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
struct iw_encode_ext *ext;
|
|
|
|
ext = (struct iw_encode_ext *) malloc(sizeof(struct iw_encode_ext) + 16);
|
|
if (ext == NULL)
|
|
return -1;
|
|
else
|
|
memset(ext, 0, sizeof(struct iw_encode_ext) + 16);
|
|
|
|
iwr.u.encoding.pointer = ext;
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWENCODEEXT, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWENCODEEXT] error");
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
*alg = ext->alg;
|
|
if(key_idx)
|
|
*key_idx = (__u8)iwr.u.encoding.flags;
|
|
if(passphrase)
|
|
memcpy(passphrase, ext->key, ext->key_len);
|
|
}
|
|
|
|
if(ext != NULL)
|
|
free(ext);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_auth_type(const char *ifname, __u32 *auth_type)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWAUTH, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWAUTH] error");
|
|
ret = -1;
|
|
}else{
|
|
*auth_type = (__u32) iwr.u.param.value;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.passphrase.pointer = (void *) passphrase;
|
|
iwr.u.passphrase.length = passphrase_len;
|
|
iwr.u.passphrase.flags = (passphrase_len != 0);
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWPRIVPASSPHRASE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWESSID+0x1f] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_passphrase(const char *ifname, __u8 *passphrase)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.passphrase.pointer = (void *) passphrase;
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWPRIVPASSPHRASE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWPRIVPASSPHRASE] error");
|
|
ret = -1;
|
|
}
|
|
else {
|
|
ret = iwr.u.passphrase.length;
|
|
passphrase[ret] = '\0';
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
int wext_set_mac_address(const char *ifname, char * mac)
|
|
{
|
|
char buf[13+17+1];
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
snprintf(buf, 13+17, "write_mac %s", mac);
|
|
return wext_private_command(ifname, buf, 0);
|
|
}
|
|
|
|
int wext_get_mac_address(const char *ifname, char * mac)
|
|
{
|
|
int ret = 0;
|
|
char buf[32];
|
|
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
rtw_memcpy(buf, "read_mac", 8);
|
|
ret = wext_private_command_with_retval(ifname, buf, buf, 32);
|
|
strcpy(mac, buf);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int wext_enable_powersave(const char *ifname, __u8 ips_mode, __u8 lps_mode)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u16 pindex = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("pm_set");
|
|
|
|
// Encode parameters as TLV (type, length, value) format
|
|
para = pvPortMalloc( 7 + (1+1+1) + (1+1+1) );
|
|
if(para == NULL) return -1;
|
|
|
|
snprintf((char*)para, cmd_len, "pm_set");
|
|
pindex = 7;
|
|
|
|
para[pindex++] = 0; // type 0 for ips
|
|
para[pindex++] = 1;
|
|
para[pindex++] = ips_mode;
|
|
|
|
para[pindex++] = 1; // type 1 for lps
|
|
para[pindex++] = 1;
|
|
para[pindex++] = lps_mode;
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = pindex;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVAPESSID] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_disable_powersave(const char *ifname)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u16 pindex = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("pm_set");
|
|
|
|
// Encode parameters as TLV (type, length, value) format
|
|
para = pvPortMalloc( 7 + (1+1+1) + (1+1+1) );
|
|
if(para == NULL) return -1;
|
|
|
|
snprintf((char*)para, cmd_len, "pm_set");
|
|
pindex = 7;
|
|
|
|
para[pindex++] = 0; // type 0 for ips
|
|
para[pindex++] = 1;
|
|
para[pindex++] = 0; // ips = 0
|
|
|
|
para[pindex++] = 1; // type 1 for lps
|
|
para[pindex++] = 1;
|
|
para[pindex++] = 0; // lps = 0
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = pindex;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVAPESSID] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
|
|
}
|
|
|
|
int wext_set_tdma_param(const char *ifname, __u8 slot_period, __u8 rfon_period_len_1, __u8 rfon_period_len_2, __u8 rfon_period_len_3)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u16 pindex = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("pm_set");
|
|
|
|
// Encode parameters as TLV (type, length, value) format
|
|
para = pvPortMalloc( 7 + (1+1+4) );
|
|
|
|
snprintf((char*)para, cmd_len, "pm_set");
|
|
pindex = 7;
|
|
|
|
para[pindex++] = 2; // type 2 tdma param
|
|
para[pindex++] = 4;
|
|
para[pindex++] = slot_period;
|
|
para[pindex++] = rfon_period_len_1;
|
|
para[pindex++] = rfon_period_len_2;
|
|
para[pindex++] = rfon_period_len_3;
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = pindex;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVAPESSID] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_lps_dtim(const char *ifname, __u8 lps_dtim)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u16 pindex = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("pm_set");
|
|
|
|
// Encode parameters as TLV (type, length, value) format
|
|
para = pvPortMalloc( 7 + (1+1+1) );
|
|
|
|
snprintf((char*)para, cmd_len, "pm_set");
|
|
pindex = 7;
|
|
|
|
para[pindex++] = 3; // type 3 lps dtim
|
|
para[pindex++] = 1;
|
|
para[pindex++] = lps_dtim;
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = pindex;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVAPESSID] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_lps_dtim(const char *ifname, __u8 *lps_dtim)
|
|
{
|
|
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u16 pindex = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("pm_get");
|
|
|
|
// Encode parameters as TLV (type, length, value) format
|
|
para = pvPortMalloc( 7 + (1+1+1) );
|
|
|
|
snprintf((char*)para, cmd_len, "pm_get");
|
|
pindex = 7;
|
|
|
|
para[pindex++] = 3; // type 3 for lps dtim
|
|
para[pindex++] = 1;
|
|
para[pindex++] = 0;
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = pindex;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVAPESSID] error");
|
|
ret = -1;
|
|
goto exit;
|
|
}
|
|
|
|
//get result at the beginning of iwr.u.data.pointer
|
|
if((para[0]==3)&&(para[1]==1))
|
|
*lps_dtim = para[2];
|
|
else
|
|
printf("\n\r%s error", __func__);
|
|
|
|
exit:
|
|
vPortFree(para);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_tos_value(const char *ifname, __u8 *tos_value)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = sizeof("set_tos_value");
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
para = pvPortMalloc(cmd_len + 4);
|
|
snprintf((char*)para, cmd_len, "set_tos_value");
|
|
|
|
if(*tos_value >= 0 && *tos_value <=32){
|
|
*(para + cmd_len) = 0x4f;
|
|
*(para + cmd_len+1) = 0xa4;
|
|
*(para + cmd_len+2) = 0;
|
|
*(para + cmd_len+3) = 0;
|
|
}
|
|
else if(*tos_value > 32 && *tos_value <=96){
|
|
*(para + cmd_len) = 0x2b;
|
|
*(para + cmd_len+1) = 0xa4;
|
|
*(para + cmd_len+2) = 0;
|
|
*(para + cmd_len+3) = 0;
|
|
}
|
|
else if(*tos_value > 96 && *tos_value <= 160){
|
|
*(para + cmd_len) = 0x22;
|
|
*(para + cmd_len+1) = 0x43;
|
|
*(para + cmd_len+2) = 0x5e;
|
|
*(para + cmd_len+3) = 0;
|
|
}
|
|
else if(*tos_value > 160){
|
|
*(para + cmd_len) = 0x22;
|
|
*(para + cmd_len+1) = 0x32;
|
|
*(para + cmd_len+2) = 0x2f;
|
|
*(para + cmd_len+3) = 0;
|
|
}
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = cmd_len + 4;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_set_tos_value():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_tx_power(const char *ifname, __u8 *poweridx)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = sizeof("get_tx_power");
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
//Tx power size : 20 Bytes
|
|
//CCK 1M,2M,5.5M,11M : 4 Bytes
|
|
//OFDM 6M, 9M, 12M, 18M, 24M, 36M 48M, 54M : 8 Bytes
|
|
//MCS 0~7 : 8 Bytes
|
|
para = pvPortMalloc(cmd_len + 20);
|
|
snprintf((char*)para, cmd_len, "get_tx_power");
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = cmd_len + 20;
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_get_tx_power():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
|
|
memcpy(poweridx,(__u8 *)(iwr.u.data.pointer),20);
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
int wext_set_txpower(const char *ifname, int poweridx)
|
|
{
|
|
int ret = 0;
|
|
char buf[24];
|
|
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
snprintf(buf, 24, "txpower patha=%d", poweridx);
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_associated_client_list(const char *ifname, void * client_list_buffer, uint16_t buffer_length)
|
|
{
|
|
int ret = 0;
|
|
char buf[25];
|
|
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
snprintf(buf, 25, "get_client_list %x", client_list_buffer);
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_ap_info(const char *ifname, rtw_bss_info_t * ap_info, rtw_security_t* security)
|
|
{
|
|
int ret = 0;
|
|
char buf[24];
|
|
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
snprintf(buf, 24, "get_ap_info %x", ap_info);
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
snprintf(buf, 24, "get_security");
|
|
ret = wext_private_command_with_retval(ifname, buf, buf, 24);
|
|
sscanf(buf, "%d", security);
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int wext_set_mode(const char *ifname, int mode)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.mode = mode;
|
|
if (iw_ioctl(ifname, SIOCSIWMODE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWMODE] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_mode(const char *ifname, int *mode)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWMODE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWMODE] error");
|
|
ret = -1;
|
|
}
|
|
else
|
|
*mode = iwr.u.mode;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
if(ssid_len > 32){
|
|
printf("Error: SSID should be 0-32 characters\r\n");
|
|
return RTW_BADARG;
|
|
}
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.essid.pointer = (void *) ssid;
|
|
iwr.u.essid.length = ssid_len;
|
|
iwr.u.essid.flags = (ssid_len != 0);
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWPRIVAPESSID, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVAPESSID] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_country(const char *ifname, rtw_country_code_t country_code)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
iwr.u.param.value = country_code;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWPRIVCOUNTRY, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWPRIVCOUNTRY] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_rssi(const char *ifname, int *rssi)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWSENS, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWSENS] error");
|
|
ret = -1;
|
|
} else {
|
|
*rssi = 0 - iwr.u.sens.value;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_bcn_rssi(const char *ifname, int *rssi)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWBCNSENS, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWBCNSENS] error");
|
|
ret = -1;
|
|
} else {
|
|
*rssi = 0 - iwr.u.bcnsens.value;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_snr(const char *ifname, int *snr)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWSNR, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWSNR] error");
|
|
ret = -1;
|
|
} else {
|
|
*snr = iwr.u.snr.value;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_pscan_channel(const char *ifname, __u8 *ch, __u8 *pscan_config, __u8 length)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int i =0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
//Format of para:function_name num_channel chan1... pscan_config1 ...
|
|
para = pvPortMalloc((length + length + 1) + 12);//size:num_chan + num_time + length + function_name
|
|
if(para == NULL) return -1;
|
|
|
|
//Cmd
|
|
snprintf((char*)para, 12, "PartialScan");
|
|
//length
|
|
*(para+12) = length;
|
|
for(i = 0; i < length; i++){
|
|
*(para + 13 + i)= *(ch + i);
|
|
*(para + 13 + length + i)= *(pscan_config + i);
|
|
}
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = (length + length + 1) + 12;
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_set_pscan_channel():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
int wext_set_channel(const char *ifname, __u8 ch)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.freq.m = 0;
|
|
iwr.u.freq.e = 0;
|
|
iwr.u.freq.i = ch;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWFREQ, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWFREQ] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_channel(const char *ifname, __u8 *ch)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
if (iw_ioctl(ifname, SIOCGIWFREQ, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWFREQ] error");
|
|
ret = -1;
|
|
}
|
|
else
|
|
*ch = iwr.u.freq.i;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_register_multicast_address(const char *ifname, rtw_mac_t *mac)
|
|
{
|
|
int ret = 0;
|
|
char buf[32];
|
|
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
snprintf(buf, 32, "reg_multicast "MAC_FMT, MAC_ARG(mac->octet));
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_unregister_multicast_address(const char *ifname, rtw_mac_t *mac)
|
|
{
|
|
int ret = 0;
|
|
char buf[35];
|
|
|
|
rtw_memset(buf, 0, sizeof(buf));
|
|
snprintf(buf, 35, "reg_multicast -d "MAC_FMT, MAC_ARG(mac->octet));
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_scan(const char *ifname, char *buf, __u16 buf_len, __u16 flags)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
#if 0 //for scan_with_ssid
|
|
if(buf)
|
|
memset(buf, 0, buf_len);
|
|
#endif
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.flags = flags;
|
|
iwr.u.data.length = buf_len;
|
|
if (iw_ioctl(ifname, SIOCSIWSCAN, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWSCAN] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_scan(const char *ifname, char *buf, __u16 buf_len)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.length = buf_len;
|
|
if (iw_ioctl(ifname, SIOCGIWSCAN, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCGIWSCAN] error");
|
|
ret = -1;
|
|
}else
|
|
ret = iwr.u.data.flags;
|
|
return ret;
|
|
}
|
|
|
|
int wext_private_command_with_retval(const char *ifname, char *cmd, char *ret_buf, int ret_len)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0, buf_size;
|
|
char *buf;
|
|
|
|
buf_size = 128;
|
|
if(strlen(cmd) >= buf_size)
|
|
buf_size = strlen(cmd) + 1; // 1 : '\0'
|
|
buf = (char*)pvPortMalloc(buf_size);
|
|
if(!buf){
|
|
printf("\n\rWEXT: Can't malloc memory");
|
|
return -1;
|
|
}
|
|
memset(buf, 0, buf_size);
|
|
strcpy(buf, cmd);
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.length = buf_size;
|
|
iwr.u.data.flags = 0;
|
|
|
|
if ((ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr)) < 0) {
|
|
printf("\n\rioctl[SIOCDEVPRIVATE] error. ret=%d\n", ret);
|
|
}
|
|
if(ret_buf){
|
|
if(ret_len > iwr.u.data.length)
|
|
ret_len = iwr.u.data.length;
|
|
rtw_memcpy(ret_buf, (char *) iwr.u.data.pointer, ret_len);
|
|
}
|
|
vPortFree(buf);
|
|
return ret;
|
|
}
|
|
|
|
int wext_private_command(const char *ifname, char *cmd, int show_msg)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0, buf_size;
|
|
char *buf;
|
|
|
|
u8 cmdname[17] = {0}; // IFNAMSIZ+1
|
|
|
|
sscanf(cmd, "%16s", cmdname);
|
|
if((strcmp((const char *)cmdname, "config_get") == 0)
|
|
|| (strcmp((const char *)cmdname, "config_set") == 0)
|
|
|| (strcmp((const char *)cmdname, "efuse_get") == 0)
|
|
|| (strcmp((const char *)cmdname, "efuse_set") == 0)
|
|
|| (strcmp((const char *)cmdname, "mp_psd") == 0))
|
|
buf_size = 2600;//2600 for config_get rmap,0,512 (or realmap)
|
|
else
|
|
buf_size = 512;
|
|
|
|
|
|
|
|
if(strlen(cmd) >= buf_size)
|
|
buf_size = strlen(cmd) + 1; // 1 : '\0'
|
|
buf = (char*)pvPortMalloc(buf_size);
|
|
if(!buf){
|
|
printf("\n\rWEXT: Can't malloc memory");
|
|
return -1;
|
|
}
|
|
memset(buf, 0, buf_size);
|
|
strcpy(buf, cmd);
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.length = buf_size;
|
|
iwr.u.data.flags = 0;
|
|
|
|
if ((ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr)) < 0) {
|
|
printf("\n\rioctl[SIOCDEVPRIVATE] error. ret=%d\n", ret);
|
|
}
|
|
if (show_msg && iwr.u.data.length) {
|
|
if(iwr.u.data.length > buf_size)
|
|
printf("\n\rWEXT: Malloc memory is not enough");
|
|
printf("\n\rPrivate Message: %s", (char *) iwr.u.data.pointer);
|
|
}
|
|
vPortFree(buf);
|
|
return ret;
|
|
}
|
|
|
|
void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra)
|
|
{
|
|
unsigned char null_mac[6] = {0};
|
|
|
|
switch(cmd)
|
|
{
|
|
case SIOCGIWAP:
|
|
if(wrqu->ap_addr.sa_family == ARPHRD_ETHER)
|
|
{
|
|
if(!memcmp(wrqu->ap_addr.sa_data, null_mac, sizeof(null_mac)))
|
|
wifi_indication(WIFI_EVENT_DISCONNECT, wrqu->ap_addr.sa_data, sizeof(null_mac)+ 2, 0);
|
|
else
|
|
wifi_indication(WIFI_EVENT_CONNECT, wrqu->ap_addr.sa_data, sizeof(null_mac), 0);
|
|
}
|
|
break;
|
|
|
|
case IWEVCUSTOM:
|
|
if(extra)
|
|
{
|
|
if(!memcmp(IW_EXT_STR_FOURWAY_DONE, extra, strlen(IW_EXT_STR_FOURWAY_DONE)))
|
|
wifi_indication(WIFI_EVENT_FOURWAY_HANDSHAKE_DONE, extra, strlen(IW_EXT_STR_FOURWAY_DONE), 0);
|
|
else if(!memcmp(IW_EXT_STR_RECONNECTION_FAIL, extra, strlen(IW_EXT_STR_RECONNECTION_FAIL)))
|
|
wifi_indication(WIFI_EVENT_RECONNECTION_FAIL, extra, strlen(IW_EXT_STR_RECONNECTION_FAIL), 0);
|
|
else if(!memcmp(IW_EVT_STR_NO_NETWORK, extra, strlen(IW_EVT_STR_NO_NETWORK)))
|
|
wifi_indication(WIFI_EVENT_NO_NETWORK, extra, strlen(IW_EVT_STR_NO_NETWORK), 0);
|
|
else if(!memcmp(IW_EVT_STR_ICV_ERROR, extra, strlen(IW_EVT_STR_ICV_ERROR)))
|
|
wifi_indication(WIFI_EVENT_ICV_ERROR, extra, strlen(IW_EVT_STR_ICV_ERROR), 0);
|
|
else if(!memcmp(IW_EVT_STR_CHALLENGE_FAIL, extra, strlen(IW_EVT_STR_CHALLENGE_FAIL)))
|
|
wifi_indication(WIFI_EVENT_CHALLENGE_FAIL, extra, strlen(IW_EVT_STR_CHALLENGE_FAIL), 0);
|
|
#if CONFIG_ENABLE_P2P || defined(CONFIG_AP_MODE)
|
|
else if(!memcmp(IW_EVT_STR_STA_ASSOC, extra, strlen(IW_EVT_STR_STA_ASSOC)))
|
|
wifi_indication(WIFI_EVENT_STA_ASSOC, wrqu->data.pointer, wrqu->data.length, 0);
|
|
else if(!memcmp(IW_EVT_STR_STA_DISASSOC, extra, strlen(IW_EVT_STR_STA_DISASSOC)))
|
|
wifi_indication(WIFI_EVENT_STA_DISASSOC, wrqu->addr.sa_data, sizeof(null_mac), 0);
|
|
else if(!memcmp(IW_EVT_STR_SEND_ACTION_DONE, extra, strlen(IW_EVT_STR_SEND_ACTION_DONE)))
|
|
wifi_indication(WIFI_EVENT_SEND_ACTION_DONE, NULL, 0, wrqu->data.flags);
|
|
#endif
|
|
}
|
|
break;
|
|
case SIOCGIWSCAN:
|
|
if(wrqu->data.pointer == NULL)
|
|
wifi_indication(WIFI_EVENT_SCAN_DONE, NULL, 0, 0);
|
|
else
|
|
wifi_indication(WIFI_EVENT_SCAN_RESULT_REPORT, wrqu->data.pointer, wrqu->data.length, 0);
|
|
break;
|
|
case IWEVMGNTRECV:
|
|
wifi_indication(WIFI_EVENT_RX_MGNT, wrqu->data.pointer, wrqu->data.length, wrqu->data.flags);
|
|
break;
|
|
#ifdef REPORT_STA_EVENT
|
|
case IWEVREGISTERED:
|
|
if(wrqu->addr.sa_family == ARPHRD_ETHER)
|
|
wifi_indication(WIFI_EVENT_STA_ASSOC, wrqu->addr.sa_data, sizeof(null_mac), 0);
|
|
break;
|
|
case IWEVEXPIRED:
|
|
if(wrqu->addr.sa_family == ARPHRD_ETHER)
|
|
wifi_indication(WIFI_EVENT_STA_DISASSOC, wrqu->addr.sa_data, sizeof(null_mac), 0);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
int wext_send_eapol(const char *ifname, char *buf, __u16 buf_len, __u16 flags)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.length = buf_len;
|
|
iwr.u.data.flags = flags;
|
|
if (iw_ioctl(ifname, SIOCSIWEAPOLSEND, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWEAPOLSEND] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_send_mgnt(const char *ifname, char *buf, __u16 buf_len, __u16 flags)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.length = buf_len;
|
|
iwr.u.data.flags = flags;
|
|
if (iw_ioctl(ifname, SIOCSIWMGNTSEND, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWMGNTSEND] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_gen_ie(const char *ifname, char *buf, __u16 buf_len, __u16 flags)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.data.pointer = buf;
|
|
iwr.u.data.length = buf_len;
|
|
iwr.u.data.flags = flags;
|
|
if (iw_ioctl(ifname, SIOCSIWGENIE, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWGENIE] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_autoreconnect(const char *ifname, __u8 mode, __u8 retry_times, __u16 timeout)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("SetAutoRecnt");
|
|
para = pvPortMalloc((4) + cmd_len);//size:para_len+cmd_len
|
|
if(para == NULL) return -1;
|
|
|
|
//Cmd
|
|
snprintf((char*)para, cmd_len, "SetAutoRecnt");
|
|
//length
|
|
*(para+cmd_len) = mode; //para1
|
|
*(para+cmd_len+1) = retry_times; //para2
|
|
*(para+cmd_len+2) = timeout; //para3
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = (4) + cmd_len;
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_set_autoreconnect():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_autoreconnect(const char *ifname, __u8 *mode)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("GetAutoRecnt");
|
|
para = pvPortMalloc(cmd_len);//size:para_len+cmd_len
|
|
//Cmd
|
|
snprintf((char*)para, cmd_len, "GetAutoRecnt");
|
|
//length
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = cmd_len;
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_get_autoreconnect():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
*mode = *(__u8 *)(iwr.u.data.pointer);
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_get_drv_ability(const char *ifname, __u32 *ability)
|
|
{
|
|
int ret = 0;
|
|
char * buf = (char *)rtw_zmalloc(33);
|
|
if(buf == NULL) return -1;
|
|
|
|
snprintf(buf, 33, "get_drv_ability %x", ability);
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
rtw_free(buf);
|
|
return ret;
|
|
}
|
|
|
|
#ifdef CONFIG_CUSTOM_IE
|
|
int wext_add_custom_ie(const char *ifname, void *cus_ie, int ie_num)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
if(ie_num <= 0 || !cus_ie){
|
|
printf("\n\rwext_add_custom_ie():wrong parameter");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("SetCusIE");
|
|
para = pvPortMalloc((4)* 2 + cmd_len);//size:addr len+cmd_len
|
|
if(para == NULL) return -1;
|
|
|
|
//Cmd
|
|
snprintf(para, cmd_len, "SetCusIE");
|
|
//addr length
|
|
*(__u32 *)(para + cmd_len) = (__u32)cus_ie; //ie addr
|
|
//ie_num
|
|
*(__u32 *)(para + cmd_len + 4) = ie_num; //num of ie
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = (4)* 2 + cmd_len;// 2 input
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_add_custom_ie():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
vPortFree(para);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int wext_update_custom_ie(const char *ifname, void * cus_ie, int ie_index)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
if(ie_index <= 0 || !cus_ie){
|
|
printf("\n\rwext_update_custom_ie():wrong parameter");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("UpdateIE");
|
|
para = pvPortMalloc((4)* 2 + cmd_len);//size:addr len+cmd_len
|
|
if(para == NULL) return -1;
|
|
|
|
//Cmd
|
|
snprintf(para, cmd_len, "UpdateIE");
|
|
//addr length
|
|
*(__u32 *)(para + cmd_len) = (__u32)cus_ie; //ie addr
|
|
//ie_index
|
|
*(__u32 *)(para + cmd_len + 4) = ie_index; //num of ie
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = (4)* 2 + cmd_len;// 2 input
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_update_custom_ie():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
vPortFree(para);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
int wext_del_custom_ie(const char *ifname)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("DelIE");
|
|
para = pvPortMalloc(cmd_len);//size:addr len+cmd_len
|
|
//Cmd
|
|
snprintf(para, cmd_len, "DelIE");
|
|
|
|
iwr.u.data.pointer = para;
|
|
iwr.u.data.length = cmd_len;
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_del_custom_ie():ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
vPortFree(para);
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_AP_MODE
|
|
int wext_enable_forwarding(const char *ifname)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("forwarding_set");
|
|
para = pvPortMalloc(cmd_len + 1);
|
|
if(para == NULL) return -1;
|
|
|
|
// forwarding_set 1
|
|
snprintf((char *) para, cmd_len, "forwarding_set");
|
|
*(para + cmd_len) = '1';
|
|
|
|
iwr.u.essid.pointer = para;
|
|
iwr.u.essid.length = cmd_len + 1;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_enable_forwarding(): ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
}
|
|
|
|
int wext_disable_forwarding(const char *ifname)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
__u8 *para = NULL;
|
|
int cmd_len = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
cmd_len = sizeof("forwarding_set");
|
|
para = pvPortMalloc(cmd_len + 1);
|
|
if(para == NULL) return -1;
|
|
|
|
// forwarding_set 0
|
|
snprintf((char *) para, cmd_len, "forwarding_set");
|
|
*(para + cmd_len) = '0';
|
|
|
|
iwr.u.essid.pointer = para;
|
|
iwr.u.essid.length = cmd_len + 1;
|
|
|
|
if (iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr) < 0) {
|
|
printf("\n\rwext_disable_forwarding(): ioctl[SIOCDEVPRIVATE] error");
|
|
ret = -1;
|
|
}
|
|
|
|
vPortFree(para);
|
|
return ret;
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_CONCURRENT_MODE
|
|
int wext_set_ch_deauth(const char *ifname, __u8 enable)
|
|
{
|
|
int ret = 0;
|
|
char * buf = (char *)rtw_zmalloc(16);
|
|
if(buf == NULL) return -1;
|
|
|
|
snprintf(buf, 16, "SetChDeauth %d", enable);
|
|
ret = wext_private_command(ifname, buf, 0);
|
|
|
|
rtw_free(buf);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int wext_set_adaptivity(rtw_adaptivity_mode_t adaptivity_mode)
|
|
{
|
|
extern u8 rtw_adaptivity_en;
|
|
extern u8 rtw_adaptivity_mode;
|
|
|
|
switch(adaptivity_mode){
|
|
case RTW_ADAPTIVITY_NORMAL:
|
|
rtw_adaptivity_en = 1; // enable adaptivity
|
|
rtw_adaptivity_mode = RTW_ADAPTIVITY_MODE_NORMAL;
|
|
break;
|
|
case RTW_ADAPTIVITY_CARRIER_SENSE:
|
|
rtw_adaptivity_en = 1; // enable adaptivity
|
|
rtw_adaptivity_mode = RTW_ADAPTIVITY_MODE_CARRIER_SENSE;
|
|
break;
|
|
case RTW_ADAPTIVITY_DISABLE:
|
|
default:
|
|
rtw_adaptivity_en = 0; //disable adaptivity
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int wext_set_adaptivity_th_l2h_ini(__u8 l2h_threshold)
|
|
{
|
|
extern s8 rtw_adaptivity_th_l2h_ini;
|
|
rtw_adaptivity_th_l2h_ini = (__s8)l2h_threshold;
|
|
return 0;
|
|
}
|
|
|
|
int wext_set_trp_tis(__u8 enable)
|
|
{
|
|
extern u8 rtw_tx_pwr_lmt_enable;
|
|
extern u8 rtw_tx_pwr_by_rate;
|
|
extern u8 rtw_trp_tis_test_en;
|
|
|
|
if(enable != RTW_TRP_TIS_DISABLE){
|
|
//close the tx power limit and pwr by rate incase the efficiency of Antenna is not good enough.
|
|
rtw_tx_pwr_lmt_enable = 2;//set 0 to disable, set 2 to use efuse value
|
|
rtw_tx_pwr_by_rate = 2;//set 0 to disable, set 2 to use efuse value
|
|
if(enable == RTW_TRP_TIS_NORMAL){
|
|
//disable some dynamic mechanism
|
|
rtw_trp_tis_test_en = BIT0;
|
|
}else if(enable == RTW_TRP_TIS_DYNAMIC){
|
|
rtw_trp_tis_test_en = BIT1 | BIT0;
|
|
}else if(enable == RTW_TRP_TIS_FIX_ACK_RATE){
|
|
rtw_trp_tis_test_en = BIT2 | BIT0;
|
|
}
|
|
//you can change autoreconnct mode to RTW_AUTORECONNECT_INFINITE in init_thread function
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#if defined(CONFIG_WLAN_LOW_PW)
|
|
extern void rtw_enable_wlan_low_pwr_mode(WLAN_LOW_PW_MODE mode);
|
|
void wext_set_low_power_mode(__u8 enable)
|
|
{
|
|
extern WLAN_LOW_PW_MODE rtw_wlan_low_pw_mode;
|
|
extern int rtw_wlan_low_pw_mode4_c1;
|
|
extern int rtw_wlan_low_pw_mode4_c2;
|
|
extern int rtw_reduce_pa_gain;
|
|
if(enable == ENABLE){
|
|
rtw_wlan_low_pw_mode = PW_MODE_1|PW_MODE_2|PW_MODE_3|PW_MODE_4|PW_MODE_6;
|
|
rtw_wlan_low_pw_mode4_c1 = 24;
|
|
rtw_wlan_low_pw_mode4_c2 = 16;
|
|
rtw_reduce_pa_gain = 1; //0:not reduce, 1:reduce 2, 2:reduce 3
|
|
rtw_enable_wlan_low_pwr_mode(rtw_wlan_low_pw_mode);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int wext_get_auto_chl(const char *ifname, unsigned char *channel_set, unsigned char channel_num)
|
|
{
|
|
int ret = -1;
|
|
int channel = 0;
|
|
wext_disable_powersave(ifname);
|
|
if((channel = rltk_get_auto_chl(ifname,channel_set,channel_num)) != 0 )
|
|
ret = channel ;
|
|
wext_enable_powersave(ifname, 1, 1);
|
|
return ret;
|
|
}
|
|
|
|
int wext_set_sta_num(unsigned char ap_sta_num)
|
|
{
|
|
return rltk_set_sta_num(ap_sta_num);
|
|
}
|
|
|
|
int wext_del_station(const char *ifname, unsigned char* hwaddr)
|
|
{
|
|
return rltk_del_station(ifname, hwaddr);
|
|
}
|
|
|
|
extern struct list_head *mf_list_head;
|
|
int wext_init_mac_filter(void)
|
|
{
|
|
if(mf_list_head != NULL){
|
|
return -1;
|
|
}
|
|
|
|
mf_list_head = malloc(sizeof(struct list_head));
|
|
if(mf_list_head == NULL){
|
|
printf("\n\r[ERROR] %s : can't allocate mf_list_head",__func__);
|
|
return -1;
|
|
}
|
|
|
|
INIT_LIST_HEAD(mf_list_head);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int wext_deinit_mac_filter(void)
|
|
{
|
|
if(mf_list_head == NULL){
|
|
return -1;
|
|
}
|
|
struct list_head *iterator;
|
|
rtw_mac_filter_list_t *item;
|
|
list_for_each(iterator, mf_list_head) {
|
|
item = list_entry(iterator, rtw_mac_filter_list_t, node);
|
|
list_del(iterator);
|
|
free(item);
|
|
item = NULL;
|
|
iterator = mf_list_head;
|
|
}
|
|
|
|
free(mf_list_head);
|
|
mf_list_head = NULL;
|
|
return 0;
|
|
}
|
|
|
|
int wext_add_mac_filter(unsigned char* hwaddr)
|
|
{
|
|
if(mf_list_head == NULL){
|
|
return -1;
|
|
}
|
|
|
|
rtw_mac_filter_list_t *mf_list_new;
|
|
mf_list_new = malloc(sizeof(rtw_mac_filter_list_t));
|
|
if(mf_list_new == NULL){
|
|
printf("\n\r[ERROR] %s : can't allocate mf_list_new",__func__);
|
|
return -1;
|
|
}
|
|
memcpy(mf_list_new->mac_addr,hwaddr,6);
|
|
list_add(&(mf_list_new->node), mf_list_head);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int wext_del_mac_filter(unsigned char* hwaddr)
|
|
{
|
|
if(mf_list_head == NULL){
|
|
return -1;
|
|
}
|
|
|
|
struct list_head *iterator;
|
|
rtw_mac_filter_list_t *item;
|
|
list_for_each(iterator, mf_list_head) {
|
|
item = list_entry(iterator, rtw_mac_filter_list_t, node);
|
|
if(memcmp(item->mac_addr,hwaddr,6) == 0){
|
|
list_del(iterator);
|
|
free(item);
|
|
item = NULL;
|
|
return 0;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
extern void rtw_set_indicate_mgnt(int enable);
|
|
void wext_set_indicate_mgnt(int enable)
|
|
{
|
|
rtw_set_indicate_mgnt(enable);
|
|
return;
|
|
}
|
|
|
|
void wext_set_sigstat_fast_enable(int enable)
|
|
{
|
|
rtw_set_sigstat_fast_enable(enable);
|
|
return;
|
|
}
|
|
|
|
void wext_set_lowrssi_use_b(int enable,int rssi)
|
|
{
|
|
rtw_set_lowrssi_use_b(enable,rssi);
|
|
return ;
|
|
}
|
|
#ifdef CONFIG_AP_MODE
|
|
extern void rltk_stop_softap(const char *ifname);
|
|
extern void rltk_suspend_softap(const char *ifname);
|
|
extern void rltk_suspend_softap_beacon(const char *ifname);
|
|
void wext_stop_softap(const char *ifname)
|
|
{
|
|
rltk_stop_softap(ifname);
|
|
}
|
|
void wext_suspend_softap(const char *ifname)
|
|
{
|
|
rltk_suspend_softap(ifname);
|
|
}
|
|
void wext_suspend_softap_beacon(const char *ifname)
|
|
{
|
|
rltk_suspend_softap_beacon(ifname);
|
|
}
|
|
void wext_resume_softap(const char *ifname)
|
|
{
|
|
rltk_resume_softap(ifname);
|
|
}
|
|
int wext_ap_switch_chl_and_inform(unsigned char new_channel)
|
|
{
|
|
if(rtw_ap_switch_chl_and_inform(new_channel))
|
|
return RTW_SUCCESS;
|
|
else
|
|
return RTW_ERROR;
|
|
}
|
|
#endif
|
|
|
|
extern int rltk_get_nhm_ratio_level(const char *ifname, __u32 * level);
|
|
int wext_get_nhm_ratio_level(const char *ifname, __u32 *level)
|
|
{
|
|
int ret = -1;
|
|
|
|
wext_disable_powersave(ifname);
|
|
ret = rltk_get_nhm_ratio_level(ifname, level);
|
|
wext_enable_powersave(ifname, 1, 1);
|
|
return ret;
|
|
}
|
|
|
|
extern int rltk_get_retry_drop_num(const char *ifname, rtw_fw_retry_drop_t * retry);
|
|
int wext_get_retry_drop_num(const char *ifname, rtw_fw_retry_drop_t * retry)
|
|
{
|
|
return rltk_get_retry_drop_num(ifname, retry);
|
|
}
|
|
|
|
extern int rltk_get_sw_trx_statistics(const char *ifname, rtw_net_device_stats_t *stats);
|
|
int wext_get_sw_trx_statistics(const char *ifname, rtw_net_device_stats_t *stats)
|
|
{
|
|
return rltk_get_sw_trx_statistics(ifname, stats);
|
|
}
|
|
#ifndef CONFIG_MCC_STA_AP_MODE
|
|
extern int rtw_get_RxInfo(const char *ifname,u8* BeaconCnt, int *rssi, u8* CurIGValue, u32* Fa_Ofdm_count, u32* Fa_Cck_count);
|
|
int wext_get_RxInfo(const char *ifname, __u8* BeaconCnt, int *rssi, __u8* CurIGValue, __u32* Fa_Ofdm_count, __u32* Fa_Cck_count)
|
|
{
|
|
return rtw_get_RxInfo(ifname, BeaconCnt, rssi, CurIGValue, Fa_Ofdm_count, Fa_Cck_count);
|
|
}
|
|
|
|
extern int rtw_get_RxCrcInfo(const char *ifname, u32* CCK_Crc_Fail, u32* CCK_Crc_OK, u32* OFDM_Crc_Fail, u32* OFDM_Crc_OK, u32* HT_Crc_Fail, u32* HT_Crc_OK);
|
|
int wext_get_RxCrcInfo(const char *ifname, __u32* CCK_Crc_Fail, __u32* CCK_Crc_OK, __u32* OFDM_Crc_Fail, __u32* OFDM_Crc_OK, __u32* HT_Crc_Fail, __u32* HT_Crc_OK)
|
|
{
|
|
return rtw_get_RxCrcInfo(ifname, CCK_Crc_Fail, CCK_Crc_OK, OFDM_Crc_Fail, OFDM_Crc_OK, HT_Crc_Fail, HT_Crc_OK);
|
|
}
|
|
|
|
extern int rtw_get_TxInfo(const char *ifname, u32 *tx_ok, u32 *tx_retry, u32 *tx_drop);
|
|
int wext_get_TxInfo(const char *ifname, __u32 *tx_ok, __u32 *tx_retry, __u32 *tx_drop)
|
|
{
|
|
return rtw_get_TxInfo(ifname, tx_ok, tx_retry, tx_drop);
|
|
}
|
|
|
|
extern int rtw_get_PSInfo(const char *ifname, u32* tim_wake_up_count);
|
|
int wext_get_PSInfo(const char *ifname, __u32* tim_wake_up_count)
|
|
{
|
|
return rtw_get_PSInfo(ifname, tim_wake_up_count);
|
|
}
|
|
#endif
|
|
#ifdef CONFIG_SYNCPKT
|
|
int wext_set_syncpkt_da(const char *ifname, __u8 *da)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
iwr.u.data.pointer = da;
|
|
iwr.u.data.length= 6;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWSYNCDASET, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWSYNCDASET] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_send_syncpkt(const char *ifname, __u8 flag, __u8 pktnum, __u8 interval)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
iwr.u.param.flags = pktnum;
|
|
iwr.u.param.fixed = interval;
|
|
iwr.u.param.disabled = flag;
|
|
if (iw_ioctl(ifname, SIOCSIWSYNCSET, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWSYNCSET] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int wext_disable_fw_ips(const char *ifname, __u8 enable)
|
|
{
|
|
struct iwreq iwr;
|
|
int ret = 0;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
|
|
iwr.u.param.flags = enable;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWSYNCFWIPS, &iwr) < 0) {
|
|
printf("\n\rioctl[SIOCSIWSYNCFWIPS] error");
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \brief This function can set adaptivity enable value in runtime.
|
|
*
|
|
* \param ifname "wlan0" / "wlan1"
|
|
* \param value 0 diable, 1 enable
|
|
* \return 0 success, others fail
|
|
*/
|
|
int wext_set_adaptivity_enable(const char *ifname, __u8 value)
|
|
{
|
|
int ret = 0;
|
|
struct iwreq iwr;
|
|
|
|
memset(&iwr, 0, sizeof(iwr));
|
|
iwr.u.param.value = value;
|
|
|
|
if (iw_ioctl(ifname, SIOCSIWPRIVADAPTIVITY, &iwr) < 0) {
|
|
printf("\n\rwext_set_adaptivity_enable():ioctl[SIOCSIWPRIVADAPTIVITY] error");
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
extern u8 rtw_get_adaptivity_enable(const char *ifname);
|
|
/**
|
|
* \brief This function can get adaptivity enable value in use.
|
|
*
|
|
* \param ifname "wlan0" / "wlan1"
|
|
* \return 0 disable, 1 enable
|
|
*/
|
|
__u8 wext_get_adaptivity_enable(const char *ifname)
|
|
{
|
|
return rtw_get_adaptivity_enable(ifname);
|
|
}
|
|
|
|
extern int rtw_set_adaptivity_mode(const char *ifname, u8 mode);
|
|
/**
|
|
* \brief This function can set adaptivity mode in runtime.
|
|
*
|
|
* \param ifname "wlan0" / "wlan1"
|
|
* \param mode 0 RTW_ADAPTIVITY_NORMAL, 1 RTW_ADAPTIVITY_CARRIER_SENSE
|
|
* \return 0 success, others fail
|
|
*/
|
|
int wext_set_adaptivity_mode(const char *ifname, __u8 mode)
|
|
{
|
|
return rtw_set_adaptivity_mode(ifname, mode);
|
|
}
|
|
|
|
extern u8 rtw_get_adaptivity_mode(const char *ifname);
|
|
/**
|
|
* \brief This function can get adaptivity mode in use.
|
|
*
|
|
* \param ifname "wlan0" / "wlan1"
|
|
* \return 0 RTW_ADAPTIVITY_NORMAL, 1 RTW_ADAPTIVITY_CARRIER_SENSE
|
|
*/
|
|
__u8 wext_get_adaptivity_mode(const char *ifname)
|
|
{
|
|
return rtw_get_adaptivity_mode(ifname);
|
|
}
|
|
|
|
extern u8 rtw_get_channel_plan(const char *ifname);
|
|
/**
|
|
* \brief This function can get channel plan in use.
|
|
*
|
|
* \param ifname "wlan0" / "wlan1"
|
|
* \return refer to enum _RT_CHANNEL_DOMAIN, RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20, RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21 etc.
|
|
*/
|
|
__u8 wext_get_channel_plan(const char *ifname)
|
|
{
|
|
return rtw_get_channel_plan(ifname);
|
|
}
|
|
|