PageRenderTime 61ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/platform/FNET/fnet_stack/services/tftp/fnet_tftp_srv.c

https://gitlab.com/fuggles/ucos
C | 676 lines | 436 code | 98 blank | 142 comment | 96 complexity | a7eb9bf937410558706699416589901a MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0
  1. /**************************************************************************
  2. *
  3. * Copyright 2011-2015 by Andrey Butok. FNET Community.
  4. * Copyright 2008-2010 by Andrey Butok. Freescale Semiconductor, Inc.
  5. *
  6. ***************************************************************************
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License Version 3
  9. * or later (the "LGPL").
  10. *
  11. * As a special exception, the copyright holders of the FNET project give you
  12. * permission to link the FNET sources with independent modules to produce an
  13. * executable, regardless of the license terms of these independent modules,
  14. * and to copy and distribute the resulting executable under terms of your
  15. * choice, provided that you also meet, for each linked independent module,
  16. * the terms and conditions of the license of that module.
  17. * An independent module is a module which is not derived from or based
  18. * on this library.
  19. * If you modify the FNET sources, you may extend this exception
  20. * to your version of the FNET sources, but you are not obligated
  21. * to do so. If you do not wish to do so, delete this
  22. * exception statement from your version.
  23. *
  24. * This program is distributed in the hope that it will be useful,
  25. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  27. *
  28. * You should have received a copy of the GNU General Public License
  29. * and the GNU Lesser General Public License along with this program.
  30. * If not, see <http://www.gnu.org/licenses/>.
  31. *
  32. **********************************************************************/ /*!
  33. *
  34. * @file fnet_tftp_srv.c
  35. *
  36. * @author Andrey Butok
  37. *
  38. * @brief TFTP Server implementation.
  39. *
  40. ***************************************************************************/
  41. #include "fnet.h"
  42. #if FNET_CFG_TFTP_SRV
  43. #include "stack/fnet_netif_prv.h"
  44. #if FNET_CFG_DEBUG_TFTP_SRV
  45. #define FNET_DEBUG_TFTP_SRV FNET_DEBUG
  46. #else
  47. #define FNET_DEBUG_TFTP_SRV(...)
  48. #endif
  49. /************************************************************************
  50. * Definitions
  51. *************************************************************************/
  52. #define FNET_TFTP_MODE_SIZE_MAX (9)
  53. #define FNET_TFTP_FILENAME_SIZE_MAX (FNET_TFTP_DATA_SIZE_MAX-FNET_TFTP_MODE_SIZE_MAX)
  54. #define FNET_TFTP_OPCODE_READ_REQUEST (1)
  55. #define FNET_TFTP_OPCODE_WRITE_REQUEST (2)
  56. #define FNET_TFTP_OPCODE_DATA (3)
  57. #define FNET_TFTP_OPCODE_ACK (4)
  58. #define FNET_TFTP_OPCODE_ERROR (5)
  59. #define FNET_TFTP_ERR_PARAMS "ERROR: Wrong input parameters."
  60. #define FNET_TFTP_ERR_SOCKET_CREATION "ERROR: Socket creation error."
  61. #define FNET_TFTP_ERR_SOCKET_BIND "ERROR: Socket Error during bind."
  62. #define FNET_TFTP_ERR_SERVICE "ERROR: Service registration is failed."
  63. #define FNET_TFTP_ERR_IS_INITIALIZED "ERROR: TFTP Server is already initialized."
  64. /* TFTP packets:*/
  65. FNET_COMP_PACKED_BEGIN
  66. struct fnet_tftp_packet_request
  67. {
  68. unsigned short opcode FNET_COMP_PACKED;
  69. unsigned char filename_mode[FNET_TFTP_DATA_SIZE_MAX] FNET_COMP_PACKED; /* Filename, Mode */
  70. };
  71. FNET_COMP_PACKED_END
  72. FNET_COMP_PACKED_BEGIN
  73. struct fnet_tftp_packet_data
  74. {
  75. unsigned short opcode FNET_COMP_PACKED;
  76. unsigned short block_number FNET_COMP_PACKED;
  77. unsigned char data[FNET_TFTP_DATA_SIZE_MAX] FNET_COMP_PACKED;
  78. };
  79. FNET_COMP_PACKED_END
  80. FNET_COMP_PACKED_BEGIN
  81. struct fnet_tftp_packet_ack
  82. {
  83. unsigned short opcode FNET_COMP_PACKED;
  84. unsigned short block_number FNET_COMP_PACKED;
  85. };
  86. FNET_COMP_PACKED_END
  87. FNET_COMP_PACKED_BEGIN
  88. struct fnet_tftp_packet_error
  89. {
  90. unsigned short opcode FNET_COMP_PACKED;
  91. unsigned short error_code FNET_COMP_PACKED;
  92. char error_message[FNET_TFTP_DATA_SIZE_MAX] FNET_COMP_PACKED;
  93. };
  94. FNET_COMP_PACKED_END
  95. const static char *fnet_tftp_srv_error[] =
  96. {
  97. "Not defined", /* see error message (if any).*/
  98. "File not found",
  99. "Access violation",
  100. "Disk full or allocation exceeded",
  101. "Illegal TFTP operation",
  102. "Unknown transfer ID",
  103. "File already exists",
  104. "No such user"
  105. };
  106. #define FNET_TFTP_SRV_ERR_MAX (sizeof(fnet_tftp_srv_error)/sizeof(char*))
  107. /************************************************************************
  108. * TFTP server interface structure
  109. *************************************************************************/
  110. struct fnet_tftp_srv_if
  111. {
  112. fnet_tftp_srv_state_t state; /* Current state.*/
  113. SOCKET socket_listen; /* Listening socket.*/
  114. SOCKET socket_transaction; /* Socket servicing transaction.*/
  115. struct sockaddr addr_transaction;
  116. fnet_poll_desc_t service_descriptor;
  117. fnet_tftp_srv_request_handler_t request_handler;
  118. fnet_tftp_srv_data_handler_t data_handler;
  119. fnet_tftp_srv_complete_handler_t complete_handler;
  120. int complete_status; /* FNET_OK or FNET_ERR */
  121. void *handler_param; /* Handler specific parameter. */
  122. fnet_tftp_request_t request_type;
  123. void (*request_send)(struct fnet_tftp_srv_if *tftp_srv_if);
  124. unsigned short block_number_ack; /* Acknoladged block number. */
  125. unsigned long last_time; /* Last receive time, used for timeout detection. */
  126. unsigned long timeout; /* Timeout in ms. */
  127. unsigned int retransmit_max;
  128. unsigned int retransmit_cur;
  129. union
  130. {
  131. struct fnet_tftp_packet_request packet_request;
  132. struct fnet_tftp_packet_data packet_data;
  133. struct fnet_tftp_packet_ack packet_ack;
  134. struct fnet_tftp_packet_error packet_error;
  135. };
  136. unsigned long packet_size;
  137. int tx_data_size;
  138. };
  139. /* The TFTP Server interface */
  140. static struct fnet_tftp_srv_if tftp_srv_if_list[FNET_CFG_TFTP_SRV_MAX];
  141. /************************************************************************
  142. * Function Prototypes
  143. *************************************************************************/
  144. static void fnet_tftp_srv_state_machine(void *tftp_srv_if_p);
  145. static void fnet_tftp_srv_send_error(struct fnet_tftp_srv_if *tftp_srv_if, SOCKET s, unsigned short error_code, const char *error_message, struct sockaddr *dest_addr);
  146. static void fnet_tftp_srv_send_data(struct fnet_tftp_srv_if *tftp_srv_if);
  147. static void fnet_tftp_srv_send_ack(struct fnet_tftp_srv_if *tftp_srv_if);
  148. static int fnet_tftp_srv_data_handler(struct fnet_tftp_srv_if *tftp_srv_if, unsigned short data_size);
  149. /************************************************************************
  150. * NAME: fnet_tftp_srv_init
  151. *
  152. * DESCRIPTION: TFTP server initialization.
  153. ************************************************************************/
  154. fnet_tftp_srv_desc_t fnet_tftp_srv_init( struct fnet_tftp_srv_params *params )
  155. {
  156. struct sockaddr local_addr;
  157. int i;
  158. struct fnet_tftp_srv_if *tftp_srv_if = 0;
  159. /* Check input paramters. */
  160. if((params == 0) || (params->data_handler == 0) || (params->request_handler==0))
  161. {
  162. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Wrong init parameters.");
  163. goto ERROR_1;
  164. }
  165. /* Try to find free TFTP server descriptor. */
  166. for(i=0; i < FNET_CFG_TFTP_SRV_MAX; i++)
  167. {
  168. if(tftp_srv_if_list[i].state == FNET_TFTP_SRV_STATE_DISABLED)
  169. {
  170. tftp_srv_if = &tftp_srv_if_list[i];
  171. }
  172. }
  173. if(tftp_srv_if == 0)
  174. {
  175. /* No free TFTP server descriptor. */
  176. FNET_DEBUG_TFTP_SRV("TFTP_SRV: No free TFTP Server.");
  177. goto ERROR_1;
  178. }
  179. /* Reset interface structure. */
  180. fnet_memset_zero(tftp_srv_if, sizeof(struct fnet_tftp_srv_if));
  181. tftp_srv_if->request_handler = params->request_handler;
  182. tftp_srv_if->data_handler = params->data_handler;
  183. tftp_srv_if->complete_handler = params->complete_handler;
  184. tftp_srv_if->handler_param = params->handler_param;
  185. if(params->timeout == 0 )
  186. tftp_srv_if->timeout = FNET_CFG_TFTP_SRV_TIMEOUT;
  187. else
  188. tftp_srv_if->timeout = (unsigned long) params->timeout;
  189. tftp_srv_if->timeout = tftp_srv_if->timeout*1000/FNET_TIMER_PERIOD_MS;
  190. if(params->retransmit_max == 0 )
  191. tftp_srv_if->retransmit_max = FNET_CFG_TFTP_SRV_RETRANSMIT_MAX;
  192. else
  193. tftp_srv_if->retransmit_max = params->retransmit_max;
  194. tftp_srv_if->socket_transaction = SOCKET_INVALID;
  195. local_addr = params->address;
  196. if(local_addr.sa_port == 0)
  197. local_addr.sa_port = FNET_CFG_TFTP_SRV_PORT; /* Aply the default port. */
  198. if(local_addr.sa_family == AF_UNSPEC)
  199. local_addr.sa_family = AF_SUPPORTED; /* Asign supported families.*/
  200. /* Create listen socket */
  201. if((tftp_srv_if->socket_listen = socket(local_addr.sa_family, SOCK_DGRAM, 0)) == SOCKET_INVALID)
  202. {
  203. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Socket creation error.");
  204. goto ERROR_1;
  205. }
  206. if(bind(tftp_srv_if->socket_listen, &local_addr, sizeof(local_addr)) == SOCKET_ERROR)
  207. {
  208. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Socket bind error.");
  209. goto ERROR_2;
  210. }
  211. /* Register service. */
  212. tftp_srv_if->service_descriptor = fnet_poll_service_register(fnet_tftp_srv_state_machine, (void *) tftp_srv_if);
  213. if(tftp_srv_if->service_descriptor == (fnet_poll_desc_t)FNET_ERR)
  214. {
  215. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Service registration error.");
  216. goto ERROR_2;
  217. }
  218. tftp_srv_if->state = FNET_TFTP_SRV_STATE_WAITING_REQUEST; /* => Send WAITING_REQUEST */
  219. return (fnet_tftp_srv_desc_t)tftp_srv_if;
  220. ERROR_2:
  221. closesocket(tftp_srv_if->socket_listen);
  222. ERROR_1:
  223. return FNET_ERR;
  224. }
  225. /************************************************************************
  226. * NAME: fnet_tftp_srv_send_error
  227. *
  228. * DESCRIPTION: Send TFTP error packet.
  229. ************************************************************************/
  230. static void fnet_tftp_srv_send_error(struct fnet_tftp_srv_if *tftp_srv_if, SOCKET s, unsigned short error_code, const char *error_message, struct sockaddr *dest_addr)
  231. {
  232. /* 2 bytes 2 bytes string 1 byte
  233. ------------------------------------------
  234. ERROR | 05 | ErrorCode | ErrMsg | 0 |
  235. ------------------------------------------
  236. */
  237. tftp_srv_if->packet_error.opcode = FNET_HTONS(FNET_TFTP_OPCODE_ERROR);
  238. tftp_srv_if->packet_error.error_code = fnet_htons(error_code);
  239. if((error_message == 0) && (error_code < FNET_TFTP_SRV_ERR_MAX))
  240. error_message = fnet_tftp_srv_error[error_code]; /* Stanndard error message acording to RFC783. */
  241. if(error_message)
  242. fnet_strncpy( tftp_srv_if->packet_error.error_message, error_message, FNET_TFTP_DATA_SIZE_MAX-1 );
  243. else
  244. tftp_srv_if->packet_error.error_message[0] = 0;
  245. sendto(s, (char*)&tftp_srv_if->packet_error, (int)(fnet_strlen(error_message)+(2+2+1)), 0,
  246. dest_addr, sizeof(*dest_addr));
  247. }
  248. /************************************************************************
  249. * NAME: fnet_tftp_srv_send_data
  250. *
  251. * DESCRIPTION: Send TFTP data packet.
  252. ************************************************************************/
  253. static void fnet_tftp_srv_send_data(struct fnet_tftp_srv_if *tftp_srv_if)
  254. {
  255. /* Send data. */
  256. tftp_srv_if->packet_data.opcode = FNET_HTONS(FNET_TFTP_OPCODE_DATA);
  257. tftp_srv_if->packet_data.block_number = fnet_htons(tftp_srv_if->block_number_ack);
  258. sendto(tftp_srv_if->socket_transaction, (char*)&tftp_srv_if->packet_data, (4+tftp_srv_if->tx_data_size), 0,
  259. &tftp_srv_if->addr_transaction, sizeof(tftp_srv_if->addr_transaction) );
  260. /* Reset timeout. */
  261. tftp_srv_if->last_time = fnet_timer_ticks();
  262. }
  263. /************************************************************************
  264. * NAME: fnet_tftp_srv_send_ack
  265. *
  266. * DESCRIPTION: Send TFTP acknowledge packet.
  267. ************************************************************************/
  268. static void fnet_tftp_srv_send_ack(struct fnet_tftp_srv_if *tftp_srv_if)
  269. {
  270. /* Send acknowledge. */
  271. tftp_srv_if->packet_ack.opcode = FNET_HTONS(FNET_TFTP_OPCODE_ACK);
  272. tftp_srv_if->packet_ack.block_number = fnet_htons(tftp_srv_if->block_number_ack);
  273. sendto(tftp_srv_if->socket_transaction, (char*)&tftp_srv_if->packet_ack, sizeof(struct fnet_tftp_packet_ack), 0,
  274. &tftp_srv_if->addr_transaction, sizeof(tftp_srv_if->addr_transaction) );
  275. /* Reset timeout. */
  276. tftp_srv_if->last_time = fnet_timer_ticks();
  277. }
  278. /************************************************************************
  279. * NAME: fnet_tftp_srv_send_ack
  280. *
  281. * DESCRIPTION: Call TFTP data handler.
  282. ************************************************************************/
  283. static int fnet_tftp_srv_data_handler(struct fnet_tftp_srv_if *tftp_srv_if, unsigned short data_size)
  284. {
  285. fnet_tftp_error_t error_code = FNET_TFTP_ERROR_NOT_DEFINED;
  286. char *error_message = 0;
  287. int result;
  288. if((result = tftp_srv_if->data_handler( tftp_srv_if->request_type,
  289. (unsigned char *)&tftp_srv_if->packet_data.data[0],
  290. data_size,
  291. &error_code,
  292. &error_message,
  293. tftp_srv_if->handler_param)) == FNET_ERR)
  294. {
  295. /* Send error. */
  296. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_transaction, error_code, error_message, &tftp_srv_if->addr_transaction);
  297. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE; /* => CLOSE */
  298. }
  299. else
  300. tftp_srv_if->block_number_ack ++;
  301. return result;
  302. }
  303. /************************************************************************
  304. * NAME: fnet_tftp_srv_state_machine
  305. *
  306. * DESCRIPTION: TFTP server state machine.
  307. ************************************************************************/
  308. static void fnet_tftp_srv_state_machine( void *fnet_tftp_srv_if_p )
  309. {
  310. struct sockaddr addr;
  311. unsigned int addr_len;
  312. int received;
  313. struct fnet_tftp_srv_if *tftp_srv_if = (struct fnet_tftp_srv_if *)fnet_tftp_srv_if_p;
  314. fnet_tftp_error_t error_code;
  315. char *error_message;
  316. char *filename; /* null-terminated.*/
  317. char *mode; /* null-terminated.*/
  318. int i;
  319. int result;
  320. switch(tftp_srv_if->state)
  321. {
  322. /*---- WAITING_REQUEST --------------------------------------------*/
  323. case FNET_TFTP_SRV_STATE_WAITING_REQUEST:
  324. addr_len = sizeof(addr);
  325. received = recvfrom(tftp_srv_if->socket_listen, (char*)&tftp_srv_if->packet_request,
  326. (int)sizeof(struct fnet_tftp_packet_request), 0,
  327. &addr, &addr_len );
  328. if(received >= 4)
  329. {
  330. /* Extract opcode, filename and mode. */
  331. /* 2 bytes string 1 byte string 1 byte
  332. * ----------------------------------------------------
  333. * RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
  334. * WRQ ----------------------------------------------------
  335. */
  336. result = FNET_OK;
  337. /* Set default error message. */
  338. error_code = FNET_TFTP_ERROR_NOT_DEFINED;
  339. error_message = 0;
  340. switch(tftp_srv_if->packet_request.opcode)
  341. {
  342. case FNET_HTONS(FNET_TFTP_OPCODE_READ_REQUEST):
  343. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Get Read request.");
  344. tftp_srv_if->request_type = FNET_TFTP_REQUEST_READ;
  345. break;
  346. case FNET_HTONS(FNET_TFTP_OPCODE_WRITE_REQUEST):
  347. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Get Write request.");
  348. tftp_srv_if->request_type = FNET_TFTP_REQUEST_WRITE;
  349. break;
  350. default:
  351. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Get wrong request (%d).", fnet_ntohs(tftp_srv_if->packet_request.opcode));
  352. result = FNET_ERR;
  353. return;
  354. }
  355. if(result == FNET_OK)
  356. {
  357. received -= 2;
  358. /* Get filename. */
  359. filename = (char *)tftp_srv_if->packet_request.filename_mode;
  360. for(i = 0; i < received; i++)
  361. {
  362. if(filename[i] == 0)
  363. {
  364. break; /* Found end of file name. */
  365. }
  366. }
  367. i++;
  368. /* Get mode.*/
  369. mode = &filename[i];
  370. for(; i < received; i++)
  371. {
  372. if(filename[i] == 0)
  373. {
  374. break; /* Found end of mode. */
  375. }
  376. }
  377. if( i < received)
  378. {
  379. result = tftp_srv_if->request_handler(tftp_srv_if->request_type,
  380. &addr,
  381. filename, /* null-terminated.*/
  382. mode, /* null-terminated.*/
  383. &error_code,
  384. &error_message,
  385. tftp_srv_if->handler_param);
  386. }
  387. else
  388. result = FNET_ERR;
  389. }
  390. if(result == FNET_OK)
  391. {
  392. tftp_srv_if->complete_status = FNET_ERR; /* Set default value.*/
  393. /* Create a socket for the new transaction. */
  394. if((tftp_srv_if->socket_transaction = socket(addr.sa_family, SOCK_DGRAM, 0)) == SOCKET_INVALID)
  395. {
  396. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Socket creation error.");
  397. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_listen, FNET_TFTP_ERROR_NOT_DEFINED, 0, &addr);
  398. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE; /* => CLOSE */
  399. }
  400. else
  401. {
  402. /* Save the client address.*/
  403. tftp_srv_if->addr_transaction = addr;
  404. /* Bind new socket. */
  405. addr.sa_port = FNET_HTONS(0);
  406. fnet_memset_zero(addr.sa_data, sizeof(addr.sa_data));
  407. if(bind(tftp_srv_if->socket_transaction, &addr, sizeof(addr)) == SOCKET_ERROR)
  408. {
  409. FNET_DEBUG_TFTP_SRV("TFTP_SRV: Socket bind error.");
  410. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_listen, FNET_TFTP_ERROR_NOT_DEFINED, 0, &addr);
  411. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE; /* => CLOSE */
  412. }
  413. else
  414. {
  415. tftp_srv_if->block_number_ack = 0;
  416. /* REQUEST_WRITE. */
  417. if(tftp_srv_if->request_type == FNET_TFTP_REQUEST_WRITE)
  418. {
  419. tftp_srv_if->request_send = fnet_tftp_srv_send_ack;
  420. }
  421. /* REQUEST_READ. */
  422. else
  423. {
  424. /* Data handler.*/
  425. if((tftp_srv_if->tx_data_size = fnet_tftp_srv_data_handler(tftp_srv_if, (unsigned short)(sizeof(tftp_srv_if->packet_data.data)))) == FNET_ERR)
  426. break;
  427. tftp_srv_if->request_send = fnet_tftp_srv_send_data;
  428. }
  429. /* Send. */
  430. tftp_srv_if->request_send(tftp_srv_if);
  431. tftp_srv_if->state = FNET_TFTP_SRV_STATE_HANDLE_REQUEST; /* => HANDLE_REQUEST */
  432. tftp_srv_if->retransmit_cur = 0;
  433. }
  434. }
  435. }
  436. else
  437. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_listen, error_code, error_message, &addr);
  438. }
  439. break;
  440. /*---- HANDLE_REQUEST -----------------------------------------------*/
  441. case FNET_TFTP_SRV_STATE_HANDLE_REQUEST:
  442. addr_len = sizeof(addr);
  443. received = recvfrom(tftp_srv_if->socket_transaction, (char*)&tftp_srv_if->packet_data, sizeof(struct fnet_tftp_packet_data), 0,
  444. &addr, &addr_len );
  445. if(received >= 4)
  446. {
  447. FNET_DEBUG_TFTP_SRV("TFTP_SRV:HANDLE_REQUEST");
  448. /* Error. */
  449. if ( (received == SOCKET_ERROR) || (tftp_srv_if->packet_data.opcode == FNET_HTONS(FNET_TFTP_OPCODE_ERROR)) )
  450. {
  451. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE;
  452. }
  453. /* Check TID. */
  454. else if ( (tftp_srv_if->addr_transaction.sa_port != addr.sa_port) ||
  455. !fnet_socket_addr_are_equal(&tftp_srv_if->addr_transaction, &addr) )
  456. {
  457. FNET_DEBUG_TFTP_SRV( "\nWARNING: Block not from our server!" );
  458. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_transaction, FNET_TFTP_ERROR_UNKNOWN_TID, 0, &addr);
  459. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE;
  460. }
  461. /* Received ACK. */
  462. else if ((tftp_srv_if->request_type == FNET_TFTP_REQUEST_READ) && (tftp_srv_if->packet_data.opcode == FNET_HTONS(FNET_TFTP_OPCODE_ACK)))
  463. {
  464. if(tftp_srv_if->block_number_ack == fnet_ntohs(tftp_srv_if->packet_data.block_number)) /* Correct ACK. */
  465. {
  466. /* If last ACK. */
  467. if(tftp_srv_if->tx_data_size < sizeof(tftp_srv_if->packet_data.data))
  468. {
  469. tftp_srv_if->complete_status = FNET_OK;
  470. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE;
  471. break;
  472. }
  473. /* More data to send. */
  474. else
  475. {
  476. /* Data handler.*/
  477. if((tftp_srv_if->tx_data_size = fnet_tftp_srv_data_handler(tftp_srv_if, (unsigned short)(sizeof(tftp_srv_if->packet_data.data)))) == FNET_ERR)
  478. break;
  479. tftp_srv_if->retransmit_cur = 0;
  480. }
  481. }
  482. /* else: Resend last packet. */
  483. /* Send. */
  484. tftp_srv_if->request_send(tftp_srv_if);
  485. }
  486. /* Received Data. */
  487. else if ((tftp_srv_if->request_type == FNET_TFTP_REQUEST_WRITE) && (tftp_srv_if->packet_data.opcode == FNET_HTONS(FNET_TFTP_OPCODE_DATA)) )
  488. {
  489. if((tftp_srv_if->block_number_ack + 1) == fnet_ntohs(tftp_srv_if->packet_data.block_number))
  490. {
  491. /* Data handler.*/
  492. if(fnet_tftp_srv_data_handler(tftp_srv_if, (unsigned short)(received - 4)) == FNET_ERR)
  493. break;
  494. /* Check return result.*/
  495. if(received < sizeof(struct fnet_tftp_packet_data)) /* EOF */
  496. {
  497. tftp_srv_if->complete_status = FNET_OK;
  498. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE; /* => CLOSE */
  499. }
  500. tftp_srv_if->retransmit_cur = 0;
  501. }
  502. /* Send ACK. */
  503. tftp_srv_if->request_send(tftp_srv_if);
  504. }
  505. else /* Wrong opration. */
  506. {
  507. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_transaction, FNET_TFTP_ERROR_ILLEGAL_OPERATION, 0, &addr);
  508. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE;
  509. }
  510. }
  511. /* Error. */
  512. if ( received == SOCKET_ERROR)
  513. {
  514. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE;
  515. }
  516. /* Check timeout */
  517. else if(fnet_timer_get_interval(tftp_srv_if->last_time, fnet_timer_ticks()) > (tftp_srv_if->timeout))
  518. {
  519. /* Retransmit */
  520. if(tftp_srv_if->retransmit_cur < tftp_srv_if->retransmit_max)
  521. {
  522. tftp_srv_if->retransmit_cur++;
  523. tftp_srv_if->request_send(tftp_srv_if);
  524. }
  525. else
  526. tftp_srv_if->state = FNET_TFTP_SRV_STATE_CLOSE;
  527. }
  528. break;
  529. /*---- CLOSING --------------------------------------------*/
  530. default:
  531. case FNET_TFTP_SRV_STATE_CLOSE:
  532. FNET_DEBUG_TFTP_SRV("TFTP_SRV: STATE_CLOSING");
  533. if(tftp_srv_if->socket_transaction != SOCKET_INVALID)
  534. {
  535. closesocket(tftp_srv_if->socket_transaction);
  536. tftp_srv_if->socket_transaction = SOCKET_INVALID;
  537. }
  538. /* Call complete handler. */
  539. if(tftp_srv_if->complete_handler)
  540. tftp_srv_if->complete_handler(tftp_srv_if->request_type, tftp_srv_if->complete_status, tftp_srv_if->handler_param);
  541. tftp_srv_if->state = FNET_TFTP_SRV_STATE_WAITING_REQUEST; /*=> WAITING_REQUEST */
  542. break;
  543. }
  544. }
  545. /************************************************************************
  546. * NAME: fnet_tftp_srv_release
  547. *
  548. * DESCRIPTION: TFTP server release.
  549. ************************************************************************/
  550. void fnet_tftp_srv_release(fnet_tftp_srv_desc_t desc)
  551. {
  552. struct fnet_tftp_srv_if *tftp_srv_if = (struct fnet_tftp_srv_if *)desc;
  553. if(tftp_srv_if && (tftp_srv_if->state != FNET_TFTP_SRV_STATE_DISABLED))
  554. {
  555. if(tftp_srv_if->state == FNET_TFTP_SRV_STATE_HANDLE_REQUEST)
  556. fnet_tftp_srv_send_error(tftp_srv_if, tftp_srv_if->socket_transaction, FNET_TFTP_ERROR_NOT_DEFINED, 0, &tftp_srv_if->addr_transaction);
  557. closesocket(tftp_srv_if->socket_listen);
  558. closesocket(tftp_srv_if->socket_transaction);
  559. fnet_poll_service_unregister(tftp_srv_if->service_descriptor); /* Delete service.*/
  560. tftp_srv_if->state = FNET_TFTP_SRV_STATE_DISABLED;
  561. }
  562. }
  563. /************************************************************************
  564. * NAME: fnet_tftp_srv_state
  565. *
  566. * DESCRIPTION: This function returns a current state of the TFTP server.
  567. ************************************************************************/
  568. fnet_tftp_srv_state_t fnet_tftp_srv_state(fnet_tftp_srv_desc_t desc)
  569. {
  570. struct fnet_tftp_srv_if *tftp_srv_if = (struct fnet_tftp_srv_if *) desc;
  571. fnet_tftp_srv_state_t result;
  572. if(tftp_srv_if)
  573. result = tftp_srv_if->state;
  574. else
  575. result = FNET_TFTP_SRV_STATE_DISABLED;
  576. return result;
  577. }
  578. #endif