0
0
Fork 0
hgicf/utils/hgic_fmac.c

1141 lines
34 KiB
C

/**
******************************************************************************
* @file hgic_fmac.c
* @author HUGE-IC Application Team
* @version V1.0.0
* @date 2021-06-23
* @brief fmac api for application.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2021 HUGE-IC</center></h2>
*
******************************************************************************
*/
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <poll.h>
#define fmac_dbg(fmt, ...) printf("%s:%d::"fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MACARG(a) (a)[0]&0xff, (a)[1]&0xff, (a)[2]&0xff, (a)[3]&0xff, (a)[4]&0xff, (a)[5]&0xff
#define IPSTR "%d.%d.%d.%d"
#define IPARG(a) ((a)>>24)&0xff, ((a)>>16)&0xff, ((a)>>8)&0xff, (a)&0xff
#define MAC2STR(mac, str) (sprintf((str), MACSTR, MACARG(mac)))
#define STR_EQ(s1,s2) (strcmp(s1,s2)==0)
#define MAC_EQ(a1,a2) (memcmp(a1,a2,6)==0)
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
enum FMAC_CONNECT_REASON {
FMAC_ASSOC_SUCCESS = 0,
FMAC_ASSOC_REFUSED = 1,
FMAC_ASSOC_DENIED_NO_MORE_STAS = 17,
FMAC_ASSOC_DENIED_INSUFFICIENT_BANDWIDTH = 33,
FMAC_ASSOC_REFUSED_AP_OUT_OF_MEMORY = 93,
FMAC_ASSOC_NO_AP = 0xff
};
struct hgic_tx_info {
uint8 band;
uint8 tx_bw;
uint8 tx_mcs;
uint8 freq_idx: 5, antenna: 3;
uint32 tx_flags;
uint16 tx_flags2;
uint8 priority;
uint8 tx_power;
};
struct hgic_freqinfo {
unsigned char bss_bw, chan_cnt;
unsigned short freq_start, freq_end;
unsigned short chan_list[16];
};
enum HGIC_MODULE_TYPE{
HGIC_MODULE_TYPE_700M = 1,
HGIC_MODULE_TYPE_900M = 2,
HGIC_MODULE_TYPE_860M = 3,
HGIC_MODULE_TYPE_810M = 5,
};
struct hgic_module_hwinfo{
union{
struct{
unsigned char type;
unsigned char saw:1, rev:7;
};
unsigned short v;
};
};
int hgic_str2mac(char *mac_str, unsigned char *mac)
{
int tmp[6];
if (mac_str && mac) {
memset(tmp, 0, sizeof(tmp));
memset(mac, 0, 6);
if (6 == sscanf(mac_str, MACSTR, &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5])) {
mac[0] = (unsigned char)tmp[0];
mac[1] = (unsigned char)tmp[1];
mac[2] = (unsigned char)tmp[2];
mac[3] = (unsigned char)tmp[3];
mac[4] = (unsigned char)tmp[4];
mac[5] = (unsigned char)tmp[5];
return 1;
}
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/* iwpriv api */
int hgic_iwpriv_read(char *buff, int len)
{
int ret = 0;
int fd = -1;
if (buff == NULL || len <= 0) {
return 0;
}
memset(buff, 0, len);
fd = open("/proc/hgic/iwpriv", O_RDONLY);
if (fd != -1) {
ret = read(fd, buff, len);
close(fd);
}
return ret;
}
int hgic_iwpriv_write(char *buff, int len)
{
int ret = 0;
int fd = -1;
if (buff == NULL || len <= 0) {
return 0;
}
fd = open("/proc/hgic/iwpriv", O_WRONLY);
if (fd != -1) {
ret = write(fd, buff, len);
close(fd);
}
return ret > 0;
}
int hgic_iwpriv_do(char *ifname, char *cmd, char *args)
{
int ret = 0;
int fd = -1;
char buff[512];
char *ptr = NULL;
memset(buff, 0, sizeof(buff));
if (args) {
sprintf(buff, "%s %s %s", ifname, cmd, args);
} else {
sprintf(buff, "%s %s", ifname, cmd);
}
if (hgic_iwpriv_write(buff, strlen(buff))) {
if (STR_EQ(cmd, "set") || STR_EQ(cmd, "scan") || STR_EQ(cmd, "save")) {
if (hgic_iwpriv_read(buff, sizeof(buff)) && strstr(buff, "OK")) {
ret = 1;
} else {
ptr = strstr(buff, "error:");
if (ptr) {
ret = atoi(ptr + 6);
fmac_dbg("error: %s\r\n", strerror(ret));
}
}
}
}
return ret;
}
int hgic_iwpriv_set_int(char *ifname, char *name, int value)
{
char arg[64];
memset(arg, 0, sizeof(arg));
sprintf(arg, "%s=%d", name, value);
return hgic_iwpriv_do(ifname, "set", arg);
}
int hgic_iwpriv_set_mac(char *ifname, char *name, char *mac)
{
char arg[64];
memset(arg, 0, sizeof(arg));
sprintf(arg, "%s="MACSTR, name, MACARG(mac));
return hgic_iwpriv_do(ifname, "set", arg);
}
int hgic_iwpriv_set_ints(char *ifname, char *name, int cnt, ...)
{
int i = 0;
int val = 0;
char arg[512];
char *ptr = arg;
va_list argptr;
memset(arg, 0, sizeof(arg));
sprintf(ptr, "%s=", name);
ptr += strlen(ptr);
va_start(argptr, cnt);
for (i = 0; i < cnt; i++) {
val = va_arg(argptr, int);
sprintf(ptr, (i == 0 ? "%d" : ",%d"), val);
ptr += strlen(ptr);
}
va_end(argptr);
return hgic_iwpriv_do(ifname, "set", arg);
}
int hgic_iwpriv_set_intarray(char *ifname, char *name, int *values, int cnt)
{
int i = 0;
char arg[512];
char *ptr = arg;
memset(arg, 0, sizeof(arg));
sprintf(ptr, "%s=", name);
ptr += strlen(ptr);
for (i = 0; i < cnt; i++) {
sprintf(ptr, (i == 0 ? "%d" : ",%d"), values[i]);
ptr += strlen(ptr);
}
return hgic_iwpriv_do(ifname, "set", arg);
}
int hgic_iwpriv_set_bytes(char *ifname, char *name, char *value)
{
char arg[512];
memset(arg, 0, sizeof(arg));
sprintf(arg, "%s=%s", name, value);
return hgic_iwpriv_do(ifname, "set", arg);
}
int hgic_iwpriv_get_int(char *ifname, char *name)
{
char buff[8];
hgic_iwpriv_do(ifname, "get", name);
hgic_iwpriv_read(buff, 8);
return atoi(buff);
}
int hgic_iwpriv_get_bytes(char *ifname, char *name, char *buff, int count)
{
hgic_iwpriv_do(ifname, "get", name);
return hgic_iwpriv_read(buff, count);
}
int hgic_iwpriv_get_mac(char *ifname, char *name, char *mac)
{
char str[32];
hgic_iwpriv_do(ifname, "get", name);
hgic_iwpriv_read(str, sizeof(str));
return hgic_str2mac(str, mac);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
int hgic_iwpriv_set_ssid(char *ifname, char *ssid)
{
return hgic_iwpriv_set_bytes(ifname, "ssid", ssid);
}
int hgic_iwpriv_set_bssid(char *ifname, char *bssid)
{
return hgic_iwpriv_set_mac(ifname, "bssid", bssid);
}
int hgic_iwpriv_set_channel(char *ifname, int channel)
{
return hgic_iwpriv_set_int(ifname, "channel", channel);
}
int hgic_iwpriv_set_keymgmt(char *ifname, char *key_mgmt)
{
return hgic_iwpriv_set_bytes(ifname, "key_mgmt", key_mgmt);
}
int hgic_iwpriv_set_wpapsk(char *ifname, char *wpa_psk)
{
return hgic_iwpriv_set_bytes(ifname, "wpa_psk", wpa_psk);
}
int hgic_iwpriv_set_freqrange(char *ifname, int freq_start, int freq_end, int bw)
{
return hgic_iwpriv_set_ints(ifname, "freq_range", 3, freq_start, freq_end, bw);
}
int hgic_iwpriv_set_bss_bw(char *ifname, int bss_bw)
{
return hgic_iwpriv_set_int(ifname, "bss_bw", bss_bw);
}
int hgic_iwpriv_set_tx_bw(char *ifname, int tx_bw)
{
return hgic_iwpriv_set_int(ifname, "tx_bw", tx_bw);
}
int hgic_iwpriv_set_tx_mcs(char *ifname, int tx_mcs)
{
return hgic_iwpriv_set_int(ifname, "tx_mcs", tx_mcs);
}
int hgic_iwpriv_set_acs(char *ifname, int start, int tmo)
{
return hgic_iwpriv_set_ints(ifname, "acs", 2, start, tmo);
}
int hgic_iwpriv_set_chan_list(char *ifname, int *chan_list, int chan_count)
{
return hgic_iwpriv_set_intarray(ifname, "chan_list", chan_list, chan_count);
}
int hgic_iwpriv_set_mode(char *ifname, char *mode)
{
return hgic_iwpriv_set_bytes(ifname, "mode", mode);
}
int hgic_iwpriv_set_paired_stas(char *ifname, char *paired_stas)
{
return hgic_iwpriv_set_bytes(ifname, "paired_stas", paired_stas);
}
int hgic_iwpriv_set_pairing(char *ifname, int start)
{
return hgic_iwpriv_set_int(ifname, "pairing", start);
}
int hgic_iwpriv_set_beacon_int(char *ifname, int beacon_int)
{
return hgic_iwpriv_set_int(ifname, "beacon_int", beacon_int);
}
int hgic_iwpriv_set_radio_off(char *ifname, int off)
{
return hgic_iwpriv_set_int(ifname, "radio_off", off);
}
int hgic_iwpriv_set_join_group(char *ifname, char *mcast_addr, int aid)
{
char arg[64];
memset(arg, 0, sizeof(arg));
sprintf(arg, "join_group="MACSTR",%d", MACARG(mcast_addr), aid);
return hgic_iwpriv_do(ifname, "set", arg);
}
int hgic_iwpriv_set_txpower(char *ifname, int txpower)
{
return hgic_iwpriv_set_int(ifname, "txpower", txpower);
}
int hgic_iwpriv_set_ps_connect(char *ifname, int period, int roundup)
{
return hgic_iwpriv_set_ints(ifname, "ps_connect", 2, period, roundup);
}
int hgic_iwpriv_set_bss_max_idle(char *ifname, int bss_max_idle)
{
return hgic_iwpriv_set_int(ifname, "bss_max_idle", bss_max_idle);
}
int hgic_iwpriv_set_wkio_mode(char *ifname, int wkio_mode)
{
return hgic_iwpriv_set_int(ifname, "wkio_mode", wkio_mode);
}
int hgic_iwpriv_set_dtim_period(char *ifname, int dtim_period)
{
return hgic_iwpriv_set_int(ifname, "dtim_period", dtim_period);
}
int hgic_iwpriv_set_ps_mode(char *ifname, int ps_mode)
{
return hgic_iwpriv_set_int(ifname, "ps_mode", ps_mode);
}
int hgic_iwpriv_set_aplost_time(char *ifname, int aplost_time)
{
return hgic_iwpriv_set_int(ifname, "aplost_time", aplost_time);
}
int hgic_iwpriv_unpair(char *ifname, char *mac)
{
return hgic_iwpriv_set_mac(ifname, "unpair", mac);
}
int hgic_iwpriv_scan(char *ifname)
{
return hgic_iwpriv_do(ifname, "scan", NULL);
}
int hgic_iwpriv_save(char *ifname)
{
return hgic_iwpriv_do(ifname, "save", NULL);
}
int hgic_iwpriv_set_auto_chswitch(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "auto_chswitch", enable);
}
int hgic_iwpriv_set_mcast_key(char *ifname, char *mcast_key)
{
return hgic_iwpriv_set_bytes(ifname, "mcast_key", mcast_key);
}
int hgic_iwpriv_set_reassoc_wkhost(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "reassoc_wkhost", enable);
}
int hgic_iwpriv_set_wakeup_io(char *ifname, int wakeup_io)
{
return hgic_iwpriv_set_int(ifname, "wakeup_io", wakeup_io);
}
int hgic_iwpriv_set_dbginfo(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "dbginfo", enable);
}
int hgic_iwpriv_set_sysdbg(char *ifname, char *sysdbg)
{
return hgic_iwpriv_set_bytes(ifname, "sysdbg", sysdbg);
}
int hgic_iwpriv_set_primary_chan(char *ifname, int primary_chan)
{
return hgic_iwpriv_set_int(ifname, "primary_chan", primary_chan);
}
int hgic_iwpriv_set_autosleep_time(char *ifname, int autosleep_time)
{
return hgic_iwpriv_set_int(ifname, "autosleep_time", autosleep_time);
}
int hgic_iwpriv_set_supper_pwr(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "supper_pwr", enable);
}
int hgic_iwpriv_set_r_ssid(char *ifname, char *r_ssid)
{
return hgic_iwpriv_set_bytes(ifname, "r_ssid", r_ssid);
}
int hgic_iwpriv_set_r_psk(char *ifname, char *r_psk)
{
return hgic_iwpriv_set_bytes(ifname, "r_psk", r_psk);
}
int hgic_iwpriv_set_auto_save(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "auto_save", enable);
}
int hgic_iwpriv_set_pair_autostop(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "pair_autostop", enable);
}
int hgic_iwpriv_set_dcdc13(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "dcdc13", enable);
}
int hgic_iwpriv_set_acktmo(char *ifname, int acktmo)
{
return hgic_iwpriv_set_int(ifname, "acktmo", acktmo);
}
int hgic_iwpriv_get_sta_list(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "sta_list", buff, size);
}
int hgic_iwpriv_get_scan_list(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "scan_list", buff, size);
}
int hgic_iwpriv_get_ssid(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "ssid", buff, size);
}
int hgic_iwpriv_get_bssid(char *ifname, char *mac)
{
return hgic_iwpriv_get_mac(ifname, "bssid", mac);
}
int hgic_iwpriv_get_wpa_psk(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "wpa_psk", buff, size);
}
int hgic_iwpriv_get_txpower(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "txpower");
}
int hgic_iwpriv_get_aggcnt(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "agg_cnt");
}
int hgic_iwpriv_get_bss_bw(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "bss_bw");
}
int hgic_iwpriv_get_chan_list(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "chan_list", buff, size);
}
int hgic_iwpriv_get_freq_range(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "freq_range", buff, size);
}
int hgic_iwpriv_get_key_mgmt(char *ifname, char *buff, int size)
{
return hgic_iwpriv_get_bytes(ifname, "key_mgmt", buff, size);
}
int hgic_iwpriv_get_battery_level(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "battery_level");
}
int hgic_iwpriv_get_module_type(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "module_type");
}
int hgic_iwpriv_set_pa_pwrctrl_dis(char *ifname, int disable)
{
return hgic_iwpriv_set_int(ifname, "pa_pwrctl_dis", disable);
}
int hgic_iwpriv_set_dhcpc(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "dhcpc", enable);
}
int hgic_iwpriv_get_disassoc_reason(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "disassoc_reason");
}
int hgic_iwpriv_set_wkdata_save(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "wkdata_save", enable);
}
int hgic_iwpriv_set_mcast_txparam(char *ifname, int dupcnt, int tx_bw, int tx_mcs, int clearch)
{
return hgic_iwpriv_set_ints(ifname, "mcast_txparam", 4, dupcnt, tx_bw, tx_mcs, clearch);
}
int hgic_iwpriv_reset_sta(char *ifname, char *mac_addr)
{
return hgic_iwpriv_set_mac(ifname, "reset_sta", mac_addr);
}
int hgic_iwpriv_ant_auto(char *ifname, int en)
{
return hgic_iwpriv_set_int(ifname, "ant_auto", en);
}
int hgic_iwpriv_set_ant_sel(char *ifname, int ant)
{
return hgic_iwpriv_set_int(ifname, "ant_sel", ant);
}
int hgic_iwpriv_get_ant_sel(char *ifname)
{
return hgic_iwpriv_get_int(ifname, "ant_sel");
}
int hgic_iwpriv_set_macfilter(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "macfilter", enable);
}
int hgic_iwpriv_send_atcmd(char *ifname, char *atcmd)
{
return hgic_iwpriv_set_bytes(ifname, "atcmd", atcmd);
}
int hgic_iwpriv_set_roaming(char *ifname, int enable)
{
return hgic_iwpriv_set_int(ifname, "roaming", enable);
}
int hgic_iwpriv_set_max_txcnt(char *ifname, int txcnt)
{
return hgic_iwpriv_set_int(ifname, "max_txcnt", txcnt);
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/* proc fs api */
int hgic_proc_read_bytes(char *name, char *buff, int len)
{
char fname[32];
int ret = 0;
int fd = -1;
if (buff == NULL || len <= 0) {
return 0;
}
memset(buff, 0, len);
memset(fname, 0, sizeof(fname));
sprintf(fname, "/proc/hgic/%s", name);
fd = open(fname, O_RDONLY);
if (fd != -1) {
ret = read(fd, buff, len);
close(fd);
}
return ret;
}
int hgic_proc_read_int(char *name)
{
char buff[32];
hgic_proc_read_bytes(name, buff, 32);
return atoi(buff);
}
int hgic_proc_read_mac(char *name, char *mac)
{
char buff[32];
hgic_proc_read_bytes(name, buff, 32);
return hgic_str2mac(buff, mac);
}
int hgic_proc_write_bytes(char *name, char *buff, int len)
{
int ret = 0;
char fname[32];
int fd = -1;
if (buff == NULL || len == 0) {
return 0;
}
memset(fname, 0, sizeof(fname));
sprintf(fname, "/proc/hgic/%s", name);
fd = open(fname, O_WRONLY);
if (fd != -1) {
ret = write(fd, buff, len);
close(fd);
if(ret < 0) perror("error");
}
return ret > 0;
}
int hgic_proc_write_int(char *name, int val)
{
char buff[12];
memset(buff, 0, sizeof(buff));
sprintf(buff, "%d", val);
return hgic_proc_write_bytes(name, buff, strlen(buff));
}
int hgic_proc_write_mac(char *name, char *mac)
{
char str[18];
memset(str, 0, sizeof(str));
MAC2STR(mac, str);
return hgic_proc_write_bytes(name, str, strlen(str));
}
int hgic_proc_write_ints(char *name, int cnt, ...)
{
int i = 0;
int val = 0;
char buff[512];
char *ptr = buff;
va_list argptr;
memset(buff, 0, sizeof(buff));
va_start(argptr, cnt);
for (i = 0; i < cnt; i++) {
val = va_arg(argptr, int);
sprintf(ptr, (i==0?"%d":",%d"), val);
ptr += strlen(ptr);
}
va_end(argptr);
return hgic_proc_write_bytes(name, buff, strlen(buff));
}
int hgic_proc_write_intarray(char *name, int *values, int cnt)
{
int i = 0;
char buff[512];
char *ptr = buff;
memset(buff, 0, sizeof(buff));
for (i = 0; i < cnt; i++) {
sprintf(ptr, (i==0?"%d":",%d"), values[i]);
ptr += strlen(ptr);
}
return hgic_proc_write_bytes(name, buff, strlen(buff));
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
int hgic_proc_read_event(void)
{
return hgic_proc_read_int("event");
}
int hgic_proc_read_tx_bitrate(void)
{
return hgic_proc_read_int("tx_bitrate");
}
int hgic_proc_read_signal(void)
{
return hgic_proc_read_int("signal");
}
int hgic_proc_read_evm(void)
{
return hgic_proc_read_int("evm");
}
int hgic_proc_read_conn_state(void)
{
char state[12];
hgic_proc_read_bytes("conn_state", state, 12);
return (strstr(state, "CONNECTED") != NULL);
}
int hgic_proc_read_temperature(void)
{
return hgic_proc_read_int("temperature");
}
int hgic_proc_read_paired_stas(char *buff, int len)
{
return hgic_proc_read_bytes("paired_stas", buff, len);
}
int hgic_proc_read_sta_count(void)
{
return hgic_proc_read_int("sta_count");
}
int hgic_proc_read_wkreason(void)
{
return hgic_proc_read_int("wkreason");
}
int hgic_proc_read_customer_mgmt(char *buff, int len)
{
return hgic_proc_read_bytes("mgmt", buff, len);
}
int hgic_proc_read_fw_dbgifno(char *buff, int len)
{
return hgic_proc_read_bytes("fwdbginfo", buff, len);
}
int hgic_proc_read_firmware_ver(char *ver_str, int size)
{
return hgic_proc_read_bytes("fw_ver", ver_str, size);
}
int hgic_proc_read_battery_level(void)
{
return hgic_proc_read_int("battery_level");
}
int hgic_proc_set_heartbeat(int ipaddr, int port, int period, int timeout)
{
struct in_addr in = { .s_addr = (in_addr_t)ipaddr };
return hgic_proc_write_ints("heartbeat", 4, inet_ntoa(in), port, period, timeout);
}
int hgic_proc_set_heartbeat_resp_data(char *resp_data, int len)
{
return hgic_proc_write_bytes("heartbeat_resp", resp_data, len);
}
int hgic_proc_set_wakeup_data(char *wakeup_data, int len)
{
return hgic_proc_write_bytes("wakeup_data", wakeup_data, len);
}
int hgic_proc_wakeup_sta(char *addr)
{
return hgic_proc_write_mac("wakeup", addr);
}
int hgic_proc_sleep(int sleep)
{
return hgic_proc_write_int("sleep", sleep);
}
int hgic_proc_ota(char *fw_file)
{
return hgic_proc_write_bytes("ota", fw_file, strlen(fw_file));
}
int hgic_proc_read_pairing_sta(char *sta_mac)
{
return hgic_proc_read_mac("pairing_sta", sta_mac);
}
int hgic_proc_send_custmgmt(char *dest, struct hgic_tx_info *txinfo, char *mgmt, int len)
{
int ret = -1;
char *buf = malloc(len+sizeof(struct hgic_tx_info)+6);
if(buf){
memcpy(buf, dest, 6);
memcpy(buf+6, txinfo, sizeof(struct hgic_tx_info));
memcpy(buf+6+sizeof(struct hgic_tx_info), mgmt, len);
ret = hgic_proc_write_bytes("mgmt", buf, len+6+sizeof(struct hgic_tx_info));
free(buf);
}
return ret;
}
int hgic_proc_read_dhcpc_result(char *buff, int len)
{
return hgic_proc_read_bytes("dhcpc", buff, len);
}
int hgic_proc_read_wkdata_buff(char *buff, int len)
{
return hgic_proc_read_bytes("wkdata_buff", buff, len);
}
int hgic_proc_set_wkdata_mask(unsigned short offset, char *mask, int mask_len)
{
char buff[128];
if(mask_len > 16) mask_len = 16;
memcpy(buff, &offset, 2);
memcpy(buff+2, mask, mask_len);
return hgic_proc_write_bytes("wkdata_mask", buff, mask_len + 2);
}
int hgic_proc_read_cust_driverdata(char *buff, int len)
{
return hgic_proc_read_bytes("cust_driverdata", buff, len);
}
int hgic_proc_set_cust_driverdata(char *buff, int len)
{
if(len > 1500){
printf("data len:%d too big\r\n", len);
return -1;
}
return hgic_proc_write_bytes("cust_driverdata", buff, len);
}
int hgic_proc_set_stafreqinfo(char *sta_addr, struct hgic_freqinfo *freqinfo)
{
int ret = -1;
char *buff = malloc(6+sizeof(struct hgic_freqinfo));
if(buff){
memset(buff, 0, 6+sizeof(struct hgic_freqinfo));
if(sta_addr) memcpy(buff, sta_addr, 6);
memcpy(buff+6, freqinfo, sizeof(struct hgic_freqinfo));
ret = hgic_proc_write_bytes("freqinfo", buff, 6+sizeof(struct hgic_freqinfo));
free(buff);
}
return ret;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
#if 1 //sample code
#define IFNAME "hg0"
#define AH_STA_COUNT (8)
struct hgic_ah_sta {
unsigned char mac[6];
unsigned char used: 1, ps: 1, paired: 1, connected: 1, update:1;
unsigned char aid;
char rssi, evm;
};
struct hgic_ah_sta_mgr {
struct hgic_ah_sta stas[AH_STA_COUNT];
int count;
}ah_sta_mgr;
struct hgic_dhcp_result{
unsigned int ipaddr, netmask, svrip, router, dns1, dns2;
};
static int hgic_parse_paired_stas(struct hgic_ah_sta *stas, char *paired_stas)
{
int i = 0;
int cnt = 0;
char mac[6];
char *ptr = paired_stas;
memset(stas, 0, AH_STA_COUNT*sizeof(struct hgic_ah_sta));
if(paired_stas && stas){
cnt = strlen(paired_stas)/17;
if(cnt > AH_STA_COUNT) cnt = AH_STA_COUNT;
for(i=0; i<cnt; i++){
if(hgic_str2mac(ptr, mac)){
memcpy(stas[i].mac, mac, 6);
stas[i].paired = 1;
stas[i].used = 1;
ptr += 17;
}
}
}
return i;
}
static void hgic_parse_sta_list(struct hgic_ah_sta *stas, char *sta_list)
{
int i = 0;
int aid = 0;
int ps = 0;
int rssi = 0;
int evm = 0;
int mac[6];
char *ptr = sta_list;
char *ptr2 = NULL;
if(sta_list && stas){
memset(stas, 0, AH_STA_COUNT*sizeof(struct hgic_ah_sta));
ptr = strstr(ptr, "aid:");
while(ptr && i < AH_STA_COUNT){
ptr2 = strstr(ptr, "\r\n");
if(ptr2){
*ptr2 = 0;
ptr2 = strstr(ptr2+2, "aid:");
}
if(10 == sscanf(ptr, "aid:%d, "MACSTR", ps:%d, rssi:%d, evm:%d",
&aid, mac, mac+1, mac+2, mac+3, mac+4, mac+5, &ps, &rssi, &evm)){
stas[i].aid = aid;
stas[i].mac[0] = (unsigned char)mac[0];
stas[i].mac[1] = (unsigned char)mac[1];
stas[i].mac[2] = (unsigned char)mac[2];
stas[i].mac[3] = (unsigned char)mac[3];
stas[i].mac[4] = (unsigned char)mac[4];
stas[i].mac[5] = (unsigned char)mac[5];
stas[i].ps = atoi(ptr);
stas[i].used = 1;
stas[i].rssi = rssi;
stas[i].evm = evm;
stas[i].connected = 1;
i++;
}
ptr = ptr2;
}
}
}
struct hgic_ah_sta *hgic_find_sta(struct hgic_ah_sta *stas, unsigned char *mac)
{
int i = 0;
for(i=0; i<AH_STA_COUNT; i++){
if(MAC_EQ(stas[i].mac, mac))
return &stas[i];
}
return NULL;
}
struct hgic_ah_sta *hgic_new_sta(unsigned char *mac)
{
int i = 0;
for(i=0; i<AH_STA_COUNT; i++){
if(!ah_sta_mgr.stas[i].used){
memcpy(ah_sta_mgr.stas[i].mac, mac, 6);
ah_sta_mgr.stas[i].used = 1;
return &ah_sta_mgr.stas[i];
}
}
return NULL;
}
void hgic_update_stas(struct hgic_ah_sta *new_stas, char paired)
{
int i = 0;
struct hgic_ah_sta *sta = NULL;
for(i=0; i<AH_STA_COUNT; i++){
ah_sta_mgr.stas[i].update = 0;
if(paired){
if(new_stas[i].paired){
sta = hgic_find_sta(ah_sta_mgr.stas, new_stas[i].mac);
if(sta == NULL){
sta = hgic_new_sta(new_stas[i].mac);
}
if(sta){
sta->paired = 1;
sta->update = 1;
sta->used = 1;
}
}
}
else {
if(new_stas[i].connected){
sta = hgic_find_sta(ah_sta_mgr.stas, new_stas[i].mac);
if(sta == NULL){
sta = hgic_new_sta(new_stas[i].mac);
}
if(sta){
sta->ps = new_stas[i].ps;
sta->rssi = new_stas[i].rssi;
sta->evm = new_stas[i].evm;
sta->aid = new_stas[i].aid;
sta->connected = 1;
sta->update = 1;
sta->used = 1;
}
}
}
}
for(i=0; i<AH_STA_COUNT; i++){
if(paired){
if(ah_sta_mgr.stas[i].paired && !ah_sta_mgr.stas[i].update){
memset(&ah_sta_mgr.stas[i], 0, sizeof(struct hgic_ah_sta));
}
}else if(!ah_sta_mgr.stas[i].update){
if(ah_sta_mgr.stas[i].paired){
ah_sta_mgr.stas[i].connected = 0;
}else{
memset(&ah_sta_mgr.stas[i], 0, sizeof(struct hgic_ah_sta));
}
}
ah_sta_mgr.stas[i].update = 1;
}
}
void hgic_dump_stas()
{
int i = 0;
printf("sta_list:\r\n");
for(i=0; i<AH_STA_COUNT; i++){
if(ah_sta_mgr.stas[i].used){
printf("sta%d:"MACSTR", ps:%d, rssi:%d, evm:%d\r\n",
ah_sta_mgr.stas[i].aid, MACARG(ah_sta_mgr.stas[i].mac),
ah_sta_mgr.stas[i].ps, ah_sta_mgr.stas[i].rssi, ah_sta_mgr.stas[i].evm);
}
}
}
static void hgic_test_read_wakeupdata()
{
int i = 0;
char *buff = malloc(4096);
do{
i = hgic_proc_read_wkdata_buff(buff, 4096);
if(i > 0){
buff[i] = 0;
printf("get wkdata, len:%d, %s\r\n", i, buff+42);
}
}while(i>0);
free(buff);
}
int hgic_event_proc(int event)
{
int i = 0;
struct hgic_dhcp_result result;
struct hgic_ah_sta *sta = NULL;
struct hgic_ah_sta tmpstas[AH_STA_COUNT];
char *buff = malloc(4096);
switch (event) {
case 5: /*HGIC_EVENT_SCANNING*/
fmac_dbg("start scan ...\r\n");
break;
case 6: /*HGIC_EVENT_SCAN_DONE*/
fmac_dbg("scan done!\r\n");
hgic_iwpriv_get_scan_list(IFNAME, buff, 4096);
if(buff) printf("%s\r\n", buff);
break;
case 7: /*HGIC_EVENT_TX_BITRATE*/
fmac_dbg("estimate tx bitrate:%dKbps\r\n", hgic_proc_read_tx_bitrate());
break;
case 8: /*HGIC_EVENT_PAIR_START*/
fmac_dbg("start pairing ...\r\n");
break;
case 9: /*HGIC_EVENT_PAIR_SUCCESS*/
hgic_proc_read_pairing_sta(buff);
fmac_dbg("pairing success! ["MACSTR"]\r\n", MACARG(buff));
hgic_iwpriv_set_pairing(IFNAME, 0); //stop pair
break;
case 10: /*HGIC_EVENT_PAIR_DONE*/
fmac_dbg("pairing done!\r\n");
hgic_proc_read_paired_stas(buff, 4096);
hgic_parse_paired_stas(tmpstas, buff);
for(i=0; i<AH_STA_COUNT; i++){
if(tmpstas[i].used && tmpstas[i].paired){
sta = hgic_find_sta(ah_sta_mgr.stas, tmpstas[i].mac);
if(sta == NULL || !sta->paired){
printf("new sta paired! "MACSTR"\r\n", MACARG(tmpstas[i].mac));
}
}
}
hgic_update_stas(tmpstas, 1);
break;
case 11: /*HGIC_EVENT_CONECT_START*/
fmac_dbg("start connecting ...\r\n");
break;
case 12: /*HGIC_EVENT_CONECTED*/
fmac_dbg("connected!\r\n");
hgic_iwpriv_get_sta_list(IFNAME, buff, 4096);
hgic_parse_sta_list(tmpstas, buff);
for(i=0; i<AH_STA_COUNT; i++){
if(tmpstas[i].used && tmpstas[i].connected){
sta = hgic_find_sta(ah_sta_mgr.stas, tmpstas[i].mac);
if(sta == NULL || !sta->connected){
printf("new sta connected! "MACSTR"\r\n", MACARG(tmpstas[i].mac));
}
}
}
hgic_update_stas(tmpstas, 0);
hgic_test_read_wakeupdata();
break;
case 13: /*HGIC_EVENT_DISCONECTED*/
fmac_dbg("disconnected!\r\n");
hgic_iwpriv_get_sta_list(IFNAME, buff, 4096);
hgic_parse_sta_list(tmpstas, buff);
for(i=0;i<AH_STA_COUNT;i++){
if(ah_sta_mgr.stas[i].used && ah_sta_mgr.stas[i].connected){
sta = hgic_find_sta(tmpstas, ah_sta_mgr.stas[i].mac);
if(sta == NULL || !sta->connected){
printf("sta disconnected! "MACSTR"\r\n", MACARG(ah_sta_mgr.stas[i].mac));
}
}
}
hgic_update_stas(tmpstas, 0);
break;
case 14: /*HGIC_EVENT_SIGNAL*/
fmac_dbg("signal changed: rssi:%d, evm:%d\r\n", hgic_proc_read_signal(), hgic_proc_read_event());
break;
case 18: /*HGIC_EVENT_FWDBG_INFO*/
hgic_proc_read_fw_dbgifno(buff, 4096);
if(buff) printf("%s", buff);
break;
case 19: /*HGIC_EVENT_CUSTOMER_MGMT*/
i = hgic_proc_read_customer_mgmt(buff, 4096);
fmac_dbg("rx customer mgmt frame from "MACSTR", %d bytes \r\n", MACARG(buff+6), i-6);
break;
case 21: /*HGIC_EVENT_DHCPC_DONE*/
hgic_proc_read_dhcpc_result((char *)&result, sizeof(result));
fmac_dbg("fw dhcpc result: ipaddr:"IPSTR", netmask:"IPSTR", svrip:"IPSTR", router:"IPSTR", dns:"IPSTR"/"IPSTR"\r\n",
IPARG(result.ipaddr), IPARG(result.netmask), IPARG(result.svrip),
IPARG(result.router), IPARG(result.dns1), IPARG(result.dns2));
break;
case 22: /*HGIC_EVENT_CONNECT_FAIL*/
fmac_dbg("connect fail, reason:%d\r\n", hgic_iwpriv_get_disassoc_reason(IFNAME));
break;
case 23: /*HGIC_EVENT_CUST_DRIVER_DATA*/
fmac_dbg("rx customer driver data %d bytes\r\n", hgic_proc_read_cust_driverdata(buff, 1024));
break;
case 24: /*HGIC_EVENT_UNPAIR_STA*/
fmac_dbg("unpair\r\n");
break;
}
if (buff) { free(buff); }
}
int main(int argc, char *argv[])
{
int event = 0;
char mask[4] = { 0x3, 0xff, 0x0f, 0xff};
char dest[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct hgic_tx_info txinfo;
struct hgic_module_hwinfo hwinfo;
struct hgic_freqinfo freqinfo={
.bss_bw = 8,
.chan_cnt = 3,
.chan_list = {9080, 9160, 9240},
};
char *custmgmt = "this is customer mgmt data";
hwinfo.v = hgic_iwpriv_get_module_type("hg0");
printf("Module HW info: type:%d, %s\r\n", hwinfo.type, hwinfo.saw?"SAW":"NO SAW");
/*test: send customer mgmt frame.*/
memset(&txinfo, 0, sizeof(txinfo));
txinfo.tx_mcs = 0xff; //auto mcs
txinfo.freq_idx = 1; //tx at channel 1
hgic_proc_send_custmgmt(dest, &txinfo, custmgmt, strlen(custmgmt));
txinfo.freq_idx = 2; //tx at channel 2
hgic_proc_send_custmgmt(dest, &txinfo, custmgmt, strlen(custmgmt));
txinfo.freq_idx = 3; //tx at channel 3
hgic_proc_send_custmgmt(dest, &txinfo, custmgmt, strlen(custmgmt));
/*test: enable dhcp client function in firmware.*/
hgic_iwpriv_set_dhcpc("hg0", 1);
/*test: set wakedata match mask*/
hgic_proc_set_wkdata_mask(42, mask, 4);
/*test: enable firmware save wakeup data.*/
hgic_iwpriv_set_wkdata_save("hg0", 1);
/*test: get current bssid (for sta mode)*/
hgic_iwpriv_get_bssid("hg0", dest);
printf("current bssid:"MACSTR"\r\n", MACARG(dest));
/*test: set remote AP's freqency info.*/
hgic_proc_set_stafreqinfo(dest, &freqinfo);
/*test: reset remote AP.*/
hgic_iwpriv_reset_sta("hg0", dest);
/*test: read wakeup data from firmware.*/
hgic_test_read_wakeupdata();
/*loop read driver event and proc event.*/
while (1) {
event = hgic_proc_read_event();
if(event){
hgic_event_proc(event);
}
}
}
#endif