1212#include < boost/network/traits/string.hpp>
1313#include < boost/cstdint.hpp>
1414#include < boost/bind.hpp>
15+ #include < boost/network/protocol/xmpp/namespaces.hpp>
1516#include < boost/network/protocol/xmpp/message.hpp>
1617#include < boost/network/protocol/xmpp/presence.hpp>
1718#include < boost/network/protocol/xmpp/iq.hpp>
1819#include < boost/asio/io_service.hpp>
20+ #include < boost/asio/placeholders.hpp>
1921#include < boost/asio/ip/tcp.hpp>
22+ #include < deque>
2023
2124
2225namespace boost {
2326namespace network {
2427namespace xmpp {
2528template <
2629class Tag ,
30+ unsigned version_major,
31+ unsigned version_minor,
2732class Handler
2833 >
2934class basic_client : boost::noncopyable {
3035
3136private:
3237
33- typedef basic_client<Tag, Handler> this_type;
38+ typedef basic_client<Tag,version_major, version_minor, Handler> this_type;
3439
3540public:
3641
@@ -44,28 +49,30 @@ class basic_client : boost::noncopyable {
4449
4550~basic_client ();
4651
47- void connect (const string_type &proxy_host,
48- const string_type &proxy_port);
52+ void set_lang (const string_type &lang);
4953
50- void disconnect ();
54+ void connect (const string_type &jid,
55+ const string_type &password);
56+
57+ void run ();
5158
52- void authenticate (const string_type &jid,
53- const string_type &password);
59+ void disconnect ();
5460
5561void send_message (const message_type &message);
5662
5763void send_presence (const presence_type &presence);
5864
5965void send_iq (const iq_type &iq);
6066
61- void set_jid (const string_type &jid);
62-
6367 string_typeget_jid ()const ;
6468
6569private:
6670
67- void write_stanza (const basic_stanza<Tag> &stanza);
68- void close_socket ();
71+ void handle_connect (const boost::system::error_code &error,
72+ boost::asio::ip::tcp::resolver::iterator iterator);
73+ void handle_write_stanza (const basic_stanza<Tag> &stanza);
74+ void handle_read_stanza (const boost::system::error_code &ec);
75+ void handle_disconnect ();
6976
7077 Handler &handler_;
7178
@@ -83,123 +90,216 @@ class basic_client : boost::noncopyable {
8390
8491// xml parser
8592
93+ // std::deque<std::string> stanza_queue_;
94+
8695};
8796
8897
8998template <
9099class Tag ,
100+ unsigned version_major,
101+ unsigned version_minor,
91102class Handler
92103 >
93- basic_client<Tag, Handler>::basic_client(Handler &handler)
104+ basic_client<Tag,version_major, version_minor, Handler>::basic_client(Handler &handler)
94105 : handler_(handler), socket_(io_service_) {
95- // set the handlers
106+
96107}
97108
98109
99110template <
100111class Tag ,
112+ unsigned version_major,
113+ unsigned version_minor,
114+ class Handler
115+ >
116+ basic_client<Tag, version_major, version_minor, Handler>::~basic_client () {
117+
118+ }
119+
120+ template <
121+ class Tag ,
122+ unsigned version_major,
123+ unsigned version_minor,
101124class Handler
102125 >
103- basic_client<Tag, Handler>::~basic_client ( ) {
126+ void basic_client<Tag,version_major, version_minor, Handler>::set_lang( const string_type &lang ) {
104127
105128}
106129
107130
108131template <
109132class Tag ,
133+ unsigned version_major,
134+ unsigned version_minor,
110135class Handler
111136 >
112- void basic_client<Tag, Handler>::connect(const string_type &proxy_host,
113- const string_type &proxy_port) {
137+ void basic_client<Tag, version_major, version_minor, Handler>::connect(const string_type &jid,
138+ const string_type &password) {
139+ using boost::asio::ip::tcp;
140+
114141// get the JID domain
115- // default port is52222
142+ // default port is5222
116143// open socket
117144// socket has a state
118145// signal connection handler
146+
147+ jid_ = jid;
148+
149+ string_type host =" 127.0.0.1" ;
150+ string_type port =" 5222" ;
151+
152+ tcp::resolverresolver (io_service_);
153+ tcp::resolver::queryquery (host, port);
154+ tcp::resolver::iterator iterator = resolver.resolve (query);
155+ socket_.async_connect (&this_type::handle_connect,
156+ this ,
157+ boost::asio::placeholders::error,
158+ iterator);
119159}
120160
121161template <
122162class Tag ,
163+ unsigned version_major,
164+ unsigned version_minor,
123165class Handler
124166 >
125- void basic_client<Tag, Handler>::disconnect() {
126- // close socket
127- // signal connection handler
128- io_service_.post (
129- boost::bind (&this_type::close_socket,this ));
167+ void basic_client<Tag, version_major, version_minor, Handler>::run() {
168+ io_service_.run ();
130169}
131170
132171template <
133172class Tag ,
173+ unsigned version_major,
174+ unsigned version_minor,
134175class Handler
135176 >
136- void basic_client<Tag, Handler>::authenticate( const string_type &jid,
137- const string_type &password) {
138-
177+ void basic_client<Tag,version_major, version_minor, Handler>::disconnect() {
178+ io_service_. post (
179+ boost::bind (&this_type::handle_disconnect, this ));
139180}
140181
141182template <
142183class Tag ,
184+ unsigned version_major,
185+ unsigned version_minor,
143186class Handler
144187 >
145- void basic_client<Tag, Handler>::send_message(const message_type &message) {
188+ void basic_client<Tag,version_major, version_minor, Handler>::send_message(const message_type &message) {
146189 io_service_.post (
147- boost::bind (&this_type::write_stanza ,this ,boost::ref (message)));
190+ boost::bind (&this_type::handle_write_stanza ,this ,boost::ref (message)));
148191}
149192
150193template <
151194class Tag ,
195+ unsigned version_major,
196+ unsigned version_minor,
152197class Handler
153198 >
154- void basic_client<Tag, Handler>::send_presence(const presence_type &presence) {
199+ void basic_client<Tag,version_major, version_minor, Handler>::send_presence(const presence_type &presence) {
155200 io_service_.post (
156- boost::bind (&this_type::write_stanza ,this ,boost::ref (presence)));
201+ boost::bind (&this_type::handle_write_stanza ,this ,boost::ref (presence)));
157202}
158203
159204template <
160205class Tag ,
206+ unsigned version_major,
207+ unsigned version_minor,
161208class Handler
162209 >
163- void basic_client<Tag, Handler>::send_iq(const iq_type &iq) {
210+ void basic_client<Tag,version_major, version_minor, Handler>::send_iq(const iq_type &iq) {
164211 io_service_.post (
165- boost::bind (&this_type::write_stanza ,this ,boost::ref (iq)));
212+ boost::bind (&this_type::handle_write_stanza ,this ,boost::ref (iq)));
166213}
167214
168215template <
169216class Tag ,
217+ unsigned version_major,
218+ unsigned version_minor,
170219class Handler
171220 >
172- typename basic_client<Tag, Handler>::string_type
173- basic_client<Tag, Handler>::get_jid()const {
221+ typename basic_client<Tag,version_major, version_minor, Handler>::string_type
222+ basic_client<Tag,version_major, version_minor, Handler>::get_jid()const {
174223return jid_;
175224}
176225
226+ template <
227+ class Tag ,
228+ unsigned version_major,
229+ unsigned version_minor,
230+ class Handler
231+ >
232+ void basic_client<Tag, version_major, version_minor, Handler>::handle_connect(
233+ const boost::system::error_code& ec,
234+ boost::asio::ip::tcp::resolver::iterator iterator) {
235+ if (!ec) {
236+
237+ // open stream
238+ // TODO: where does "lang" come from?
239+ string_type s =
240+ " <?xml version=\" %d.%d\" ?>"
241+ " <stream:stream to=\" domain\" "
242+ " xml:lang=\" lang\" "
243+ " version=\" %d.%d\" "
244+ " xmlns=\" %s\" " // xmpp_ns_client or xmpp_ns_component
245+ " xmlns:stream=\" %s\" >" ;// xmpp_ns_Streams
246+
247+ // boost::asio::async_read(
248+ // socket_,
249+ // boost::asio::buffer(read_msg_.data(), chat_message::header_length),
250+ // boost::bind(&chat_client::handle_read_header, this,
251+ // boost::asio::placeholders::error));
252+ }
253+ else if (iterator !=boost::asio::ip::tcp::resolver::iterator ()) {
254+ socket_.close ();
255+ boost::asio::ip::tcp::endpoint endpoint = *iterator;
256+ socket_.async_connect (
257+ endpoint,
258+ boost::bind (&this_type::handle_connect,
259+ this ,
260+ boost::asio::placeholders::error,
261+ ++iterator));
262+ }
263+ else {
264+ // unable to connect
265+ }
266+ }
177267
178268template <
179269class Tag ,
270+ unsigned version_major,
271+ unsigned version_minor,
180272class Handler
181273 >
182- void basic_client<Tag, Handler>::write_stanza(const basic_stanza<Tag> &stanza) {
183-
274+ void basic_client<Tag, version_major, version_minor, Handler>::handle_write_stanza(const basic_stanza<Tag> &stanza) {
275+ // stanza ==> string
276+ // socket_.async_write(socket_,
277+ // boost::asio::buffer(stanza.string()),
278+ // boost::bind(&this_type::handle_write...))
184279}
185280
186281
187282template <
188283class Tag ,
284+ unsigned version_major,
285+ unsigned version_minor,
189286class Handler
190287 >
191- void basic_client<Tag, Handler>::close_socket() {
288+ void basic_client<Tag, version_major, version_minor, Handler>::handle_disconnect() {
289+ // close stream
290+ string_type s =" </stream:stream>" ;
192291 socket_.close ();
292+ // handler_.disconnected();
193293}
194294
195295
196296template <
197297class Handler
198298 >
199- struct client : basic_client<tags::default_, Handler> {
299+ struct client : basic_client<tags::default_,1 , 0 , Handler> {
200300
201301explicit client (Handler &handler)
202- : basic_client<tags::default_, Handler>(handler) {
302+ : basic_client<tags::default_,1, 0, Handler>(handler) {
203303
204304 }
205305