Imported Upstream version 1.0beta3
[platform/upstream/syncevolution.git] / src / syncevo / ObexTransportAgent.h
1 /*
2  * Copyright (C) 2009 Intel Corporation
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) version 3.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301  USA
18  */
19
20 #ifndef INCL_OBEXTRANSPORTAGENT
21 #define INCL_OBEXTRANSPORTAGENT
22
23 #include <config.h>
24
25 #ifdef ENABLE_OBEX
26
27 #include <syncevo/TransportAgent.h>
28 #include <syncevo/Logging.h>
29 #include <syncevo/declarations.h>
30 #include <syncevo/SmartPtr.h>
31
32 #ifdef  ENABLE_BLUETOOTH
33 #include <bluetooth/sdp.h>
34 #include <bluetooth/sdp_lib.h>
35 #endif
36 #include <openobex/obex.h>
37
38 SE_BEGIN_CXX
39
40 class Socket {
41     int socketfd;
42  public:
43      Socket() {socketfd = -1;}
44      Socket(int fd) {socketfd = fd;}
45      ~Socket() { if (socketfd !=-1) {::close (socketfd);} }
46      int get() {return socketfd;}
47 }; 
48
49 class Channel {
50     GIOChannel *channel;
51  public:
52      Channel() {channel = NULL;}
53      Channel(GIOChannel *c) {channel = c;}
54      ~Channel() { if (channel) {g_io_channel_unref (channel);}}
55      GIOChannel* get() {return channel;}
56 };
57
58 class ObexEvent {
59     guint event;
60 public:
61     ObexEvent() {event = 0;}
62     ObexEvent (guint e) {event = e;}
63     ~ObexEvent () {if (event) {g_source_remove (event);}}
64     guint get() {return event;}
65 };
66
67 class ObexHandle {
68     obex_t *handle;
69 public:
70     ObexHandle() {handle = NULL;}
71     ObexHandle(obex_t *h) {handle = h;}
72     ~ObexHandle() {if (handle) {OBEX_Cleanup (handle);}}
73     obex_t* get() {return handle;}
74 };
75
76 /**
77  * message send/receive with libopenobex
78  * should work with a transport binding (Bluetooth, USB, etc.)
79  */
80 class ObexTransportAgent : public TransportAgent 
81 {
82     class ContextUnref {
83     public:
84         static void unref(GMainContext *context) { g_main_context_unref(context); }
85     };
86
87     public:
88         enum OBEX_TRANS_TYPE{
89             OBEX_BLUETOOTH,
90             OBEX_USB,
91             INVALID
92         };
93
94         /**
95          * @param loop     the glib loop to use when waiting for IO;
96          *                 transport will increase the reference count;
97          *                 if NULL a new loop in the default context is used
98          */
99         ObexTransportAgent(OBEX_TRANS_TYPE type, GMainLoop *loop);
100         ~ObexTransportAgent();
101
102         virtual void setURL (const std::string &url);
103         virtual void setContentType(const std::string &type);
104         virtual void shutdown();
105         virtual void send(const char *data, size_t len);
106         virtual void cancel();
107         virtual Status wait(bool noReply);
108         virtual void getReply(const char *&data, size_t &len, std::string &contentType);
109         virtual void setCallback (TransportCallback cb, void *udata, int interval);
110         /* Obex specific api: connecting the underlying transport */
111         void connect();
112
113     private:
114         /*call back used by libopenobex, will route to member function obex_callback*/
115         static void obex_event (obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp);
116         /* callback used by obex fd poll, will route to member function
117          * obex_fd_source_cb_impl */
118         static gboolean obex_fd_source_cb (GIOChannel *io, GIOCondition cond, void *udata);
119         /* callback used by Bluetooth sdp poll, will route to member function
120          * sdp_source_cb_impl */
121         static gboolean sdp_source_cb (GIOChannel *io, GIOCondition cond, void *udata);
122         /* callback called when a sdp async transaction is finished, route to
123          * member function sdp_callback_impl*/
124         static void sdp_callback (uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *user_data);
125
126         void obex_callback (obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp);
127         gboolean obex_fd_source_cb_impl (GIOChannel *io, GIOCondition cond);
128         gboolean sdp_source_cb_impl (GIOChannel *io, GIOCondition cond);
129         void sdp_callback_impl (uint8_t type, uint16_t status, uint8_t *rsp, size_t size);
130
131         /* First phase of OBEX connect: connect to remote peer */
132         void connectInit ();
133         /* Second phase of OBEX connect: send connect cmd to initalize */
134         void connectReq ();
135
136         /* wrapper of OBEX_ObjectNew*/
137         obex_object_t * newCmd (uint8_t cmd);
138
139         static const int DEFAULT_RX_MTU=32767;
140         static const int DEFAULT_TX_MTU=32767;
141
142         /*Indicates when the OBEX transport has finished it's part of working,
143          * it's the application to turn to do something */
144         bool m_obexReady;
145         Status m_status;
146
147         /*
148          * The underlying transport type: Bluetooth, USB.
149          */
150         OBEX_TRANS_TYPE m_transType;
151
152         /** context that needs to be kept alive while waiting for OBEX */
153         eptr<GMainContext, GMainContext, ContextUnref> m_context;
154
155         /* The address of the remote device  
156          * macadd for Bluetooth; device name for usb; host name for
157          * tcp/ip
158          */
159         std::string m_address;
160         /*
161          * Service port for the remote device 
162          * channel for Bluetooth, port for tcp/ip
163          */
164         int m_port;
165
166         /*The underlying socket fd*/
167         cxxptr<Socket> m_sock;
168         cxxptr<ObexEvent> m_obexEvent;
169         cxxptr<Channel> m_channel;
170
171         std::string m_contentType;
172         arrayptr<char> m_buffer;
173         int m_bufferSize;
174
175         sdp_session_t *m_sdp;
176
177         /* callback supplied by the user of the transport */
178         TransportCallback m_cb;
179         void *m_cbData;
180         time_t m_cbInterval;
181         time_t m_requestStart;
182         /** OBEX poll interval */
183         static const int OBEX_POLL_INTERVAL = 1;
184
185         uint32_t m_connectId;
186         //already fired disconnect
187         bool m_disconnecting;
188
189         cxxptr<ObexHandle> m_handle;
190         enum CONNECT_STATUS {
191             START, 
192             SDP_START, //sdp transaction start
193             SDP_REQ, //sdp request has been sent
194             SDP_DONE, //sdp transaction finished
195             ADDR_READY, //address is prepared
196             INIT0,  //connect is called but not finished
197             INIT1,  //connect is finished. 
198             INIT2,  //connect cmd is sent, but not finished.
199             CONNECTED, //connection sucessfully setup
200             ERROR,  //connection in error state
201             END
202         };
203         CONNECT_STATUS m_connectStatus;
204 };
205
206 SE_END_CXX
207 #endif //ENABLE_OBEX
208 #endif