349 lines
9.9 KiB
C
349 lines
9.9 KiB
C
#include <error.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <linux/if.h>
|
|
#include <linux/if_packet.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/if_ether.h>
|
|
#include "libota.h"
|
|
|
|
struct hgicOTA {
|
|
uint8 rxbuf[2048];
|
|
uint8 mac_addr[6];
|
|
int sock;
|
|
int if_index;
|
|
} hgOTA;
|
|
|
|
|
|
static void hgic_show_device(void)
|
|
{
|
|
int i = 0;
|
|
printf("\r\n------------------------------------------------------------------\r\n");
|
|
for (i = 0; i < OTA_STA_COUNT; i++) {
|
|
if (LIBOTA.stas[i].online) {
|
|
printf("| "MACSTR", chipid:%x, version:%d.%d.%d.%d-%d |\r\n",
|
|
MAC2STR(LIBOTA.stas[i].addr),
|
|
LIBOTA.stas[i].chipid,
|
|
(LIBOTA.stas[i].version >> 24) & 0xff,
|
|
(LIBOTA.stas[i].version >> 16) & 0xff,
|
|
(LIBOTA.stas[i].version >> 8) & 0xff,
|
|
(LIBOTA.stas[i].version) & 0xff,
|
|
LIBOTA.stas[i].svn_version);
|
|
}
|
|
}
|
|
printf("------------------------------------------------------------------\r\n");
|
|
}
|
|
|
|
static struct hgota_sta *hgic_get_device(u8 *addr)
|
|
{
|
|
int i = 0;
|
|
for (i = 0; i < OTA_STA_COUNT; i++) {
|
|
if (memcmp(LIBOTA.stas[i].addr, addr, 6) ==0) {
|
|
return &LIBOTA.stas[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static void hgic_save_device(void)
|
|
{
|
|
FILE *fp = fopen("/tmp/hgota.tmp", "w+");
|
|
if (fp) {
|
|
fwrite(LIBOTA.stas, 1, sizeof(LIBOTA.stas), fp);
|
|
fclose(fp);
|
|
printf("save scan result into /tmp/hgota.tmp\r\n");
|
|
}
|
|
}
|
|
|
|
static void hgic_read_device(void)
|
|
{
|
|
int i = 0;
|
|
|
|
FILE *fp = fopen("/tmp/hgota.tmp", "r");
|
|
if (fp) {
|
|
fread(LIBOTA.stas, 1, sizeof(LIBOTA.stas), fp);
|
|
fclose(fp);
|
|
printf("load device info from /tmp/hgota.tmp\r\n");
|
|
hgic_show_device();
|
|
}
|
|
}
|
|
|
|
static int hgic_sock_init(char *ifname)
|
|
{
|
|
int ret = 0;
|
|
struct ifreq req;
|
|
|
|
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
|
if (sock == -1) {
|
|
goto __fail;
|
|
}
|
|
memset(&req, 0, sizeof(struct ifreq));
|
|
strncpy(req.ifr_name, ifname, strlen(ifname));
|
|
ret = ioctl(sock, SIOCGIFINDEX, &req);
|
|
if (sock == -1) {
|
|
goto __fail;
|
|
}
|
|
hgOTA.if_index = req.ifr_ifindex;
|
|
|
|
ret = ioctl(sock, SIOCGIFHWADDR, &req);
|
|
if (sock == -1) {
|
|
goto __fail;
|
|
}
|
|
memcpy(hgOTA.mac_addr, req.ifr_hwaddr.sa_data, 6);
|
|
close(sock);
|
|
|
|
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_OTA));
|
|
hgOTA.sock = sock;
|
|
//printf("%d, %s: "MACSTR"\r\n", hgOTA.if_index, ifname, MAC2STR(hgOTA.mac_addr));
|
|
return (sock != -1);
|
|
__fail:
|
|
if (sock != -1) {
|
|
close(sock);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int hgic_sock_recv(int tmo)
|
|
{
|
|
int ret = 0;
|
|
int recv_len = 0;
|
|
fd_set rfd;
|
|
struct timeval timeout;
|
|
|
|
FD_ZERO(&rfd);
|
|
FD_SET(hgOTA.sock, &rfd);
|
|
timeout.tv_sec = tmo / 1000;
|
|
timeout.tv_usec = (tmo % 1000) * 1000;
|
|
ret = select(hgOTA.sock + 1, &rfd, NULL, NULL, &timeout);
|
|
if (ret > 0 && FD_ISSET(hgOTA.sock, &rfd)) {
|
|
recv_len = recvfrom(hgOTA.sock, hgOTA.rxbuf, 2048, 0, NULL, NULL);
|
|
}
|
|
return (recv_len);
|
|
}
|
|
|
|
int raw_sock_send(char *data, int len)
|
|
{
|
|
struct sockaddr_ll dest;
|
|
memset(&dest, 0, sizeof(struct sockaddr_ll));
|
|
dest.sll_family = AF_PACKET;
|
|
dest.sll_protocol = htons(ETH_P_OTA);
|
|
dest.sll_ifindex = hgOTA.if_index;
|
|
dest.sll_pkttype = PACKET_OUTGOING;
|
|
dest.sll_halen = 6;
|
|
memcpy(dest.sll_addr, data, 6);
|
|
memcpy(data + 6, hgOTA.mac_addr, 6);
|
|
return sendto(hgOTA.sock, data, len, 0, (const struct sockaddr *)&dest, sizeof(struct sockaddr_ll));
|
|
}
|
|
|
|
void hgic_scan_device(void)
|
|
{
|
|
int i = 0;
|
|
int recv_len = 0;
|
|
FILE *fp = NULL;
|
|
|
|
libota_scan(1);
|
|
while (i++ < 10) {
|
|
if ((i & 0xf) == 0) { libota_scan(0); }
|
|
recv_len = hgic_sock_recv(50);
|
|
if (recv_len > 0) {
|
|
libota_rx_proc(hgOTA.rxbuf, recv_len);
|
|
}
|
|
}
|
|
hgic_save_device();
|
|
printf("OTA SCAN:%d devices:\r\n", LIBOTA.sta_count);
|
|
hgic_show_device();
|
|
}
|
|
|
|
void hgic_reboot_device(char *addr)
|
|
{
|
|
uint8 mac[6];
|
|
printf("reboot sta %s\r\n", addr);
|
|
if (6 == sscanf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5)) {
|
|
libota_reboot(mac, 0);
|
|
}
|
|
}
|
|
|
|
void hgic_loaddef_device(char *addr)
|
|
{
|
|
uint8 mac[6];
|
|
|
|
printf("load default sta %s config\r\n", addr);
|
|
if (6 == sscanf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5)) {
|
|
libota_reboot(mac, ETH_P_REBOOT_FLAGS_LOADDEF);
|
|
}
|
|
}
|
|
|
|
static uint8 *hgic_read_firmware(char *path, struct hgota_fw_info *fwinfo)
|
|
{
|
|
int err = 0;
|
|
uint32 file_len = 0;
|
|
uint8 *fwdata = NULL;
|
|
uint32 rlen = 0;
|
|
FILE *fp = fopen(path, "r");
|
|
|
|
if (fp) {
|
|
fseek(fp, 0, SEEK_END);
|
|
file_len = ftell(fp);
|
|
fseek(fp, 0, SEEK_SET);
|
|
fwdata = malloc(file_len);
|
|
if (fwdata) {
|
|
rlen = fread(fwdata, 1, file_len, fp);
|
|
}
|
|
fclose(fp);
|
|
|
|
if (file_len == rlen && fwdata) {
|
|
fwinfo->chipid = fwinfo_get_fw_chipid(fwdata, &err);
|
|
fwinfo->tot_len = fwinfo_get_fw_length(fwdata, &err);
|
|
fwinfo->version = fwinfo_get_fw_sdk_version(fwdata, &err);
|
|
fwinfo->svn_version = fwinfo_get_fw_svn_version(fwdata, &err);
|
|
if (!fwinfo_get_fw_code_checksum(fwdata, fwinfo->tot_len)) {
|
|
printf("firmware Info:\r\n");
|
|
printf(" chipid:%x\r\n", fwinfo->chipid);
|
|
printf(" version:%d.%d.%d.%d-%d\r\n", (fwinfo->version >> 24) & 0xff,
|
|
(fwinfo->version >> 16) & 0xff,
|
|
(fwinfo->version >> 8) & 0xff,
|
|
(fwinfo->version) & 0xff,
|
|
fwinfo->svn_version);
|
|
printf(" size:%d\r\n", fwinfo->tot_len);
|
|
return fwdata;
|
|
}
|
|
}
|
|
printf("invalid firmware\r\n");
|
|
} else {
|
|
printf("open file %s fail\r\n", path);
|
|
}
|
|
if (fwdata) {
|
|
free(fwdata);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void hgic_ota_device(char *addr, char *fw)
|
|
{
|
|
uint8 mac[6];
|
|
uint32 ota_off = 0;
|
|
uint8 *fwdata = NULL;
|
|
uint32 rx_len = 0;
|
|
uint32 err = 0;
|
|
int32 retry = 0;
|
|
struct hgota_fw_info fwinfo;
|
|
struct hgota_sta *sta = NULL;
|
|
|
|
printf("ota sta %s, fw:%s\r\n", addr, fw);
|
|
memset(&fwinfo, 0, sizeof(fwinfo));
|
|
if (6 == sscanf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5)) {
|
|
sta = hgic_get_device(mac);
|
|
fwdata = hgic_read_firmware(fw, &fwinfo);
|
|
if (fwdata) {
|
|
if(sta && sta->svn_version == fwinfo.svn_version){
|
|
printf("same version, do not OTA\r\n");
|
|
return;
|
|
}
|
|
while (ota_off < fwinfo.tot_len && retry < 10) {
|
|
libota_send_fw_data(mac, &fwinfo, ota_off, fwdata + ota_off,
|
|
(fwinfo.tot_len - ota_off) > 1460 ? 1460 : (fwinfo.tot_len - ota_off));
|
|
rx_len = hgic_sock_recv(500);
|
|
if (rx_len > 0 && (libota_rx_proc(hgOTA.rxbuf, rx_len) == HGOTA_STATUS_FW_STATUS)) {
|
|
retry = 0;
|
|
} else {
|
|
retry++;
|
|
}
|
|
ota_off = libota_sta_nexoff(mac);
|
|
printf("OTA: %d%%\r", (ota_off * 100) / fwinfo.tot_len);
|
|
fflush(stdout);
|
|
}
|
|
free(fwdata);
|
|
}
|
|
}
|
|
printf("\r\n");
|
|
if (fwinfo.tot_len > 0) {
|
|
printf("OTA Exit: %d%% upgraded\r\n", (ota_off * 100) / fwinfo.tot_len);
|
|
}
|
|
}
|
|
|
|
void hgic_get_config(char *addr)
|
|
{
|
|
int i = 0;
|
|
char mac[6];
|
|
uint32 rx_len = 0;
|
|
struct eth_ota_fwparam param;
|
|
|
|
if (6 == sscanf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5)) {
|
|
libota_query_config(mac);
|
|
rx_len = hgic_sock_recv(500);
|
|
if (rx_len > 0) {
|
|
if (HGOTA_STATUS_CONFIG_GOT == libota_rx_proc(hgOTA.rxbuf, rx_len)) {
|
|
libota_sta_config(mac, ¶m);
|
|
printf("BSS BW :%d\r\n", param.bss_bw);
|
|
printf("TX MCS :%d\r\n", param.tx_mcs);
|
|
printf("ENCRYPT:%d\r\n", param.encrypt);
|
|
printf("FORWARD:%d\r\n", param.forward);
|
|
printf("SSID :%s\r\n", param.ssid);
|
|
printf("KEY_SET:%d\r\n", param.key_set);
|
|
printf("MACST_KEY_SET:%d\r\n", param.mkey_set);
|
|
printf("FREQ RANGE:%d - %d\r\n", param.freq_start, param.freq_end);
|
|
printf("CHAN LIST:");
|
|
for (i = 0; i < param.chan_cnt; i++) {
|
|
if (param.chan_list[0]) { printf("%d ", param.chan_list[0]); }
|
|
}
|
|
printf("\r\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char *ifname;
|
|
char *cmd;
|
|
FILE *fp = NULL;
|
|
|
|
if (argc < 3) {
|
|
printf("invalid params\r\n hgota ifname cmd [args]\r\n");
|
|
return -1;
|
|
}
|
|
ifname = argv[1];
|
|
cmd = argv[2];
|
|
|
|
libota_init(raw_sock_send);
|
|
hgic_read_device();
|
|
|
|
if (!hgic_sock_init(ifname)) {
|
|
printf("create socket fail\r\n");
|
|
return -1;
|
|
}
|
|
|
|
if (strcmp(cmd, "SCAN") == 0) {
|
|
hgic_scan_device();
|
|
} else if (strcmp(cmd, "REBOOT") == 0) {
|
|
if (argc == 3 + 1) {
|
|
hgic_reboot_device(argv[3]);
|
|
}
|
|
} else if (strcmp(cmd, "LDDEF") == 0) {
|
|
if (argc == 3 + 1) {
|
|
hgic_loaddef_device(argv[3]);
|
|
}
|
|
} else if (strcmp(cmd, "OTA") == 0) {
|
|
if (argc == 3 + 2) {
|
|
hgic_ota_device(argv[3], argv[4]);
|
|
}
|
|
} else if (strcmp(cmd, "GETCFG") == 0) {
|
|
if (argc == 3 + 1) {
|
|
hgic_get_config(argv[3]);
|
|
}
|
|
}
|
|
close(hgOTA.sock);
|
|
return 0;
|
|
}
|
|
|