123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- #include "tftpserver.h"
- #include "flash_if.h"
- #include <string.h>
- #include <stdio.h>
- #include "main.h"
- #include "crc.h"
- static uint32_t Flash_Write_Address;
- static struct udp_pcb *UDPpcb;
- static __IO uint32_t total_count=0;
- static void IAP_wrq_recv_callback(void *_args, struct udp_pcb *upcb, struct pbuf *pkt_buf,
- const ip_addr_t *addr, u16_t port);
- static int IAP_tftp_process_write(struct udp_pcb *upcb, const ip_addr_t *to, int to_port);
- static void IAP_tftp_recv_callback(void *arg, struct udp_pcb *Upcb, struct pbuf *pkt_buf,
- const ip_addr_t *addr, u16_t port);
- static void IAP_tftp_cleanup_wr(struct udp_pcb *upcb, tftp_connection_args *args);
- static tftp_opcode IAP_tftp_decode_op(char *buf);
- static u16_t IAP_tftp_extract_block(char *buf);
- static void IAP_tftp_set_opcode(char *buffer, tftp_opcode opcode);
- static void IAP_tftp_set_block(char* packet, u16_t block);
- static err_t IAP_tftp_send_ack_packet(struct udp_pcb *upcb, const ip_addr_t *to, int to_port, int block);
- static tftp_opcode IAP_tftp_decode_op(char *buf)
- {
- return (tftp_opcode)(buf[1]);
- }
- static u16_t IAP_tftp_extract_block(char *buf)
- {
- u16_t *b = (u16_t*)buf;
- return ntohs(b[1]);
- }
- static void IAP_tftp_set_opcode(char *buffer, tftp_opcode opcode)
- {
- buffer[0] = 0;
- buffer[1] = (u8_t)opcode;
- }
- static void IAP_tftp_set_block(char* packet, u16_t block)
- {
- u16_t *p = (u16_t *)packet;
- p[1] = htons(block);
- }
- static err_t IAP_tftp_send_ack_packet(struct udp_pcb *upcb, const ip_addr_t *to, int to_port, int block)
- {
- err_t err;
- struct pbuf *pkt_buf;
-
- char packet[TFTP_ACK_PKT_LEN];
-
- memset(packet, 0, TFTP_ACK_PKT_LEN *sizeof(char));
-
- IAP_tftp_set_opcode(packet, TFTP_ACK);
-
- IAP_tftp_set_block(packet, block);
-
- pkt_buf = pbuf_alloc(PBUF_TRANSPORT, TFTP_ACK_PKT_LEN, PBUF_POOL);
- if (!pkt_buf)
- {
- DEBUG_ERROR("Can not allocate pbuf\r\n");
- return ERR_MEM;
- }
-
- memcpy(pkt_buf->payload, packet, TFTP_ACK_PKT_LEN);
-
- err = udp_sendto(upcb, pkt_buf, to, to_port);
-
- pbuf_free(pkt_buf);
- return err;
- }
- static void IAP_wrq_recv_callback(void *_args, struct udp_pcb *upcb, struct pbuf *pkt_buf, const ip_addr_t *addr, u16_t port)
- {
- tftp_connection_args *args = (tftp_connection_args *)_args;
- uint32_t data_buffer[128];
- uint16_t count=0;
- if (pkt_buf->len != pkt_buf->tot_len)
- {
- DEBUG_ERROR("Invalid data length\r\n");
- return;
- }
-
- if ((pkt_buf->len > TFTP_DATA_PKT_HDR_LEN) &&
- (IAP_tftp_extract_block(pkt_buf->payload) == (args->block + 1)))
- {
-
- pbuf_copy_partial(pkt_buf, data_buffer, pkt_buf->len - TFTP_DATA_PKT_HDR_LEN,
- TFTP_DATA_PKT_HDR_LEN);
-
- total_count += pkt_buf->len - TFTP_DATA_PKT_HDR_LEN;
-
- count = (pkt_buf->len - TFTP_DATA_PKT_HDR_LEN)/4;
- if (((pkt_buf->len - TFTP_DATA_PKT_HDR_LEN)%4)!=0)
- count++;
-
-
- FLASH_If_Write(Flash_Write_Address, data_buffer ,count);
- Flash_Write_Address += count*4;
-
- args->block++;
-
- (args->tot_bytes) += (pkt_buf->len - TFTP_DATA_PKT_HDR_LEN);
-
- }
- else if (IAP_tftp_extract_block(pkt_buf->payload) == (args->block + 1))
- {
-
- args->block++;
- }
-
-
- IAP_tftp_send_ack_packet(upcb, addr, port, args->block);
-
- if (pkt_buf->len < TFTP_DATA_PKT_LEN_MAX)
- {
- uint8_t endFlag[4]={0x55,0xaa,0x55,0xaa};
- IAP_tftp_cleanup_wr(upcb, args);
- pbuf_free(pkt_buf);
-
- DEBUG_INFO("Total bytes Received: %d byte\r\n", total_count);
- DEBUG_INFO("State: Prog Finished \r\n");
- DEBUG_INFO("Reset the board \r\n");
-
- Flash_Write_Address = NEW_CODE_ADDRESS;
- uint32_t checksum = HAL_CRC_Calculate(&hcrc, (uint32_t *)Flash_Write_Address, ((FLASH_AP_LENGTH-4)>>2));
- Flash_Write_Address = ((uint32_t)(NEW_CODE_ADDRESS+FLASH_AP_LENGTH-4));
- #if defined(DEBUG) || defined(RTOS_STAT)
- DEBUG_INFO("Firmware transfer end, AP CRC checksum, flash: 0x%x, 0x%x\r\n", checksum, *((uint32_t *)Flash_Write_Address) );
- #endif
-
- if(checksum == *((uint32_t *)Flash_Write_Address))
- {
- if (FLASH_If_Write(UPGRADE_REQ_ADDRESS, (uint32_t *)&endFlag[0], 1) == FLASHIF_OK)
- {
- #if defined(DEBUG) || defined(RTOS_STAT)
- DEBUG_INFO("Firmware Confirm Tag write ok..\n\r");
- #endif
- NVIC_SystemReset();
- }
- else
- {
- #if defined(DEBUG) || defined(RTOS_STAT)
- DEBUG_INFO("Firmware Confirm Tag write fail...\n\r");
- #endif
- }
- }
- }
- else
- {
- pbuf_free(pkt_buf);
- return;
- }
- }
- static int IAP_tftp_process_write(struct udp_pcb *upcb, const ip_addr_t *to, int to_port)
- {
- tftp_connection_args *args = NULL;
-
- args = mem_malloc(sizeof *args);
- if (!args)
- {
- DEBUG_ERROR("Memory error \r\n");
- IAP_tftp_cleanup_wr(upcb, args);
- return 0;
- }
- args->op = TFTP_WRQ;
- args->to_ip.addr = to->addr;
- args->to_port = to_port;
-
- args->block = 0;
- args->tot_bytes = 0;
-
- udp_recv(upcb, IAP_wrq_recv_callback, args);
-
- total_count =0;
-
- FLASH_If_Init();
-
-
- FLASH_If_Erase(NEW_CODE_ADDRESS, 3);
-
- Flash_Write_Address = NEW_CODE_ADDRESS;
-
- IAP_tftp_send_ack_packet(upcb, to, to_port, args->block);
- DEBUG_INFO("State: Programming... \r\n");
- return 0;
- }
- static void IAP_tftp_recv_callback(void *arg, struct udp_pcb *upcb, struct pbuf *pkt_buf,
- const ip_addr_t *addr, u16_t port)
- {
- tftp_opcode op;
- struct udp_pcb *upcb_tftp_data;
- err_t err;
- uint32_t i;
- char filename[40],message[46], *ptr;
-
- upcb_tftp_data = udp_new();
- if (!upcb_tftp_data)
- {
-
- DEBUG_ERROR("Can not create pcb \r\n");
- return;
- }
-
-
- err = udp_bind(upcb_tftp_data, IP_ADDR_ANY, 0);
- if (err != ERR_OK)
- {
-
- DEBUG_ERROR("Can not create pcb \r\n");
- return;
- }
- op = IAP_tftp_decode_op(pkt_buf->payload);
- if (op != TFTP_WRQ)
- {
-
- DEBUG_ERROR("Bad TFTP opcode \r\n");
- udp_remove(upcb_tftp_data);
- }
- else
- {
- ptr = pkt_buf->payload;
- ptr = ptr +2;
-
- i= 0;
- while (*(ptr+i)!=0x0)
- {
- i++;
- }
- strncpy(filename, ptr, i+1);
- DEBUG_INFO("IAP using TFTP \r\n");
- sprintf(message, "File: %s",filename);
- DEBUG_INFO("%s\r\n", message);
- DEBUG_INFO("State: Erasing...\r\n");
-
- IAP_tftp_process_write(upcb_tftp_data, addr, port);
- }
- pbuf_free(pkt_buf);
- }
- static void IAP_tftp_cleanup_wr(struct udp_pcb *upcb, tftp_connection_args *args)
- {
-
- mem_free(args);
-
- udp_disconnect(upcb);
-
-
- udp_remove(upcb);
-
-
- udp_recv(UDPpcb, IAP_tftp_recv_callback, NULL);
-
- }
- void IAP_tftpd_init(void)
- {
- err_t err;
- unsigned port = 69;
-
- UDPpcb = udp_new();
- if (!UDPpcb)
- {
-
- DEBUG_ERROR("Can not create pcb \r\n");
- return;
- }
-
- err = udp_bind(UDPpcb, IP_ADDR_ANY, port);
- if (err == ERR_OK)
- {
-
- udp_recv(UDPpcb, IAP_tftp_recv_callback, NULL);
- }
- else
- {
- DEBUG_ERROR("Can not create pcb \r\n");
- }
- }
|