Refactor to use new protocol module and sipo.
[bertos.git] / bertos / net / tftp.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief TFTP protocol implementation
34  *
35  * This module implements a TFTP server with a handy KFile interface.
36  * The call to tftp_listen() will block until a client tries to connect,
37  * then it returns a KFile.
38  * If you want to accept the transfer, start reading from the handle and
39  * the transfer will continue. Otherwise, don't access it and immediately
40  * call kfile_close().
41  * Close the KFile when you're done.
42  *
43  * The usage pattern is as follows:
44  * \code
45  * // initialize a TFTP session
46  * tftp_init();
47  * // start listening for connections
48  * KFile *f = tftp_listen();
49  * // now you can check the returned file name
50  * // and change behaviour at runtime
51  * if (!strcmp(filename, "firmware.bin"))
52  *     // do something
53  * else if (!strcmp(filename, "conf.ini"))
54  *     // update the configuration
55  * kfile_close(f);
56  * \endcode
57  *
58  *
59  * \author Luca Ottaviano <lottaviano@develer.com>
60  *
61  * $WIZ$ module_name = "tftp"
62  * $WIZ$ module_configuration = "bertos/cfg/cfg_tftp.h"
63  * $WIZ$ module_depends = "lwip", "kfile"
64  */
65
66 #ifndef TFTP_H
67 #define TFTP_H
68
69 #include <cfg/compiler.h>
70 #include <lwip/sockets.h> // sockaddr_in, socklen_t
71 #include <io/kfile.h>
72
73 #define TFTP_RRQ     0x0100     /* TFTP read request packet (already in net endianess). */
74 #define TFTP_WRQ     0x0200     /* TFTP write request packet (already in net endianess). */
75 #define TFTP_DATA    03         /* TFTP data packet. */
76 #define TFTP_ACK     0x0400     /* TFTP acknowledgement packet (already in net endianess). */
77 #define TFTP_PROTOERR     0x0500     /* TFTP acknowledgement packet (already in net endianess). */
78
79 /* TFTP protocol error codes */
80 #define TFTP_PROTOERR_ACCESS_VIOLATION 0x0200
81
82 #define TFTP_SERVER_PORT 69
83
84 /* Return error codes */
85 #define TFTP_ERR_TIMEOUT -2
86 #define TFTP_ERR         -1
87
88 struct PACKED TftpHeader
89 {
90         short opcode;            ///< packet type */
91         union PACKED
92         {
93                 short block;         /* block # */
94                 short code;          /* error code */
95                 char stuff[1];       /* request packet stuff */
96         } th_u;
97 };
98
99 typedef struct PACKED Tftpframe {
100         struct TftpHeader hdr;
101         char data[512];          /* data or error string */
102 } Tftpframe;
103
104 struct PACKED ackframe
105 {
106         short opcode;
107         short block_num;
108 };
109
110 struct PACKED errframe
111 {
112         short opcode;
113         short errcode;
114         char str;
115 };
116
117 typedef enum
118 {
119         TFTP_READ,
120         TFTP_WRITE,
121 } TftpOpenMode;
122
123 typedef struct TftpSession
124 {
125         struct sockaddr_in addr;
126         socklen_t addr_len;
127         int sock;
128         unsigned short block;
129         mtime_t timeout;
130         int error;
131         Tftpframe frame;
132         size_t bytes_available;
133         size_t valid_data;
134         bool is_xfer_end;
135         bool pending_ack;
136         KFile kfile_request;
137 } TftpSession;
138
139 int tftp_init(TftpSession *ctx, unsigned short port, mtime_t timeout);
140 KFile *tftp_listen(TftpSession *ctx, char *filename, size_t len, TftpOpenMode *mode);
141
142 #endif // TFTP_H