/** * @brief Sends TFTP ACK packet * @param upcb: pointer on udp_pcb structure * @param to: pointer on the receive IP address structure * @param to_port: receive port number * @param block: block number * @retval: err_t: error code */ static err_t IAP_tftp_send_ack_packet(struct udp_pcb *upcb, struct ip_addr *to, int to_port, int block) { err_t err; struct pbuf *pkt_buf; /* Chain of pbuf's to be sent */ /* create the maximum possible size packet that a TFTP ACK packet can be */ char packet[TFTP_ACK_PKT_LEN]; /* define the first two bytes of the packet */ IAP_tftp_set_opcode(packet, TFTP_ACK); /* Specify the block number being ACK'd. * If we are ACK'ing a DATA pkt then the block number echoes that of the DATA pkt being ACK'd (duh) * If we are ACK'ing a WRQ pkt then the block number is always 0 * RRQ packets are never sent ACK pkts by the server, instead the server sends DATA pkts to the * host which are, obviously, used as the "acknowledgement". This saves from having to sEndTransferboth * an ACK packet and a DATA packet for RRQs - see RFC1350 for more info. */ IAP_tftp_set_block(packet, block); /* PBUF_TRANSPORT - specifies the transport layer */ pkt_buf = pbuf_alloc(PBUF_TRANSPORT, TFTP_ACK_PKT_LEN, PBUF_POOL); if (!pkt_buf) /*if the packet pbuf == NULL exit and EndTransfertransmission */ { udp_lcd_y += UPDATE_WORD_SIZE + UPDATE_ROW_DISTANCE; lcd_font24(udp_lcd_x,udp_lcd_y,COLOR_POINT,COLOR_BACK,"> ÒÔÌ«ÍøÉý¼¶³ö´íÁË¡£´íÎó´úÂ룺1",UPDATE_FONT); UDP_AddUpdateError(); // #ifdef USE_LCD // LCD_SetTextColor(Red); // LCD_DisplayStringLine(Line9, (uint8_t*)"Can not allocate pbuf"); // #endif return ERR_MEM; } /* Copy the original data buffer over to the packet buffer's payload */ memcpy(pkt_buf->payload, packet, TFTP_ACK_PKT_LEN); /* Sending packet by UDP protocol */ err = udp_sendto(upcb, pkt_buf, to, to_port); /* free the buffer pbuf */ pbuf_free(pkt_buf); return err; }
/** * @brief Sends TFTP ACK packet * @param upcb: pointer on udp_pcb structure * @param to: pointer on the receive IP address structure * @param to_port: receive port number * @param block: block number * @retval: err_t: error code */ static err_t IAP_tftp_send_ack_packet(struct udp_pcb *upcb, struct ip_addr *to, int to_port, int block) { err_t err; struct pbuf *pkt_buf; /* Chain of pbuf's to be sent */ /* create the maximum possible size packet that a TFTP ACK packet can be */ char packet[TFTP_ACK_PKT_LEN]; memset(packet, 0, TFTP_ACK_PKT_LEN *sizeof(char)); /* define the first two bytes of the packet */ IAP_tftp_set_opcode(packet, TFTP_ACK); /* Specify the block number being ACK'd. * If we are ACK'ing a DATA pkt then the block number echoes that of the DATA pkt being ACK'd (duh) * If we are ACK'ing a WRQ pkt then the block number is always 0 * RRQ packets are never sent ACK pkts by the server, instead the server sends DATA pkts to the * host which are, obviously, used as the "acknowledgement". This saves from having to sEndTransferboth * an ACK packet and a DATA packet for RRQs - see RFC1350 for more info. */ IAP_tftp_set_block(packet, block); /* PBUF_TRANSPORT - specifies the transport layer */ pkt_buf = pbuf_alloc(PBUF_TRANSPORT, TFTP_ACK_PKT_LEN, PBUF_POOL); if (!pkt_buf) /*if the packet pbuf == NULL exit and EndTransfertransmission */ { #ifdef USE_LCD LCD_ErrLog("Can not allocate pbuf\n"); #endif return ERR_MEM; } /* Copy the original data buffer over to the packet buffer's payload */ memcpy(pkt_buf->payload, packet, TFTP_ACK_PKT_LEN); /* Sending packet by UDP protocol */ err = udp_sendto(upcb, pkt_buf, to, to_port); /* free the buffer pbuf */ pbuf_free(pkt_buf); return err; }