/** ************************************************************************** * @file tcp_server.c * @version v2.0.4 * @date 2021-12-31 * @brief implement tcp server ************************************************************************** * Copyright notice & Disclaimer * * The software Board Support Package (BSP) that is made available to * download from Artery official website is the copyrighted work of Artery. * Artery authorizes customers to use, copy, and distribute the BSP * software and its related documentation for the purpose of design and * development in conjunction with Artery microcontrollers. Use of the * software is governed by this copyright notice and the following disclaimer. * * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * ************************************************************************** */ #include "tcp_server.h" #include "http_server.h" #include "lwip/err.h" #include "lwip/tcp.h" #include "string.h" #include "at32_emac.h" #include "netconf.h" #include "SystemDelayInterface.h" #include "at32f435_437.h" #include "cmsis_os2.h" /** @addtogroup AT32F437_periph_examples * @{ */ /** @addtogroup 437_EMAC_tcp_server * @{ */ /** * @brief receive and transmit tcp data * @param arg: the user argument * @param pcb: the tcp_pcb that has received the data * @param p: the packet buffer * @param err: the error value linked with the received data * @retval error value */ // uint8_t dataHTTP[2048]; // uint32_t dataHTTP_len; uint32_t com = 0; uint8_t flashProgramming = 0; tCom01 com01; uint8_t bufWriteTcp[1600]; static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb,struct pbuf *p,err_t err) { // char* pPrintBuf; if(p != NULL) { tcp_recved(pcb, p->tot_len); if (!flashProgramming) { memcpy(&com, p->payload, sizeof(com)); // if (com == 0x02) { // tcp_write(pcb, dataHTTP, dataHTTP_len, 1); // } if (com == 0x01) { memcpy(&com01.BlockInfo, p->payload, sizeof(com01.BlockInfo)); com01.blockCounter = 0; com01.flashPointer = FileTableDescriptorAddress; flash_status_type status; flash_unlock(); uint32_t sectorAddress = FileTableDescriptorAddress; for (int i=0; i<16; ++i) { status = flash_block_erase(sectorAddress); if (FLASH_OPERATE_DONE != status) { //flash_lock(); break; } sectorAddress += 0x10000; } //flash_status_type status = flash_bank2_erase(); flash_lock(); if (status != FLASH_OPERATE_DONE) { pbuf_free(p); tcp_write(pcb, ETH_ERR, strlen(ETH_ERR), 1); return 0; } else { flashProgramming = 1; tcp_write(pcb, ETH_OK, strlen(ETH_OK), 1); } } pbuf_free(p); } else { flash_unlock(); for (uint32_t i=0; itot_len / 4; ++i) { pbuf_copy_partial(p, bufWriteTcp, p->tot_len, 0); pbuf_free(p); flash_word_program(com01.flashPointer, ((uint32_t *) bufWriteTcp)[i]); if (((uint32_t*)com01.flashPointer)[0] != ((uint32_t*)bufWriteTcp)[i]) { flash_lock(); tcp_write(pcb, ETH_ERR, strlen(ETH_ERR), 1); flashProgramming = 0; return 0; } com01.flashPointer += 4; } flash_lock(); ++com01.blockCounter; if (com01.blockCounter == com01.BlockInfo.blockCount) { flashProgramming = 0; } tcp_write(pcb, ETH_OK, strlen(ETH_OK), 1); } //tcp_recved(pcb, p->tot_len); /* Get data length; tot_len: length of tcp data block */ //tcp_write(pcb,p->payload,p->tot_len,TCP_WRITE_FLAG_COPY); /* payload is starting position of TCP data block */ //tcp_output(pcb); } else { tcp_close(pcb); /* TCP server shouldn't close this session actively */ } //pbuf_free(p); /* free the TCP segment */ //free(pPrintBuf); err = ERR_OK; return err; } /** * @brief callback function for receiving data * @param arg: user supplied argument * @param pcb: the tcp_pcb which accepted the connection * @param err: error value * @retval error value */ static err_t tcp_server_accept(void *arg,struct tcp_pcb *pcb,err_t err) { tcp_setprio(pcb, TCP_PRIO_MIN); /* set the priority of callback function, if there are multiple session exist, this function must be called */ tcp_recv(pcb,tcp_server_recv); /* set callbacl function for TCP segments come in */ err = ERR_OK; return err; } /** * @brief initialize tcp server * @param none * @retval none */ void tcp_server_init(void) { struct tcp_pcb *pcb; err_t err; /*****************************************************/ pcb = tcp_new(); /* create TCP protocol control block for communication */ if (!pcb) { return ; } err = tcp_bind(pcb,IP_ADDR_ANY,TCP_LOCAL_PORT); /* bind local IP and port for TCP server */ if(err != ERR_OK) { return ; } pcb = tcp_listen(pcb); /* entering listening status */ tcp_accept(pcb,tcp_server_accept); /* set callback function for connection requestion */ } /* void EMAC_IRQHandler(void) { while(emac_received_packet_size_get() != 0) { lwip_pkt_handle(); } emac_dma_flag_clear(EMAC_DMA_RI_FLAG); emac_dma_flag_clear(EMAC_DMA_NIS_FLAG); } */ /* void httpd_init(void); void vInitEthServer() { nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); error_status status = emac_system_init(); while(status == ERROR); tcpip_stack_init(); tcp_server_init(); httpd_init(); } */ /* void taskEthServer(void *env) { for (;;) { lwip_periodic_handle(SystemGetMs()); SystemDelayMs(300); } } */ /** * @} */ /** * @} */