/*=========================================================================== Combined Charging System (CCS): SECC PCBATester.c initiated by Joseph (since 2020/05/19) =============================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //for pow #include #include #include #include #include #include #include #include #include "define.h" #include "CsuComm.h" #include "SeccComm.h" #include "PCBATester.h" #if SAVE_SYS_LOG_MSG_PCBATESTER_SWITCH == ENABLE unsigned char buf_log_pcbatstr[SIZE_OF_LOG_BUFFER]; #endif unsigned char QcaMac[6]; unsigned char CsuMac[6] = {0x60, 0x39, 0x1F, 0x01, 0x02, 0x03}; int RawSock = 0; unsigned char *V2gtpMsgRxBuf, *V2gtpMsgTxBuf; struct sockaddr_ll DestSocketAddress; struct ifreq Req; struct timeb SeqStartTime, SeqEndTime; /*=========================================================================== FUNCTION: StoreLogMsg DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ #if SAVE_SYS_LOG_MSG_PCBATESTER_SWITCH == ENABLE int StoreLogMsg(unsigned char *DataString) { static unsigned char Buf[1024]; static time_t CurrentTime; static struct tm *tm; static struct timeval tv; memset(Buf, 0, sizeof(Buf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 sprintf(Buf, "echo \"[%04d%02d%02d: %02d:%02d:%02d.%06d][PCBATester]%s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, DataString, tm->tm_year + 1900, tm->tm_mon + 1); system(Buf); DEBUG_PRINTF_PCBATESTER_SYSTEM_LOG("[%02d:%02d:%02d.%06d][PCBATester]%s \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, DataString); //Reset the buf_log_pcbatstr Buffer, i.e. DataString memset(buf_log_pcbatstr, 0, SIZE_OF_LOG_BUFFER); } #endif /*=========================================================================== FUNCTION: DiffTimeb DESCRIPTION: Caculating the time difference in ms precision (milli-second). PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ double DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second double StartTime, EndTime; double t_diff; StartTime = ((double)ST.time)*1000 + (double)ST.millitm; EndTime = ((double)ET.time)*1000 + (double)ET.millitm; t_diff = EndTime - StartTime; //printf("%.02lf - %.02lf = %.02lf\n", EndTime, StartTime, t_diff); if (t_diff < 0) { #if 0 if (t_diff < -1000) //1000ms { sprintf(buf_log_pcbatstr, "[Warning]StartTime(%.02lf) > EndTime(%.02lf), d(%.02lf)", StartTime, EndTime, t_diff); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } #endif return -1; } return t_diff; } /*=========================================================================== FUNCTION: GetQca7kMac DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int GetQca7kMac() { int i = 0; struct QcaVendorMmeHeader SendPacket; memset(&SendPacket, 0, sizeof(struct QcaVendorMmeHeader)); memset(SendPacket.ODA, 0xFF, 6); //broadcast memcpy(SendPacket.OSA, CsuMac, 6); SendPacket.MTYPE = htons(EtherType_HomePlug); SendPacket.MMV = 0x00; SendPacket.MMTYPE = MMTYPE_VENDOR_VS_NW_INFO; SendPacket.OUI[0] = 0x00; SendPacket.OUI[1] = 0xB0; SendPacket.OUI[2] = 0x52; i = sendto(RawSock, &SendPacket, 20, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll)); DEBUG_PRINTF_EVCOMM_DETAIL("GetQca7kMac: send size =%d\n", i); SAVE_SYS_LOG_MSG_PCBATESTER("[QCA7K][Tx][VENDOR_VS_NW_INFO]Req for QCA7K MacAddr"); } unsigned int isKernelSupportNAT() { unsigned int result = 0; unsigned int version = 0; FILE *fp; char cmd[256]; char buf[512]; // Get IP address & net mask strcpy(cmd, "uname -v"); fp = popen(cmd, "r"); if(fp != NULL) { if(fgets(buf, sizeof(buf), fp) != NULL) { sscanf(buf, "#%d", &version); // DEBUG_INFO("Kernel version: %d\n", version); if(version >= 30) result = 1; } } pclose(fp); return result; } /*=========================================================================== FUNCTION: CANBus_Init DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CANBus_Init() { int s0, nbytes; struct timeval tv; struct ifreq ifr0; struct sockaddr_can addr0; system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100"); system("/sbin/ip link set can0 up"); s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (s0 < 0) //added by Joseph (not full implemented) { SAVE_SYS_LOG_MSG_PCBATESTER("[ERROR] Fail on initializing CAN Bus socket"); return -1; } tv.tv_sec = 0; tv.tv_usec = 10000; if(setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("CANBus_Init:Set SO_RCVTIMEO NG"); } nbytes = 40960; if(setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("CANBus_Init:Set SO_RCVBUF NG"); } nbytes = 40960; if(setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("CANBus_Init:Set SO_SNDBUF NG"); } strcpy(ifr0.ifr_name, "can0" ); ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */ addr0.can_family = AF_CAN; addr0.can_ifindex = ifr0.ifr_ifindex; bind(s0, (struct sockaddr *)&addr0, sizeof(addr0)); return s0; } /*=========================================================================== FUNCTION: CAN_Tx_MSG DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CAN_Tx_MSG(int Fd, unsigned int MsgId, unsigned char SlaveAddress, unsigned char DataLength, unsigned char *SendData) { struct can_frame frame; unsigned int tmp = 0; int nbytes = 0; int i = 0; //Protection: To avoid unexpected length for CAN bus payload. if (DataLength > 8) { DataLength = 8; } memset(&frame, 0, sizeof(struct can_frame)); frame.can_id = 0x80000000 | CAN_SEND_DIRECTION | MsgId | SlaveAddress; //0x80000000: extension ID format frame.can_dlc = DataLength; memcpy(frame.data, SendData, DataLength); nbytes = write(Fd, &frame, sizeof(struct can_frame)); #if 0 DEBUG_PRINTF_PCBATESTER_DETAIL("[CsuComm][CAN_Tx_MSG] <%X> ", frame.can_id); for (i = 0; i < frame.can_dlc; i++) { DEBUG_PRINTF_PCBATESTER_DETAIL("%02X ", frame.data[i]); } DEBUG_PRINTF_PCBATESTER_DETAIL("(%d Bytes)\n", frame.can_dlc); #endif return nbytes; } /*=========================================================================== FUNCTION: PRINT_CAN_FRAME DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void PRINT_CAN_FRAME(struct can_frame *frame) { if (frame->can_dlc != 0) { int i = 0; DEBUG_PRINTF_PCBATESTER_DETAIL("[CsuComm] Got CAN Message: \n\ \t - Length: %d (Bytes, DEC)\n\ \t - ID: %08X\n\ \t - Payload: ", frame->can_dlc, frame->can_id ); for (i = 0; i< frame->can_dlc; i++) { DEBUG_PRINTF_PCBATESTER_DETAIL("%02X ", frame->data[i]); } DEBUG_PRINTF_PCBATESTER_DETAIL("\n"); } } /*=========================================================================== FUNCTION: System_Init DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int System_Init() { system("../root/stop.sh"); } /*=========================================================================== FUNCTION: ReadAdcVolt DESCRIPTION: 1. fork1 #define ADC_CHANNEL_AIN0_NTC1 0 #define ADC_CHANNEL_AIN1_NTC2 1 #define ADC_CHANNEL_AIN2_PP 2 #define ADC_CHANNEL_AIN3_CP 3 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ float ReadAdcVolt(unsigned char AdcChannel) { //AIN0=CCS GUN Temp 1 //AIN1=CCS GUN Temp 2 //AIN2=CCS_Proximity/2 //AIN3=pilot voltage int fd; int AvgTimes = 0; unsigned char SampleBuf[4]; float TmpVolt = 0; float AvgSample = 0; float result = 0; switch (AdcChannel) { case ADC_CHANNEL_AIN0_NTC1: //0 { fd = open("/sys/bus/iio/devices/iio\:device0/in_voltage0_raw", O_RDONLY); break; } case ADC_CHANNEL_AIN1_NTC2: //1 { fd = open("/sys/bus/iio/devices/iio\:device0/in_voltage1_raw", O_RDONLY); break; } case ADC_CHANNEL_AIN2_PP: //2 { fd = open("/sys/bus/iio/devices/iio\:device0/in_voltage2_raw", O_RDONLY); break; } case ADC_CHANNEL_AIN3_CP: //3 { fd = open("/sys/bus/iio/devices/iio\:device0/in_voltage3_raw", O_RDONLY); break; } default: { sprintf(buf_log_pcbatstr, "[ReadAdcVolt]unexpected AdcChannel(%d)", AdcChannel); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); return -1; } } if(fd > 0) { for(AvgTimes = 0; AvgTimes < 5; AvgTimes++) //get 5 samples { read(fd, SampleBuf, 4); TmpVolt = (float)atoi(SampleBuf); lseek(fd, 0, SEEK_SET); AvgSample += TmpVolt; } close(fd); AvgSample /= AvgTimes; switch (AdcChannel) { case ADC_CHANNEL_AIN0_NTC1: //0 { result = (3.6 * AvgSample) / 4095; //sprintf(buf_log_pcbatstr, "[ReadAdcVolt]AIN0_NTC1 = %.02f", result); //SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); break; } case ADC_CHANNEL_AIN1_NTC2: //1 { result = (3.6 * AvgSample) / 4095; //sprintf(buf_log_pcbatstr, "[ReadAdcVolt]AIN1_NTC2 = %.02f", result); //SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); break; } case ADC_CHANNEL_AIN2_PP: //2 { result = (3.6 * AvgSample) / 4095; //sprintf(buf_log_pcbatstr, "[ReadAdcVolt]AIN2_PP = %.02f", result); //SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); break; } case ADC_CHANNEL_AIN3_CP: //3 { result = (0.954-(1.8*AvgSample/4095))/0.06; //sprintf(buf_log_pcbatstr, "[ReadAdcVolt]AIN3_CP = %.02f", result); //SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); break; } default: { sprintf(buf_log_pcbatstr, "[ReadAdcVolt]unknown AdcChannel(%d)", AdcChannel); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = -1; break; } } return result; } else { SAVE_SYS_LOG_MSG_PCBATESTER("[ReadAdcVolt]failed on open adc channel"); return -1; } } /*=========================================================================== FUNCTION: PCBATstr_canbus DESCRIPTION: 1. Tx: AA 55 2. Rx: 55 AA (expected) PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_canbus() { int FD_CAN_Socket = 0; int result = PASS; int err_cnt = 0; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [canbus] start --------"); unsigned char can_tx_payload[8]; struct can_frame frame; //Step 1: CAN Bus FD_CAN_Socket = CANBus_Init(); if (FD_CAN_Socket < 0) { return FAIL; } while(1) { //Step 2: Tx CAN Message memset(can_tx_payload, 0, sizeof(can_tx_payload)); can_tx_payload[0] = 0xAA; can_tx_payload[1] = 0x55; CAN_Tx_MSG(FD_CAN_Socket, CAN_CMD_PCBA_TEST, 0, 2, can_tx_payload); sleep(1); //Step 3: Rx CAN Message memset(&frame, 0, sizeof(struct can_frame)); read(FD_CAN_Socket, &frame, sizeof(struct can_frame)); //PRINT_CAN_FRAME(&frame); if( (frame.can_id == 0) || //all zero (frame.can_id & 0x08000000) || //to avoid incoreect DIRECTION bit ((frame.can_id & 0x0000FF00) != CAN_CMD_PCBA_TEST) || //the 1st command ID from Master should be 0x02 (frame.can_dlc != 2)) //payload length should be only 5 bytes. { if (err_cnt++ >= 10) { SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_canbus]Rx err_cnt >= 5"); result = FAIL; break; } continue; } if ((frame.data[0] == 0x55) && (frame.data[1] == 0xAA)) { sprintf(buf_log_pcbatstr, "[PCBATstr_canbus]rx: %02X %02X (PASS)", frame.data[0], frame.data[1]); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); break; } else { sprintf(buf_log_pcbatstr, "[PCBATstr_canbus]rx: %02X %02X (FAIL)", frame.data[0], frame.data[1]); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; break; } } SAVE_SYS_LOG_MSG_PCBATESTER("-------- [canbus] end --------"); return result; } /*=========================================================================== FUNCTION: PCBATstr_ethernet DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_ethernet() { int result = PASS; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [ethernet] --------"); system("/sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up"); system("/sbin/route add default gw 192.168.1.1"); //system("ping -I eth0 -c 3 192.168.1.1"); sleep(1); return result; } /*=========================================================================== FUNCTION: PCBATstr_gpio_ntc DESCRIPTION: 1. AM_IO_1 <<==>> NTC1 & NTC2 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_gpio_ntc() { int result = PASS; float ntc1 = 0; float ntc2 = 0; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [ntc] --------"); //Step 1: AM_IO_1 system("echo 87 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio87/direction"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_gpio_ntc]AM_IO_1(ON): read NTC1, NTC2"); system("echo 1 > /sys/class/gpio/gpio87/value"); //[AM_IO_1](gpio2_25: output) usleep(100000); ntc1 = ReadAdcVolt(ADC_CHANNEL_AIN0_NTC1); ntc2 = ReadAdcVolt(ADC_CHANNEL_AIN1_NTC2); if (ntc1 > 3.0) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc1 = %.02fV (PASS, > 3.0)", ntc1); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); if (ntc2 > 3.0) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc2 = %.02fV (PASS, > 3.0)", ntc2); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc2 = %.02fV (FAIL, > 3.0)", ntc2); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc1 = %.02fV (FAIL, > 3.0)", ntc1); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } //========================================================================= SAVE_SYS_LOG_MSG_PCBATESTER("\n"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_gpio_ntc]AM_IO_1(OFF): read NTC1, NTC2"); system("echo 0 > /sys/class/gpio/gpio87/value"); //[AM_IO_1](gpio2_25: output) usleep(100000); ntc1 = ReadAdcVolt(ADC_CHANNEL_AIN0_NTC1); ntc2 = ReadAdcVolt(ADC_CHANNEL_AIN1_NTC2); if (ntc1 < 0.5) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc1 = %.02fV (PASS, < 0.5)", ntc1); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); if (ntc2 < 0.5) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc2 = %.02fV (PASS, < 0.5)", ntc2); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc2 = %.02fV (FAIL, < 0.5)", ntc2); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]ntc1 = %.02fV (FAIL, < 0.5)", ntc1); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } return result; } /*=========================================================================== FUNCTION: PCBATstr_gpio_pp DESCRIPTION: 1. AM_IO_2 <<==>> PP PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_gpio_pp() { int result = PASS; float pp = 0; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [pp] --------"); // initial gpio system("echo 89 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio89/direction"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_gpio_ntc]PP(ON): read PP"); system("echo 1 > /sys/class/gpio/gpio89/value"); //[AM_IO_2](gpio2_25: output) usleep(100000); pp = ReadAdcVolt(ADC_CHANNEL_AIN2_PP); if (pp > 2.0) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]PP = %.02fV (PASS, > 2.0)", pp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]PP = %.02fV (FAIL, > 2.0)", pp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_gpio_ntc]PP(OFF): read PP..."); system("echo 0 > /sys/class/gpio/gpio89/value"); //[AM_IO_2](gpio2_25: output) usleep(100000); pp = ReadAdcVolt(ADC_CHANNEL_AIN2_PP); if (pp < 0.5) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]PP = %.02fV (PASS, < 0.5)", pp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]PP = %.02fV (FAIL, < 0.5)", pp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } return result; } /*=========================================================================== FUNCTION: PCBATstr_cp DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_cp() { int result = PASS; float cp = 0; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [cp] --------"); // initial pwm system("echo 0 > /sys/class/pwm/pwmchip0/export"); system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period");// nano seconds =>1k Hz system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); //default 100% system("echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable"); system("echo 89 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio89/direction"); system("echo 86 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio86/direction"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_gpio_ntc]CP(PWM:100%,SetStateE:OFF): read CP"); system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); system("echo 0 > /sys/class/gpio/gpio86/value"); //state E usleep(100000); cp = ReadAdcVolt(ADC_CHANNEL_AIN3_CP); if (cp > 11.0) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]CP = %.02fV (PASS, > 11.0)", cp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]CP = %.02fV (FAIL, > 11.0)", cp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } SAVE_SYS_LOG_MSG_PCBATESTER("\n"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_gpio_ntc]CP(PWM:100%,SetStateE:ON): read CP"); system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); system("echo 1 > /sys/class/gpio/gpio86/value"); //state E usleep(100000); cp = ReadAdcVolt(ADC_CHANNEL_AIN3_CP); if (cp < 1.0) { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]CP = %.02fV (PASS, < 1.0V)", cp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); } else { sprintf(buf_log_pcbatstr, "[PCBATstr_gpio_ntc]CP = %.02fV (FAIL, < 1.0V)", cp); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); result = FAIL; } return result; } /*=========================================================================== FUNCTION: PCBATstr_reboot DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_reboot() { SAVE_SYS_LOG_MSG_PCBATESTER("-------- [reboot] --------"); system("reboot -f"); sleep(2); system("reboot -f"); return PASS; } /*=========================================================================== FUNCTION: PCBATstr_killtasks DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_killtasks() { int result = PASS; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [killtasks] --------"); system("../root/stop.sh"); return result; } /*=========================================================================== FUNCTION: PCBATstr_qca7k DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_qca7k() { SAVE_SYS_LOG_MSG_PCBATESTER("-------- [qca7000] --------"); if(isKernelSupportNAT() == 1) system("/sbin/insmod /lib/qcaspi_nat.ko"); else system("/sbin/insmod /lib/qcaspi.ko"); // system("/sbin/insmod /lib/qcaspi.ko"); sleep(2); system("/sbin/ifconfig eth1 192.168.0.11 netmask 255.255.255.0 up"); sleep(1); int state = IDLE; int result = PASS; int packet_size = 0; double t_diff = 0; //Step1: Init if(RawSock > 0) { close(RawSock); } RawSock = -1; //Init V2G TCP/IPv6 packets buffer V2gtpMsgRxBuf = (unsigned char *)malloc(V2GTP_MSG_RX_BUFFER_SIZE); memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE); V2gtpMsgTxBuf = (unsigned char *)malloc(V2GTP_MSG_TX_BUFFER_SIZE); memset(V2gtpMsgTxBuf, 0, V2GTP_MSG_TX_BUFFER_SIZE); while (1) { if(RawSock >= 0) { memset(V2gtpMsgRxBuf, 0, V2GTP_MSG_RX_BUFFER_SIZE); packet_size = recvfrom(RawSock, V2gtpMsgRxBuf, V2GTP_MSG_RX_BUFFER_SIZE, 0, NULL, NULL); if(packet_size > 0) { struct MmeHeader *MmePacket; MmePacket = (struct MmeHeader *)V2gtpMsgRxBuf; switch(MmePacket->MMTYPE) { case MMTYPE_VENDOR_VS_NW_INFO_CNF: { memcpy(QcaMac, MmePacket->OSA, 6); sprintf(buf_log_pcbatstr, "[QCA7K][Rx][VENDOR_VS_NW_INFO_CNF]Got QCA7K MacAddr:%02X:%02X:%02X:%02X:%02X:%02X (comm:OK)", QcaMac[0], QcaMac[1], QcaMac[2], QcaMac[3], QcaMac[4], QcaMac[5]); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); return PASS; } default: { break; } } } } switch(state) { case IDLE: { if(RawSock < 0) { RawSock = socket(PF_PACKET, SOCK_RAW, htons(EtherType_HomePlug)); sprintf(buf_log_pcbatstr, "[RawSock]opened(%d)", RawSock); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); if(RawSock == -1) { SAVE_SYS_LOG_MSG_PCBATESTER("SlacComm:Failed to create socket"); return FAIL; } if (setsockopt(RawSock, SOL_SOCKET, SO_BINDTODEVICE, QcaInterface, 4) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("SlacComm:Set SO_BINDTODEVICE NG"); return FAIL; } struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; //100ms (Rx timeout) if (setsockopt(RawSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("SlacComm:Set SO_RCVTIMEO NG"); return FAIL; } tv.tv_usec = 100000; //100ms (Tx timeout) if (setsockopt(RawSock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("SlacComm:Set SO_SNDTIMEO NG"); return FAIL; } memset(&Req, 0, sizeof(struct ifreq)); strcpy( (char*)Req.ifr_name, QcaInterface); if (ioctl(RawSock, SIOCGIFINDEX, &Req) < 0) { SAVE_SYS_LOG_MSG_PCBATESTER("SlacComm: ioctl NG"); return FAIL; } memset(&DestSocketAddress, 0, sizeof(struct sockaddr_ll)); DestSocketAddress.sll_ifindex = Req.ifr_ifindex; DestSocketAddress.sll_halen = ETH_ALEN; SAVE_SYS_LOG_MSG_PCBATESTER("[QCA7K]connecting..."); //Get QCA7K MAC address GetQca7kMac(); ftime(&SeqStartTime); break; } else //RawSock: opened { ftime(&SeqEndTime); t_diff = DiffTimeb(SeqStartTime, SeqEndTime); if (t_diff > V2G_SECC_QCA7000_COMM_TIMEOUT) //10 secs { sprintf(buf_log_pcbatstr, "[QCA7K][Error]comm: fail (%.02lf/%dms)", t_diff, V2G_SECC_QCA7000_COMM_TIMEOUT); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); return FAIL; } else if (t_diff > V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD) //3 secs { sprintf(buf_log_pcbatstr, "[QCA7K]re-try connecting...(%.02lf/%dms)", t_diff, V2G_SECC_QCA7000_GET_MAC_ADDR_REQ_RETRY_PERIOD); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); GetQca7kMac(); //re-send req break; } else { //null } } break; } default: { break; } } } } /*=========================================================================== FUNCTION: PCBATstr_sdcard DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_sdcard() { int result = FAIL; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [sdcard] --------"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]mount SDCard on mnt"); system("mount /dev/mmcblk0p1 /mnt"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]delete file.txt"); system("rm -rfv /mnt/file.txt"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]creat file.txt in SDCard"); system("touch /mnt/file.txt"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]unmount SDCard from mnt"); system("umount /mnt"); sleep(1); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]mount SDCard on UsbFlash"); system("mount /dev/mmcblk0p1 /UsbFlash"); FILE *fp; fp = fopen("/UsbFlash/file.txt", "r"); if (fp == NULL) { SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]file.txt is not found"); } else { SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]file.txt is found"); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]delete file.txt"); system("rm -rfv /mnt/file.txt"); result = PASS; } fclose(fp); SAVE_SYS_LOG_MSG_PCBATESTER("[PCBATstr_sdcard]unmount SDCard from UsbFlash"); system("umount /UsbFlash"); return result; } /*=========================================================================== FUNCTION: PCBATstr_all DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int PCBATstr_all() { int result = PASS; SAVE_SYS_LOG_MSG_PCBATESTER("-------- [all] --------"); //case 'k': //Kill other tasks if (PCBATstr_killtasks() == PASS) { printf("[kill]PASS\n"); } else { printf("[kill]FAIL\n"); result = FAIL; } //case 'b': //CAN Bus Test if (PCBATstr_canbus() == PASS) { printf("[can]PASS\n"); } else { printf("[can]FAIL\n"); result = FAIL; } //case 'e': //Ethernet(eth1) Test if (PCBATstr_ethernet() == PASS) { printf("[eth]READY\n"); } else { printf("[eth]FAIL\n"); result = FAIL; } //case 'n': //GPIO(AM_IO_1) and ADC(NTC1,NTC2) Test if (PCBATstr_gpio_ntc() == PASS) { printf("[ntc]PASS\n"); } else { printf("[ntc]FAIL\n"); result = FAIL; } //case 'p': //GPIO(AM_IO_2) and ADC(PP) Test if (PCBATstr_gpio_pp() == PASS) { printf("[pp]PASS\n"); } else { printf("[pp]FAIL\n"); result = FAIL; } //case 'c': //CP Test if (PCBATstr_cp() == PASS) { printf("[cp]PASS\n"); } else { printf("[cp]FAIL\n"); result = FAIL; } //case 'q': //QCA7000 Test if (PCBATstr_qca7k() == PASS) { printf("[qca]PASS\n"); } else { printf("[qca]FAIL\n"); result = FAIL; } //case 's': //SD Card Test if (PCBATstr_sdcard() == PASS) { printf("[sd]PASS\n"); } else { printf("[sd]FAIL\n"); result = FAIL; } return result; } /*=========================================================================== FUNCTION: main DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int main(int argc, char *argv[]) { SAVE_SYS_LOG_MSG_PCBATESTER("PCBATester: on"); SAVE_SYS_LOG_MSG_PCBATESTER("---------------------------------------------"); SAVE_SYS_LOG_MSG_PCBATESTER("-- PCBATester --"); SAVE_SYS_LOG_MSG_PCBATESTER("---------------------------------------------\n"); //Initialization //System_Init(); //Arguments Parsing for Commands if (argv[1][0] == '-' ) { switch (argv[1][1]) { case 'h': //help { printf(" ================= [HELP] PCBATester ==============\n"); printf(" -h \t :help\n"); printf(" -a \t :Auto Run All Test Cases\n"); printf(" -b \t :CAN Bus Test\n"); printf(" -c \t :CP Test\n"); printf(" -e \t :Ethernet(eth1) Test\n"); printf(" -k \t :Killall other tasks\n"); printf(" -p \t :GPIO(AM_IO_2) and ADC(PP) Test\n"); printf(" -n \t :GPIO(AM_IO_1) and ADC(NTC1,NTC2) Test\n"); printf(" -q \t :QCA7000 Test\n"); printf(" -r \t :Reboot\n"); printf(" -s \t :SD Card Test\n"); break; } case 'a': //Auto Run All Test Cases { if (PCBATstr_all() == PASS) { printf("[all]PASS\n"); } else { printf("[all]FAIL\n"); } break; } case 'b': //CAN Bus Test { if (PCBATstr_canbus() == PASS) { printf("[can]PASS\n"); } else { printf("[can]FAIL\n"); } break; } case 'e': //Ethernet(eth1) Test { if (PCBATstr_ethernet() == PASS) { printf("[eth]READY\n"); } else { printf("[eth]FAIL\n"); } break; } case 'n': //GPIO(AM_IO_1) and ADC(NTC1,NTC2) Test { if (PCBATstr_gpio_ntc() == PASS) { printf("[ntc]PASS\n"); } else { printf("[ntc]FAIL\n"); } break; } case 'p': //GPIO(AM_IO_2) and ADC(PP) Test { if (PCBATstr_gpio_pp() == PASS) { printf("[pp]PASS\n"); } else { printf("[pp]FAIL\n"); } break; } case 'k': //Kill other tasks { if (PCBATstr_killtasks() == PASS) { printf("[kill]PASS\n"); } else { printf("[kill]FAIL\n"); } break; } case 'c': //CP Test { if (PCBATstr_cp() == PASS) { printf("[cp]PASS\n"); } else { printf("[cp]FAIL\n"); } break; } case 'q': //QCA7000 Test { if (PCBATstr_qca7k() == PASS) { printf("[qca]PASS\n"); } else { printf("[qca]FAIL\n"); } break; } case 'r': //Reboot { if (PCBATstr_reboot() == PASS) { printf("[reboot]PASS\n"); } else { printf("[reboot]FAIL\n"); } break; } case 's': //SD Card Test { if (PCBATstr_sdcard() == PASS) { printf("[sd]PASS\n"); } else { printf("[sd]FAIL\n"); } break; } default: { sprintf(buf_log_pcbatstr, "Unknown option -%c\n\n", argv[1][1]); SAVE_SYS_LOG_MSG_PCBATESTER(buf_log_pcbatstr); printf("[others]UNSUPPORTED\n"); break; } } } }