1 
2 /*
3   Meanwhile - Unofficial Lotus Sametime Community Client Library
4   Copyright (C) 2004  Christopher (siege) O'Brien
5 
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Library General Public
8   License as published by the Free Software Foundation; either
9   version 2 of the License, or (at your option) any later version.
10 
11   This library 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 GNU
14   Library General Public License for more details.
15 
16   You should have received a copy of the GNU Library General Public
17   License along with this library; if not, write to the Free
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 
22 #ifndef _MW_SRVC_FT_H
23 #define _MW_SRVC_FT_H
24 
25 
26 /** @file mw_srvc_ft.h
27 
28     A file transfer is a simple way to get large chunks of binary data
29     from one client to another.
30 */
31 
32 
33 #include "mw_common.h"
34 
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 
41 /** @struct mwServiceFileTransfer
42     File transfer service
43 */
44 struct mwServiceFileTransfer;
45 
46 
47 /** @struct mwFileTransfer
48     A single file trasfer session
49  */
50 struct mwFileTransfer;
51 
52 
53 #define mwService_FILE_TRANSFER  0x00000038
54 
55 
56 enum mwFileTransferState {
57   mwFileTransfer_NEW,   /**< file transfer is not open */
58   mwFileTransfer_PENDING,  /**< file transfer is opening */
59   mwFileTransfer_OPEN,     /**< file transfer is open */
60   mwFileTransfer_CANCEL_LOCAL,
61   mwFileTransfer_CANCEL_REMOTE,
62   mwFileTransfer_DONE,
63   mwFileTransfer_ERROR,    /**< error in file transfer */
64   mwFileTransfer_UNKNOWN,  /**< unknown state */
65 };
66 
67 
68 #define mwFileTransfer_isState(ft, state) \
69   (mwFileTransfer_getState(ft) == (state))
70 
71 #define mwFileTransfer_isNew(ft) \
72   mwFileTransfer_isState((ft), mwFileTransfer_NEW)
73 
74 #define mwFileTransfer_isPending(ft) \
75   mwFileTransfer_isState((ft), mwFileTransfer_PENDING)
76 
77 #define mwFileTransfer_isOpen(ft) \
78   mwFileTransfer_isState((ft), mwFileTransfer_OPEN)
79 
80 #define mwFileTransfer_isDone(ft) \
81   mwFileTransfer_isState((ft), mwFileTransfer_DONE)
82 
83 #define mwFileTransfer_isCancelLocal(ft) \
84   mwFileTransfer_isState((ft), mwFileTransfer_CANCEL_LOCAL)
85 
86 #define mwFileTransfer_isCancelRemote(ft) \
87   mwFileTransfer_isState((ft), mwFileTransfer_CANCEL_REMOTE)
88 
89 
90 enum mwFileTranferCode {
91   mwFileTransfer_SUCCESS   = 0x00000000,
92   mwFileTransfer_REJECTED  = 0x08000606,
93 };
94 
95 
96 struct mwFileTransferHandler {
97 
98   /** an incoming file transfer has been offered */
99   void (*ft_offered)(struct mwFileTransfer *ft);
100 
101   /** a file transfer has been fully initiated */
102   void (*ft_opened)(struct mwFileTransfer *ft);
103 
104   /** a file transfer has been closed. Check the status of the file
105       transfer to determine if the transfer was complete or if it had
106       been interrupted */
107   void (*ft_closed)(struct mwFileTransfer *ft, guint32 code);
108 
109   /** receive a chunk of a file from an inbound file transfer. */
110   void (*ft_recv)(struct mwFileTransfer *ft, struct mwOpaque *data);
111 
112   /** received an ack for a sent chunk on an outbound file transfer.
113       this indicates that a previous call to mwFileTransfer_send has
114       reached the target and that the target has responded. */
115   void (*ft_ack)(struct mwFileTransfer *ft);
116 
117   /** optional. called from mwService_free */
118   void (*clear)(struct mwServiceFileTransfer *srvc);
119 };
120 
121 
122 struct mwServiceFileTransfer *
123 mwServiceFileTransfer_new(struct mwSession *session,
124 			  struct mwFileTransferHandler *handler);
125 
126 
127 struct mwFileTransferHandler *
128 mwServiceFileTransfer_getHandler(struct mwServiceFileTransfer *srvc);
129 
130 
131 const GList *
132 mwServiceFileTransfer_getTransfers(struct mwServiceFileTransfer *srvc);
133 
134 
135 struct mwFileTransfer *
136 mwFileTransfer_new(struct mwServiceFileTransfer *srvc,
137 		   const struct mwIdBlock *who, const char *msg,
138 		   const char *filename, guint32 filesize);
139 
140 
141 /** deallocate a file transfer. will call mwFileTransfer_close if
142     necessary */
143 void
144 mwFileTransfer_free(struct mwFileTransfer *ft);
145 
146 
147 /** the status of this file transfer */
148 enum mwFileTransferState
149 mwFileTransfer_getState(struct mwFileTransfer *ft);
150 
151 
152 struct mwServiceFileTransfer *
153 mwFileTransfer_getService(struct mwFileTransfer *ft);
154 
155 
156 /** the user on the other end of the file transfer */
157 const struct mwIdBlock *
158 mwFileTransfer_getUser(struct mwFileTransfer *ft);
159 
160 
161 /** the message sent along with an offered file transfer */
162 const char *
163 mwFileTransfer_getMessage(struct mwFileTransfer *ft);
164 
165 
166 /** the publicized file name. Not necessarily related to any actual
167     file on either system */
168 const char *
169 mwFileTransfer_getFileName(struct mwFileTransfer *ft);
170 
171 
172 /** total bytes intended to be sent/received */
173 guint32 mwFileTransfer_getFileSize(struct mwFileTransfer *ft);
174 
175 
176 /** bytes remaining to be received/send */
177 guint32 mwFileTransfer_getRemaining(struct mwFileTransfer *ft);
178 
179 
180 /** count of bytes sent/received over this file transfer so far */
181 #define mwFileTransfer_getSent(ft) \
182   (mwFileTransfer_getFileSize(ft) - mwFileTransfer_getRemaining(ft))
183 
184 
185 /** initiate an outgoing file transfer */
186 int mwFileTransfer_offer(struct mwFileTransfer *ft);
187 
188 
189 /** accept an incoming file transfer */
190 int mwFileTransfer_accept(struct mwFileTransfer *ft);
191 
192 
193 /** reject an incoming file transfer */
194 #define mwFileTransfer_reject(ft) \
195   mwFileTransfer_close((ft), mwFileTransfer_REJECTED)
196 
197 
198 /** cancel an open file transfer */
199 #define mwFileTransfer_cancel(ft) \
200   mwFileTransfer_close((ft), mwFileTransfer_SUCCESS);
201 
202 
203 /** Close a file transfer. This will trigger the ft_close function of the
204     session's handler.
205 
206     @see mwFileTransfer_reject
207     @see mwFileTransfer_cancel
208 */
209 int mwFileTransfer_close(struct mwFileTransfer *ft, guint32 code);
210 
211 
212 /** send a chunk of data over an outbound file transfer. The client at
213     the other end of the transfer should respond with an acknowledgement
214     message, which can be caught in the service's handler.
215 
216     @see mwFileTransferHandler::ft_ack
217 */
218 int mwFileTransfer_send(struct mwFileTransfer *ft,
219 			struct mwOpaque *data);
220 
221 
222 /** acknowledge the receipt of a chunk of data from an inbound file
223     transfer.  This should be done after every received chunk, or the
224     transfer will stall. However, not all clients will wait for an ack
225     after sending a chunk before sending the next chunk, so it is
226     possible to have the handler's ft_recv function triggered again
227     even if no ack was sent.
228 
229     @see mwFileTransferHandler::ft_recv
230 */
231 int mwFileTransfer_ack(struct mwFileTransfer *ft);
232 
233 
234 void mwFileTransfer_setClientData(struct mwFileTransfer *ft,
235 				  gpointer data, GDestroyNotify clean);
236 
237 
238 gpointer mwFileTransfer_getClientData(struct mwFileTransfer *ft);
239 
240 
241 void mwFileTransfer_removeClientData(struct mwFileTransfer *ft);
242 
243 
244 #ifdef __cplusplus
245 }
246 #endif
247 
248 
249 #endif /* _MW_SRVC_FT_H */
250