#include
#include
#include
#include
#include
#include
#include
#include
#define BOARD_ID_MAX_LEN 2
#define MAC_MAX_LEN 6
#define FACTORY_MAX_LEN32
#define FACTORY_SIZE0x10000
#define BOARD_TYPE_OFFSET0
#define WIFI_MAC_OFFSET 4
#define ETH0_1_MAC_OFFSET 46
#define ETH0_2_MAC_OFFSET 40
#define FACTORY_OFFSET12
#define FACTORY_MTD_RD "/dev/mtdblock2"
#define FACTORY_MTD_WR "/dev/mtd2"
unsigned char *char2hex(unsigned char *ret,unsigned char c)
{
if(c<='9' && c>='0') *ret=c-'0';
else if(c<='F' && c>='A') *ret=c-'A'+0x0a;
else if(c<='f' && c>='a') *ret=c-'a'+0x0a;
else *ret=0xff;
return ret;
}
unsigned char *str2hex(unsigned char *dest,const char *src,unsigned short int length)
{
unsigned short int i;
unsigned char c;
for(i=0;i
char2hex(&c,src[i]);
if(i%2) dest[((i+1)/2+(i+1)%2)-1]|=c;
else dest[((i+1)/2+(i+1)%2)-1]=c<<4;
}
return dest;
}
void byte_reversed(unsigned short int *val)
{
*((unsigned char*)val) ^= *((unsigned char*)val+1);
*((unsigned char*)val+1) ^= *((unsigned char*)val);
*((unsigned char*)val) ^= *((unsigned char*)val+1);
}
int mtd_write_data(unsigned char *mtd, unsigned char *filebuf, unsigned long file_len)
{
int mtd_fd = -1;
mtd_info_t mtd_info;
erase_info_t erase_info;
unsigned char *buf = filebuf;
long count;
int ret = -1;
printf("%s: mtd='%s', len='%lu'\n", __FUNCTION__, mtd, file_len);
/* 打开mtd设备,获取mtd设备信息 */
if ((mtd_fd = open(mtd, O_RDWR)) < 0 || ioctl(mtd_fd, MEMGETINFO, &mtd_info) != 0){
perror(mtd);
goto fail;
}
erase_info.length = mtd_info.erasesize;
count = file_len < (mtd_info.erasesize)?file_len:(mtd_info.erasesize);
/* 写数据到mtd设备*/
for (erase_info.start = 0; erase_info.start < file_len; erase_info.start += count){
printf("Writing block 0x%x, count=0x%x\n", erase_info.start, count);
/*解锁mtd设备*/
(void) ioctl(mtd_fd, MEMUNLOCK, &erase_info);
/*擦除mtd设备和写数据到mtd设备*/
if (ioctl(mtd_fd, MEMERASE, &erase_info) != 0 || write(mtd_fd, buf, count) != count){
perror(mtd);
goto fail;
}
buf += count;
}
ret = 0;
fail:
if (buf) {
unsigned char temp[10];
/* 读MTD设备使能其处于非 锁定/挂起 的状态 */
(void) read(mtd_fd, temp, sizeof(temp));
}
if (mtd_fd >= 0)
close(mtd_fd);
return ret;
}
int mtd_read_data(unsigned char *mtd,int mtd_size,unsigned char *buf)
{
int mtd_fd;
unsigned char *mtd_buf;
mtd_fd = open(mtd, O_RDONLY);
if (mtd_fd < 0){
perror("open");
return -1;
}
/* 映射分区 */
mtd_buf = mmap(NULL, mtd_size, PROT_READ, MAP_SHARED, mtd_fd, 0);
if (mtd_buf < (unsigned char *) 0){
perror("mmap");
close(mtd_fd);
return -1;
}
/* 拷贝数据到用户buf */
memcpy(buf, mtd_buf, mtd_size);
munmap(mtd_buf, mtd_size);
close(mtd_fd);
return 0;
}
int mt76x8_read_board_type(unsigned char *board_type,int len)
{
unsigned char buf[FACTORY_SIZE];
if(NULL == board_type){
return -1;
}
if(mtd_read_data(FACTORY_MTD_RD,FACTORY_SIZE,buf))
return -1;
memcpy(board_type, &buf[BOARD_TYPE_OFFSET], len);
return 0;
}
int mt76x8_write_board_type(unsigned char *board_type)
{
unsigned char buf[FACTORY_SIZE];
if(NULL == board_type){
return -1;
}
printf("write board id %s\n", board_type);
if(mtd_read_data(FACTORY_MTD_RD,FACTORY_SIZE,buf))
return -1;
unsigned short int tmp=0xFFFF;
str2hex((unsigned char*)&tmp,board_type,4);
byte_reversed(&tmp);
memcpy(&buf[BOARD_TYPE_OFFSET], &tmp, BOARD_ID_MAX_LEN);
return mtd_write_data(FACTORY_MTD_WR,buf,FACTORY_SIZE);
}
/*板子上有一个lan,一个wan,一个wifi。lanmac偏移ETH0_1_MAC_OFFSET;wanmac偏移ETH0_2_MAC_OFFSET;wifimac偏移WIFI_MAC_OFFSET*/
int mt76x8_read_mac(char *mac_class,unsigned char *mac,int len)
{
unsigned char buf[FACTORY_SIZE];
if(NULL == mac_class || NULL == mac){
return -1;
}
if(mtd_read_data(FACTORY_MTD_RD,FACTORY_SIZE,buf))
return -1;
if(!strcmp("lanmac",mac_class)){
memcpy(mac, &buf[ETH0_1_MAC_OFFSET],len);
}else if(!strcmp("wanmac",mac_class)){
memcpy(mac, &buf[ETH0_1_MAC_OFFSET],len);
}else if(!strcmp("wifimac",mac_class)){
memcpy(mac, &buf[WIFI_MAC_OFFSET],len);
}else{
return -1;
}
return 0;
}
int mt76x8_write_mac(char *mac_class,unsigned char *mac)
{
unsigned char buf[FACTORY_SIZE];
if(NULL == mac_class || NULL == mac){
return -1;
}
printf("write mac %s\n", mac);
if(mtd_read_data(FACTORY_MTD_RD,FACTORY_SIZE,buf))
return -1;
unsigned char tmp[MAC_MAX_LEN]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
str2hex(tmp,mac,MAC_MAX_LEN*2);
//for(int i=0;i
//byte_reversed((unsigned short int*)&tmp[i*2]);
//}
if(!strcmp("lanmac",mac_class)){
memcpy(&buf[ETH0_1_MAC_OFFSET],tmp,MAC_MAX_LEN);
}else if(!strcmp("wanmac",mac_class)){
memcpy(&buf[ETH0_1_MAC_OFFSET],tmp,MAC_MAX_LEN);
}else if(!strcmp("wifimac",mac_class)){
memcpy(&buf[WIFI_MAC_OFFSET],tmp,MAC_MAX_LEN);
}else{
return -1;
}
return mtd_write_data(FACTORY_MTD_WR,buf,FACTORY_SIZE);
}
int main(int argc,char **argv)
{
if(argc < 3){
return -1;
}
unsigned char mac[6]={0};
if(!strcmp("read",argv[1])){
mt76x8_read_mac(argv[2],mac,6);
for(int i=0;i<6;i++){
printf("%02x",mac[i]);
}
printf("\n");
}
if(!strcmp("write",argv[1])){
mt76x8_write_mac(argv[2],argv[3]);
}
#if 0
unsigned char type[2]={0};
mt76x8_read_board_type(type,2);
byte_reversed(type);
printf("%02x%02x\n",type[0],type[1]);
#endif
return 0;
}