TRC 630401

auxfunc.cpp

Committer:
supawat
Date:
2020-04-02
Revision:
0:a140efde67cf

File content as of revision 0:a140efde67cf:

//#include "mbed.h"
#include "U201SARA.h"
#include "auxfunc.h"
#include "vms.h"
#include "at45db161e.h"
#include "EEPROM.h"
#include "global_variable.h"

extern Serial pc;
extern U201SARA modem;

extern ATD45DB161E eflash;

extern EEPROM eeprom;

//volatile bool mready=false;
volatile bool bconfig=false;
volatile bool bactive=false;
volatile bool b_ftpstate=false;
volatile bool bgetfile=false;
volatile bool bchgdir=false;
volatile int lst_frmblock=-1;

char locBIN_fname[]="firmware.bin\0";
char insTXT_fname[]="Instruction_vms.txt\0";

int num_pfrm=0;
int size_lstf=0;

//char *rdbuf_block=(char*)malloc(4096*sizeof(char));
char rdbuf_block[4096];

//char json_instruction[]= {"BEGIN:\nFirmware version: \"%d\"\nDevice: \"%16[^\"]\"\nDirectory: \"%19[^\"]\"\nLast file size: \"%d\"\nChecksum: \"%400[^\"]\"\nFile name: \"%29[^\"]\"\nEND:"};
//char json_instruction[]= {"%*s\nFirmware version: \"%d\"\nDevice: \"%16[^\"]\"\nDirectory: \"%19[^\"]\"\nLast file size: \"%d\"\nChecksum: \"%400[^\"]\"\nFile name: \"%29[^\"]\"\n%*s"};
char json_instruction[]= {"%*s\nFirmware version: \"%d\"\nDevice: \"%[^\"]\"\nDirectory: \"%[^\"]\"\nLast file size: \"%d\"\nChecksum: \"%[^\"]\"\nFile name: \"%[^.]\"\n%*s"};

extern json_ota myota;
extern vms_stat *_mystat;
extern ota_flag flag_fw;

// >>> Bootloader Programmer

__asm void bootValidApp()
{
	
		LDR R0, = 0xE000ED08            //  Load SCB->VTOR address into R0
    LDR R1, = Bootloader_address    //  Load Bootloader_address into R1
    STR R1, [R0]                    //  Store value of R0 into value of R1
    LDR R0, [R1]                    //  Load R1 into R0
    MOV SP, R0                      //  Copy the value of R0 into SP
    NOP                             //  No operation
    LDR R0, [R1, #4]                //  Load sum of R1 and #4 into R0
    BX R0 
	
}

void jump_bootloader(void){
    uint32_t tmp = LPC_FLASHCTRL->FLASHCFG & (~(0x3));
    uint32_t pdrun;
   
    LPC_SYSCON->MAINCLKSEL  = 0x00;
    LPC_SYSCON->MAINCLKUEN  = 0;
    LPC_SYSCON->MAINCLKUEN  = 1;
    
    LPC_FLASHCTRL->FLASHCFG = tmp & 0xFFFFFFFC;
    
    pdrun = LPC_SYSCON->PDRUNCFG & 0x000025FF;
    pdrun |= ((1 << 7) & 0x000025FF);

    LPC_SYSCON->PDRUNCFG = (pdrun | 0x0000C800);
    bootValidApp();
}

//Bootloader Programmer <<<

bool chkgrant_upgradeFW(int vers,char *device){
		pc.printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n");
		bool bfw_vers=false;
		bool b_device=false;
		
		if(vers-atoi(FW_NO)>0){
				bfw_vers=true;
				pc.printf("my firmware [%d] is out to date : Having new firmware [%d]\r\n",atoi(FW_NO),vers);
		}
		
		if(strcmp(device,"ALL")==0){
				b_device=true;
				pc.printf("device : ALL	---> I having grant Device!!!\r\n");
		}else if(strcmp(device,DEV_GROUP)==0){
				b_device=true;
				pc.printf("device group : %s	---> I having grant Device!!!\r\n",DEV_GROUP);
		}else if(strcmp(device,_mystat->id)==0){
				b_device=true;
				pc.printf("device : %s	---> I having grant Device!!!\r\n",_mystat->id);
		}else{
				b_device=false;
				pc.printf("device : %s ---> I don't having grant Device!!!\r\n",device);
		}
		pc.printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\r\n");
		
	return (bfw_vers&&b_device);
}

//void eflash_block(char *data,int block){
//    int st_addr=block<<12;
//        eflash.ContinuousWriteThroughBuffer(st_addr, WRITE_BUFFER ,(unsigned char*)data,4096);
//}

void eflash_block(char data[],int block){
    int st_addr=block<<12;
        //eflash.ContinuousWriteThroughBuffer(st_addr, WRITE_BUFFER ,(unsigned char*)data,4096);
		eflash.ContinuousWriteThroughBuffer(st_addr, WRITE_BUFFER ,(unsigned char*)data,4096);
}
 
void eflash_eraseBlock(int block){
    int start_page=block<<3;
        for(int i=0;i<8;i++){
            eflash.PageErase(start_page+i);
        }
}

bool check_ota()
{
    pc.printf("check OTA\r\n");

    myota.firm_vers=0;
    strcpy(myota.device,"\0");
    strcpy(myota.dir,"\0");
    myota.fsize=0;
    //myota.chksum=0;
    strcpy(myota.filename,"\0");

    // if(bpsd) {
    bconfig=modem.configFTP(srv_IP,usr,pwd,ota_ftpPort);
    // }

    if(bconfig) {
        bactive=modem.activateFTP(1);
        if(bactive) {
            b_ftpstate=true;
        }
        bactive=false;
    }

    if(b_ftpstate) {
        bchgdir=modem.changedirFTP("/");
        if(bchgdir) {
            //bgetfile=modem.getFTP("Instruction_vms.txt","Instruction_vms.txt");
						bgetfile=modem.getFTP(insTXT_fname,insTXT_fname);
        }

        if(bgetfile) {
            bactive=modem.activateFTP(0);
            if(bactive) {
                b_ftpstate=false;

                bconfig=false;
                bactive=false;
                b_ftpstate=false;
                //bgetfile=false;
                bchgdir=false;
            }

            bactive=false;
        }
        bool format_found=false;
        if(bgetfile) {
            bgetfile=false;
            format_found=readFS_ota();
        }

        if(format_found) {
            format_found=false;
            pc.printf("device FW %d\r\n",atoi(FW_NO));
						if(chkgrant_upgradeFW(myota.firm_vers,myota.device)){
            //if(myota.firm_vers-atoi(FW_NO)>0) {
                pc.printf("device need firmware upgrading\r\n");
                return true;
            }else{
								pc.printf("device firmware is up to date\r\n");
						}
        }

    }
    return false;
}

bool readFS_ota()
{
    //char fname[]="Instruction_vms.txt";
    int nlst=-1;
    nlst=modem.lstFS(insTXT_fname);
		//char *rdbuf_block2=(char*)malloc()
		char rdbuf_block2[nlst+1];
 
    if(nlst>0) 
			{
						//rdbuf_block=(char*)realloc(rdbuf_block,nlst);
				
						//memset(rdbuf_block,0xff,nlst);
						//memset(rdbuf_block,0xff,4096);
				
						memset(rdbuf_block2,0,nlst+1);
				
						//rcv=modem.rdBlockFS(fname,0,nlst);
						modem.rdBlockFS(insTXT_fname,rdbuf_block2,0,nlst);
						//rdbuf_block[nlst]='\0';
						//rdbuf_block=modem.rdBlockFS(fname,0,nlst);
						pc.printf("msg---------------------->\r\n");

						//modem.printHex(rcv,nlst);

						memset(myota.device,0,15);
						memset(myota.dir,0,20);
						memset(myota.filename,0,30);
						char fname[30];

						char crc_str[400];
						memset(crc_str,0,400);
						//sscanf(rcv,json_instruction,&myota.firm_vers,myota.device,myota.dir,&myota.fsize,&myota.chksum,myota.filename);
						//sscanf(rdbuf_block,json_instruction,&myota.firm_vers,myota.device,myota.dir,&myota.fsize,&myota.chksum,myota.filename);
						//sscanf(rdbuf_block2,json_instruction,&myota.firm_vers,myota.device,myota.dir,&myota.fsize,crc_str,myota.filename);
						sscanf(rdbuf_block2,json_instruction,&myota.firm_vers,myota.device,myota.dir,&myota.fsize,crc_str,fname);
						strcpy(myota.filename,fname);
						strcat(myota.filename,".bin");
						//free(rdbuf_block);
						
						char inst_pattern[]="firm_vers %d\r\ndevice %s\r\ndir %s\r\nfsize %d\r\nchksum CRC16_CCITT: %s\r\nfilename %s\r\n";
						char buf_inst[512];
						memset(buf_inst,0,512);
						sprintf(buf_inst,inst_pattern,myota.firm_vers,myota.device,myota.dir,myota.fsize,crc_str,myota.filename);
						pc.printf("%s",buf_inst);
						
						
//						eeprom.write(ADDRESS_EEPROM_JSON_OTA,(char*)&myota,sizeof(json_ota));
						
						char delim[]=",";
						char *ptr;
						ptr=strtok(crc_str,delim);
						char crc_short_str[64][6];
						int k=0;
								while(ptr!=0) {
										memset(crc_short_str[k],0,6);
										strcpy(crc_short_str[k],ptr);
										k++;
										ptr=strtok(NULL,delim);
								}
						
								for (int i=0;i<k;i++){
										myota.chksum[i]=atoi(crc_short_str[i]);
								}
								eeprom.write(ADDRESS_EEPROM_JSON_OTA,(char*)&myota,sizeof(json_ota));
						
						return true;
    }
    return false;
}

bool getBIN()
{
    pc.printf("get %s\r\n",locBIN_fname);
		bconfig=modem.configFTP(srv_IP,usr,pwd,ota_ftpPort);

    if(bconfig) {
        bactive=modem.activateFTP(1);
        if(bactive) {
            b_ftpstate=true;
        }
        bactive=false;
    }

    if(b_ftpstate) {

        bchgdir=modem.changedirFTP(myota.dir);

        if(bchgdir) {
            //bgetfile=modem.getFTP(myota.filename,loc_name);
						bgetfile=modem.getFTP(myota.filename,locBIN_fname);
        }
        //    pc.printf("getfile %s stat=> %d\r\n",myota.filename,bgetfile);

        if(bgetfile) {
            bactive=modem.activateFTP(0);
            if(bactive) {
                b_ftpstate=false;
                bconfig=false;
                bactive=false;
                //b_ftpstate=false;
                //bgetfile=false;
                bchgdir=false;
            }
            //b_ftpstate=false;
            bactive=false;
        }
				
				if(bgetfile) {
            bgetfile=false;
						flag_fw.get_frm=1;
						eeprom.write(ADDRESS_EEPROM_FLAG_OTA,(char*)&flag_fw,sizeof(flag_fw));
            //bool_rdFS=readFLASH_bin();
						return true;
        }
               
		return false;
    }
    return false;
}

//bool getBIN()

bool readFLASH_bin()
{
    //char fname[]="firmware.bin";
    int nlst=-1;
    flag_fw.get_nfs=0;
    nlst=modem.lstFS(locBIN_fname);
			
    if(nlst>0) {
						int size_block=4096;
						size_lstf=nlst%4096;
						num_pfrm=nlst/4096;
			
						if(size_lstf>0){
								num_pfrm+=1;
						}           
						
//						uint16_t chk_psum[num_pfrm];
						unsigned short chk_psum[num_pfrm];
						//memset((char*)chk_psum,0,num_pfrm*sizeof(uint16_t));
						pc.printf("num_pfrm: %d  size_lstf: %d\r\n",num_pfrm,size_lstf);
						pc.printf("nlst =%d fsize=%d\r\n",nlst,myota.fsize);

						if(nlst==myota.fsize){
									pc.printf("get firmware.bin complete --> Transfering to exFlash...\r\n");
						//rdbuf_block=(char *) realloc(rdbuf_block, 4096);
									for(int i=0;i<num_pfrm;i++){
												//eflash.block_erase(i);
												eflash_eraseBlock(i);

												if(i==(num_pfrm-1)){
															size_block=size_lstf;
												}

												//rdbuf_block=(char *) realloc(rdbuf_block, 4096);

												memset(rdbuf_block,0xff,4096);
												modem.rdBlockFS(locBIN_fname,rdbuf_block,(i<<12),size_block);
												chk_psum[i]=CRC16_CCITT((unsigned char*)rdbuf_block, size_block);
												pc.printf("chk_psum[%d] = %d [%04X]\r\n",i,chk_psum[i],chk_psum[i]);
												pc.printf("instruction checksum block[%d]= %d [%04X]\r\n",i,myota.chksum[i],myota.chksum[i]);

												if(chk_psum[i]==myota.chksum[i]){
															pc.printf("block[%d] CRC16_CCITT MATCHED\r\n",i);
															//eflash_block(rdbuf_block,i);
															pc.printf("block[%d] Transfer to exflash\r\n------------------------------------\r\n",i);
															eflash_block(rdbuf_block,i);
																
															lst_frmblock=i;
															flag_fw.get_nfs++;
															eeprom.write(ADDRESS_EEPROM_FLAG_OTA,(char*)&flag_fw,sizeof(flag_fw));
												}

									}
						//free(rdbuf_block);
									pc.printf("flag_fw.get_nfs = %d num_pfrm = %d\r\n",flag_fw.get_nfs,num_pfrm);
									
									if(flag_fw.get_nfs==num_pfrm){
												//if(lst_frmblock==(num_pfrm-1)){
												flag_fw.crc_match=1;
												eeprom.write(ADDRESS_EEPROM_FLAG_OTA,(char*)&flag_fw,sizeof(flag_fw));
												pc.printf("Tranfering firmware.bin to exflash complete...\r\n");																													
												return true;
									}else{
												flag_fw.check_ota=0;
												flag_fw.get_frm=0;
												flag_fw.get_nfs=0;
												flag_fw.crc_match=0;
												eeprom.write(ADDRESS_EEPROM_FLAG_OTA,(char*)&flag_fw,sizeof(flag_fw));
												pc.printf("Tranfering firmware.bin  Fail!!! reboot OTA process NOW!!!\r\n");
												return false;
									}

						}
						//jump_bootloader();
						return false;
    }
    return false;
}