/**************************************************************************** * * Name: packet_send * Function: send a packet * variable: pPacket -- packet information point * ****************************************************************************/ UINT32 packet_send(PPACKET pPacket) { //create packet head buffer; unsigned char packet_head[PACKET_HEAD_LEN]; unsigned char szCRC[4]; MakePacketHeadBuffer(pPacket, packet_head); //send packet header if(PACKET_HEAD_LEN != com_send(packet_head, PACKET_HEAD_LEN)) { return ERROR_SENDPACKETHEAD; } UINT32 nLength = pPacket->packet_length; if(0 != pPacket->blank_flag && PACKET_DATA == pPacket->packet_type) nLength = 4; if(nLength != com_send(pPacket->data_buffer, nLength)) { return ERROR_SENDPACKETDATA; } UINT32 nCRC = MG_Table_Driven_CRC(0xFFFFFFFF, pPacket->data_buffer, nLength); store_long(szCRC, nCRC); if(4 != com_send(szCRC, 4)) { return ERROR_SENDPACKETCRC; } return SUCCESS; }
void ota_save_parameter(UINT8 *p) { unsigned long crc, len; MEMCPY(p+CHUNK_HEADER_SIZE, &m_ota_cfg, sizeof(m_ota_cfg)); MG_Setup_CRC_Table(); len = fetch_long(p + CHUNK_LENGTH); crc = (unsigned long)MG_Table_Driven_CRC(0xFFFFFFFF, p + CHUNK_NAME, len); store_long( (unsigned char*)(p + CHUNK_CRC), crc); }
/**************************************************************************** * * Name: MakePacketHeadBuffer * Function: Make Packet head buffer * Remark: local function * variable: * ****************************************************************************/ void MakePacketHeadBuffer(PPACKET pPacket, unsigned char *packet_head) { MEMSET(packet_head, 0, PACKET_HEAD_LEN); // set packet head information; MEMCPY(packet_head + PACKET_HEAD_FLAG_OFFSET, l_packet_head_flag, sizeof(l_packet_head_flag) - 1); MEMCPY(packet_head + PACKET_TYPE_OFFSET, &(pPacket->packet_type), sizeof(pPacket->packet_type)); MEMCPY(packet_head + PACKET_BLANKFLAG_OFFSET, &(pPacket->blank_flag), sizeof(pPacket->blank_flag)); store_long(packet_head + PACKET_INDEX_OFFSET, pPacket->packet_index); MEMCPY(packet_head + PACKET_REPEAT_OFFSET, &(pPacket->packet_repeat), sizeof(pPacket->packet_repeat)); store_long( packet_head + PACKET_LENGTH_OFFSET, pPacket->packet_length); UINT32 nCRC = MG_Table_Driven_CRC(0xFFFFFFFF, packet_head + PACKET_TYPE_OFFSET, PACKET_HEAD_LEN - 8); store_long( packet_head + PACKET_HEAD_CRC_OFFSET, nCRC); }
static UINT8 find_ota_loader(UINT32 *ota_loader_addr) { #define C_SECTOR_SIZE 0x10000 UINT8 *buffer; UINT32 data_id; UINT32 data_len; UINT32 data_off; UINT32 data_crc; UINT32 crc; UINT32 pointer = 0; struct sto_device *flash_dev = (struct sto_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_STO); while(pointer < (UINT32)flash_dev->totol_size) { data_id = sto_fetch_long((UINT32)pointer + CHUNK_ID); data_len = sto_fetch_long((UINT32)pointer + CHUNK_LENGTH); data_off = sto_fetch_long((UINT32)pointer + CHUNK_OFFSET); data_crc = sto_fetch_long((UINT32)pointer + CHUNK_CRC); if(data_len && (data_len < data_off) && (data_crc != NO_CRC) && ((data_id & CHUNKID_SECLOADER_MASK) == CHUNKID_SECLOADER)) { buffer = (UINT8 *)MALLOC(data_len); if(buffer != NULL) { sto_get_data(flash_dev, buffer, pointer + 16, data_len); crc = MG_Table_Driven_CRC(0xFFFFFFFF, buffer, data_len); FREE(buffer); if(data_crc == crc) { *ota_loader_addr = pointer; return 1; } } } pointer += C_SECTOR_SIZE; } return 0; }
/**************************************************************************** * * Name: packet_receive * Function: receive a packet * variable: pPacket -- packet information point * nTimeOut -- time out * ****************************************************************************/ UINT32 packet_receive(PPACKET pPacket, UINT32 nTimeOut) { //receive and compare packet head flag unsigned char c = 0; BOOL bPacketHead = FALSE; BOOL bComtest = FALSE; UINT32 i = 0; int n = 0; UINT32 nLength = 0; MEMSET(pPacket, 0, sizeof(PACKET)); for(i = 0; i < nTimeOut;) { if( c == 'H') { // judge if packet head for(n = 0; n < 3; n++) { if(SUCCESS != com_read_tm(&c, 1, 1)) { c = 0; break; } if(c != l_packet_head_flag[n + 1]) break; } if(n == 3) { bPacketHead = TRUE; break; } } else if(c == 'c') { pPacket->data_buffer[0] = 'c'; LIB_ASH_OC(c); //judge if comtest for(n = 0; n < 6; n++) { // c = LIB_ASH_IC(); if(SUCCESS != com_read_tm(&c, 1, 100)) { c = 0; SH_PRINTF("comtest not all : %d\n", n); break; } if(c != l_packet_comtest[n + 1]) break; LIB_ASH_OC(c); } if(n == 6) { SH_PRINTF("RECEIVE comtest\n"); bComtest = TRUE; break; } } else if(SUCCESS != com_read(&c, 1)) { Sleep(1); i++; } } if(bPacketHead) { //receive packet head unsigned char packet_head[PACKET_HEAD_LEN]; if(SUCCESS != com_read_tm(packet_head + PACKET_TYPE_OFFSET, PACKET_HEAD_LEN - 4, 1000)) { SH_PRINTF("ERROR:receive head error"); return ERROR_PACKET_RECEIVEHEAD; } //compare CRC about packet head UINT32 nCRC = MG_Table_Driven_CRC(0xFFFFFFFF, packet_head + PACKET_TYPE_OFFSET, PACKET_HEAD_LEN - 8); if(nCRC != fetch_long(packet_head + PACKET_HEAD_CRC_OFFSET)) return ERROR_PACKET_HEADCRC; MakePacketHead(packet_head, pPacket); //Receive data and CRC nLength = pPacket->packet_length; // if blank packet receive 4B packet number only if(0 != pPacket->blank_flag && PACKET_DATA == pPacket->packet_type) nLength = 4; if(SUCCESS != com_read_tm(pPacket->data_buffer, nLength + 4, 1000)) return ERROR_PACKET_RECEIVEDATA; nCRC = MG_Table_Driven_CRC(0xFFFFFFFF, pPacket->data_buffer, nLength); if(nCRC != fetch_long(pPacket->data_buffer + nLength)) return ERROR_PACKET_DATACRC; if(PACKET_DATA == pPacket->packet_type) { if(1 == pPacket->blank_flag) memset(pPacket->data_buffer + 4, 0xFF, pPacket->packet_length - 4); else if(2 == pPacket->blank_flag) memset(pPacket->data_buffer + 4, 0x00, pPacket->packet_length - 4); } } else if(bComtest) { pPacket->packet_type = PACKET_COMMAND; MEMCPY(pPacket->data_buffer, l_packet_comtest, 7); i = 7; while(i < 128) { pPacket->data_buffer[i] = LIB_ASH_IC(); c = pPacket->data_buffer[i]; LIB_ASH_OC(c); if (c == 0x0D || c == 0x0A) break; i++; } pPacket->packet_length = STRLEN(pPacket->data_buffer); // for(i = 0; i < pPacket->packet_length; i++) // LIB_ASH_OC(pPacket->data_buffer[i]); SH_PRINTF(pPacket->data_buffer); g_packet_index = 0; g_packet_repeat = 0; } else return ERROR_NOPACKETRECEIVE; return SUCCESS; }
/* collect information */ n = sto_chunk_count(0, 0); of = sto_chunk_goto(&chid, 0, n); len = sto_fetch_long(of + CHUNK_LENGTH); /* send Length */ data_len = n * CHUNK_HEADER_SIZE + 2; LIB_ASH_OC((data_len >> 8) & 0xFF); LIB_ASH_OC(data_len & 0xFF); crc = 0xFFFFFFFF; /* send Flash ID */ LIB_ASH_OC(flash_id_val); crc = MG_Table_Driven_CRC(crc, &flash_id_val, 1); /* send Chunk Status */ LIB_ASH_OC(g_crc_bad); crc = MG_Table_Driven_CRC(crc, &g_crc_bad, 1); /* send Chunks */ for (i = 1; i <= n; i++) { of = sto_chunk_goto(&chid, 0, i); sto_get_data(flash_dev, buf, of, CHUNK_HEADER_SIZE); data_len = sto_fetch_long(of + CHUNK_LENGTH); crc1 = MG_Table_Driven_CRC(0xFFFFFFFF, (unsigned char *) \ SYS_FLASH_BASE_ADDR + of + 16, data_len); store_long(buf + CHUNK_CRC, crc1); for (j = 0; j < CHUNK_HEADER_SIZE; j++) LIB_ASH_OC(buf[j]); crc = MG_Table_Driven_CRC(crc, buf, CHUNK_HEADER_SIZE);
UINT32 cmd_stbid(unsigned int argc, unsigned char *argv[]) { UINT8 i = 0, j = 0, ch = 0xff; UINT8 *_stbid_flag = "SRI"; INT32 _stbid_flag_len = 3; UINT8 _serial_data[1024]; // max receive 1KB data UINT32 timeout = 1000, stbid_offset = STB_HWINFO_SERIAL_OFF, _stbid_crc = 0, _stbid_len = 0, _serial_len = 0, _crc = 0, _crc_pos = 0; UINT8 *buffer = NULL; UINT32 nReturn = SUCCESS; UINT32 nPacketNum = 0; PACKET packet; UINT32 tick = osal_get_tick(); UINT8 retry_num = 5, _tr_num = 5; ID _task_id = g_com_ash_id; osal_task_dispatch_off(); SendStatusPacket(COMMAND_STATUS_OK, 0); pan_display(g_pan_dev, "Stb-", 4); RETRY: _tr_num = 5; //transfer data MEMSET(&packet, 0, sizeof(PACKET)); nReturn = packet_receive(&packet, 5 * 1000); if(SUCCESS != nReturn) { SERIAL_DEBUG("receive packet fail!\n"); retry_num--; goto RETURN; } if(packet.packet_type == PACKET_DATA) { _serial_len = packet.packet_length-4; MEMCPY(_serial_data, packet.data_buffer+4, packet.packet_length-4); } else { SERIAL_DEBUG("receive %d packet, ignore!\n", packet.packet_type); retry_num--; goto RETURN; } SERIAL_DEBUG("stbid get data total len %d finish, data: \n", _serial_len); for(i=0; i<_serial_len; i++) { SERIAL_DEBUG("%c", _serial_data[i]); } SERIAL_DEBUG("\n"); pan_display(g_pan_dev, "GET", 4); if((_serial_data[0] != _stbid_flag[0]) || (_serial_data[1] != _stbid_flag[1]) || (_serial_data[2] != _stbid_flag[2])) // received flag tag { SERIAL_DEBUG("Error: SRI flag missing!\n"); retry_num--; goto RETURN; } pan_display(g_pan_dev, "FLAG", 4); _stbid_len = _serial_len-4-8; if(_stbid_len > STB_HWINFO_MAC_OFF) { SERIAL_DEBUG("Error: stbid len %d != [%d], please resend cmd!\n", _stbid_len, STB_HWINFO_MAC_OFF); retry_num--; goto RETURN; } pan_display(g_pan_dev, "LENG", 4); // do crc check _crc_pos = _stbid_flag_len+1+_stbid_len; _stbid_crc = 0; for(i=0; i<8; i++) { _stbid_crc |= (((_serial_data[_crc_pos+i]>'9') ? (_serial_data[_crc_pos+i]-'A'+10) : (_serial_data[_crc_pos+i]-'0'))<<((7-i)*4)); } _crc = MG_Table_Driven_CRC(0xFFFFFFFF, _serial_data, _crc_pos); if(_stbid_crc != _crc) { // fail, need re-trans SERIAL_DEBUG("stbid crc fail, calcu = 0x%x!\n", _crc); retry_num--; goto RETURN; } pan_display(g_pan_dev, "CRC", 4); // burn code, enable drive auto-erase for(i=0; i<(STB_HWINFO_OUI_OFF-STB_HWINFO_MAC_OFF); i++) // init mac { ch = _serial_data[STB_HWINFO_MAC_OFF+4-12+i*2]; _serial_data[i+STB_HWINFO_MAC_OFF+4] = (((ch>'9') ? ((ch>='a') ? (ch-'a'+10) : (ch-'A'+10)) : (ch-'0'))<<4); ch = _serial_data[STB_HWINFO_MAC_OFF+4-12+i*2+1]; _serial_data[i+STB_HWINFO_MAC_OFF+4] |= ((ch>'9') ? ((ch>='a') ? (ch-'a'+10) : (ch-'A'+10)) : (ch-'0')); } buffer = MALLOC(64*1024); if(buffer == NULL) { SDBBP(); } sto_io_control(g_sto_dev, STO_DRIVER_SECTOR_BUFFER, (UINT32)buffer); sto_io_control(g_sto_dev, STO_DRIVER_SET_FLAG, STO_FLAG_AUTO_ERASE|STO_FLAG_SAVE_REST); SERIAL_DEBUG("Now burn stbid: "); for(i=0; i<STB_HWINFO_OUI_OFF; i++) { SERIAL_DEBUG("%c", _serial_data[i+_stbid_flag_len+1]); } SERIAL_DEBUG("\n"); sto_put_data(g_sto_dev, STB_HWINFO_BASE_ADDR, &_serial_data[_stbid_flag_len+1], STB_HWINFO_OUI_OFF); if(buffer) { FREE(buffer); buffer = NULL; sto_io_control(g_sto_dev, STO_DRIVER_SECTOR_BUFFER, 0); sto_io_control(g_sto_dev, STO_DRIVER_SET_FLAG, 0); } if(g_stb_hwinfo != NULL) { FREE(g_stb_hwinfo); g_stb_hwinfo = NULL; } pan_display(g_pan_dev, "-tr-", 4); SERIAL_DEBUG("stbid finish, task %d deleted!\n", g_com_ash_id); SERIAL_DEBUG("cmd_stbid takes %dms\n", osal_get_tick()-tick); retry_num = 0; RESEND: SendStatusPacket(COMMAND_STATUS_DONE, 0); MEMSET(&packet, 0, sizeof(PACKET)); osal_task_sleep(100); nReturn = packet_receive(&packet, 5 * 1000); if((SUCCESS != nReturn) || (packet.packet_type != PACKET_STATUS)) { if(_tr_num-- > 0) { SERIAL_DEBUG("stbid finish, but signal send fail, now re-send!\n"); goto RESEND; } else { pan_display(g_pan_dev, "dStb", 4); // done, but notice fail! } } else { pan_display(g_pan_dev, "-Stb", 4); // done, all ok! } RETURN: if(retry_num >0) { SendStatusPacket(COMMAND_STATUS_ERROR, 0); goto RETRY; } else { SERIAL_DEBUG("error, please redo!\n"); api_set_com_check_flag(COM_MONITOR_CHECK_STBID); } g_com_ash_id = INVALID_ID; osal_task_dispatch_on(); osal_task_delete(_task_id); }