tftp.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Copyright (C) 2002-2004 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
  21. * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. */
  32. /*
  33. * $Log$
  34. * Revision 1.3 2005/11/03 15:11:58 haraldkipp
  35. * Make use of the new memset/memcpy routines.
  36. * Some globals replaced by CONF structures.
  37. * Use enut.bin as a default image name.
  38. *
  39. * Revision 1.2 2004/01/30 18:18:55 haraldkipp
  40. * Bugfix. Loading programs > 64k failed
  41. *
  42. * Revision 1.1 2003/11/03 16:19:38 haraldkipp
  43. * First release
  44. *
  45. */
  46. #include <avr/io.h>
  47. #include <avr/pgmspace.h>
  48. #include <avr/boot.h>
  49. #include <string.h>
  50. #include "debug.h"
  51. #include "appload.h"
  52. #include "tftp.h"
  53. /*!
  54. * \addtogroup xgTftp
  55. */
  56. /*@{*/
  57. /*
  58. * Write the contents of a buffer to a specified program memory address.
  59. *
  60. * \param addr Program memory byte address to start writing.
  61. * \param data Points to a buffer which contains the data to be written.
  62. *
  63. * \todo Would be fine to verify the result and return a result to the
  64. * caller.
  65. */
  66. void FlashPage(unsigned short page, unsigned char *data)
  67. {
  68. unsigned long i;
  69. unsigned long addr;
  70. addr = (unsigned long)page << 8;
  71. /*
  72. * Erase page.
  73. */
  74. boot_page_erase(addr);
  75. while (boot_rww_busy()) {
  76. boot_rww_enable();
  77. }
  78. /*
  79. * Fill page buffer.
  80. */
  81. for (i = addr; i < addr + SPM_PAGESIZE; i += 2) {
  82. boot_page_fill(i, *data + (*(data + 1) << 8));
  83. data += 2;
  84. }
  85. /*
  86. * Write page.
  87. */
  88. boot_page_write(addr);
  89. while (boot_rww_busy()) {
  90. boot_rww_enable();
  91. }
  92. }
  93. /*!
  94. * \brief Download a file from a TFTP server and burn it into the flash ROM.
  95. *
  96. * \return 0 on success, -1 otherwise.
  97. */
  98. int TftpRecv(void)
  99. {
  100. u_char retry;
  101. int rlen = 0;
  102. int slen;
  103. u_short tport = TPORT;
  104. u_short block = 0;
  105. u_char *cp;
  106. u_char *cp1;
  107. /*
  108. * Do nothing if there's no TFTP host configured.
  109. */
  110. if(confboot.cb_tftp_ip == 0) {
  111. return 0;
  112. }
  113. /*
  114. * Prepare the transmit buffer for a file request.
  115. */
  116. sframe.u.tftp.th_opcode = TFTP_RRQ;
  117. slen = 2;
  118. cp = sframe.u.tftp.th_u.tu_stuff;
  119. cp1 = confboot.cb_image;
  120. if (*cp1 == 0) {
  121. cp1 = "enut.bin";
  122. }
  123. do {
  124. *cp = *cp1++;
  125. slen++;
  126. } while (*cp++);
  127. memcpy_(cp, "octet", 6);
  128. slen += 6;
  129. /*
  130. * Lopp until we receive a packet with less than 512 bytes of data.
  131. */
  132. do {
  133. /*
  134. * Send file request or acknowledge and receive
  135. * a data block.
  136. */
  137. for (retry = 0; retry < 3; retry++) {
  138. if (UdpOutput(confboot.cb_tftp_ip, tport, SPORT, slen) >= 0) {
  139. if ((rlen = UdpInput(SPORT, 5000)) >= 4)
  140. break;
  141. }
  142. }
  143. /*
  144. * Can't reach the TFTP server or got a malformed
  145. * repsonse.
  146. */
  147. if (retry >= 3 || rlen < 4) {
  148. return -1;
  149. }
  150. /*
  151. * Accept data blocks only. Anything else will stop
  152. * the transfer with an error.
  153. */
  154. if (ntohs(rframe.u.tftp.th_opcode) != TFTP_DATA)
  155. return -1;
  156. /*
  157. * If this was the first block we received, prepare
  158. * the send buffer for sending ACKs.
  159. */
  160. if (block == 0) {
  161. tport = rframe.udp_hdr.uh_sport;
  162. sframe.u.tftp.th_opcode = TFTP_ACK;
  163. slen = 4;
  164. }
  165. /*
  166. * If this block is out of sequence, we ignore it.
  167. * However, if we missed the first block, return
  168. * with an error.
  169. */
  170. if (ntohs(rframe.u.tftp.th_u.tu_block) != block + 1) {
  171. if (block == 0) {
  172. return -1;
  173. }
  174. continue;
  175. }
  176. /*
  177. * Burn the received data into the flash ROM.
  178. */
  179. if (rlen > 4) {
  180. FlashPage(block << 1, rframe.u.tftp.th_data);
  181. if (rlen > 260)
  182. FlashPage((block << 1) + 1, &rframe.u.tftp.th_data[256]);
  183. }
  184. /*
  185. * Update our block counter.
  186. */
  187. block++;
  188. sframe.u.tftp.th_u.tu_block = htons(block);
  189. } while (rlen >= 516);
  190. /*
  191. * Send the last ACK.
  192. */
  193. UdpOutput(confboot.cb_tftp_ip, tport, SPORT, slen);
  194. return 0;
  195. }
  196. /*@}*/