1 #ifndef __XMPP_H__
2 #define __XMPP_H__
3 /*
4 * API for the Pedro mini-XMPP client.
5 *
6 * Authors:
7 * Bob Jamison
8 *
9 * Copyright (C) 2005 Bob Jamison
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
26 #include <stdio.h>
27 #include <vector>
29 #include <string>
31 #include "pedrodom.h"
33 namespace Pedro
34 {
36 typedef std::string DOMString;
39 //########################################################################
40 //# X M P P E V E N T
41 //########################################################################
42 class XmppUser
43 {
44 public:
45 XmppUser()
46 {
47 }
48 XmppUser(const DOMString &jidArg, const DOMString &nickArg)
49 {
50 jid = jidArg;
51 nick = nickArg;
52 }
53 XmppUser(const DOMString &jidArg, const DOMString &nickArg,
54 const DOMString &subscriptionArg, const DOMString &groupArg)
55 {
56 jid = jidArg;
57 nick = nickArg;
58 subscription = subscriptionArg;
59 group = groupArg;
60 }
61 XmppUser(const XmppUser &other)
62 {
63 jid = other.jid;
64 nick = other.nick;
65 subscription = other.subscription;
66 group = other.group;
67 show = other.show;
68 }
69 XmppUser &operator=(const XmppUser &other)
70 {
71 jid = other.jid;
72 nick = other.nick;
73 subscription = other.subscription;
74 group = other.group;
75 show = other.show;
76 return *this;
77 }
78 virtual ~XmppUser()
79 {}
80 DOMString jid;
81 DOMString nick;
82 DOMString subscription;
83 DOMString group;
84 DOMString show;
85 };
87 class XmppEvent
88 {
90 public:
92 typedef enum
93 {
94 EVENT_NONE,
95 EVENT_STATUS,
96 EVENT_ERROR,
97 EVENT_CONNECTED,
98 EVENT_DISCONNECTED,
99 EVENT_PRESENCE,
100 EVENT_ROSTER,
101 EVENT_MESSAGE,
102 EVENT_MUC_JOIN,
103 EVENT_MUC_LEAVE,
104 EVENT_MUC_PRESENCE,
105 EVENT_MUC_MESSAGE,
106 EVENT_STREAM_RECEIVE_INIT,
107 EVENT_STREAM_RECEIVE,
108 EVENT_STREAM_RECEIVE_CLOSE,
109 EVENT_FILE_ACCEPTED,
110 EVENT_FILE_RECEIVE
111 } XmppEventType;
114 /**
115 *
116 */
117 XmppEvent(int type);
119 /**
120 *
121 */
122 XmppEvent(const XmppEvent &other);
124 /**
125 *
126 */
127 virtual XmppEvent &operator=(const XmppEvent &other);
129 /**
130 *
131 */
132 virtual ~XmppEvent();
134 /**
135 *
136 */
137 virtual void assign(const XmppEvent &other);
139 /**
140 *
141 */
142 virtual int getType() const;
145 /**
146 *
147 */
148 virtual DOMString getIqId() const;
151 /**
152 *
153 */
154 virtual void setIqId(const DOMString &val);
156 /**
157 *
158 */
159 virtual DOMString getStreamId() const;
162 /**
163 *
164 */
165 virtual void setStreamId(const DOMString &val);
167 /**
168 *
169 */
170 virtual bool getPresence() const;
173 /**
174 *
175 */
176 virtual void setPresence(bool val);
178 /**
179 *
180 */
181 virtual DOMString getShow() const;
184 /**
185 *
186 */
187 virtual void setShow(const DOMString &val);
189 /**
190 *
191 */
192 virtual DOMString getStatus() const;
194 /**
195 *
196 */
197 virtual void setStatus(const DOMString &val);
199 /**
200 *
201 */
202 virtual DOMString getTo() const;
204 /**
205 *
206 */
207 virtual void setTo(const DOMString &val);
209 /**
210 *
211 */
212 virtual DOMString getFrom() const;
214 /**
215 *
216 */
217 virtual void setFrom(const DOMString &val);
219 /**
220 *
221 */
222 virtual DOMString getGroup() const;
224 /**
225 *
226 */
227 virtual void setGroup(const DOMString &val);
229 /**
230 *
231 */
232 virtual Element *getDOM() const;
235 /**
236 *
237 */
238 virtual void setDOM(const Element *val);
240 /**
241 *
242 */
243 virtual std::vector<XmppUser> getUserList() const;
245 /**
246 *
247 */
248 virtual void setUserList(const std::vector<XmppUser> &userList);
250 /**
251 *
252 */
253 virtual DOMString getFileName() const;
256 /**
257 *
258 */
259 virtual void setFileName(const DOMString &val);
262 /**
263 *
264 */
265 virtual DOMString getFileDesc() const;
268 /**
269 *
270 */
271 virtual void setFileDesc(const DOMString &val);
274 /**
275 *
276 */
277 virtual long getFileSize() const;
280 /**
281 *
282 */
283 virtual void setFileSize(long val);
285 /**
286 *
287 */
288 virtual DOMString getFileHash() const;
290 /**
291 *
292 */
293 virtual void setFileHash(const DOMString &val);
295 /**
296 *
297 */
298 virtual DOMString getData() const;
301 /**
302 *
303 */
304 virtual void setData(const DOMString &val);
306 private:
308 int eventType;
310 DOMString iqId;
312 DOMString streamId;
314 bool presence;
316 DOMString show;
318 DOMString status;
320 DOMString to;
322 DOMString from;
324 DOMString group;
326 DOMString data;
328 DOMString fileName;
329 DOMString fileDesc;
330 long fileSize;
331 DOMString fileHash;
333 Element *dom;
335 std::vector<XmppUser>userList;
337 };
340 //########################################################################
341 //# X M P P E V E N T L I S T E N E R
342 //########################################################################
344 class XmppEventListener
345 {
346 public:
348 /**
349 *
350 */
351 XmppEventListener()
352 {}
354 /**
355 *
356 */
357 XmppEventListener(const XmppEventListener &other)
358 {}
360 /**
361 *
362 */
363 virtual void operator=(const XmppEventListener &other)
364 {}
366 /**
367 *
368 */
369 virtual ~XmppEventListener()
370 {}
372 /**
373 *
374 */
375 virtual void processXmppEvent(const XmppEvent &event)
376 {}
378 };
382 //########################################################################
383 //# X M P P E V E N T T A R G E T
384 //########################################################################
386 class XmppEventTarget
387 {
388 public:
390 /**
391 *
392 */
393 XmppEventTarget();
395 /**
396 *
397 */
398 XmppEventTarget(const XmppEventTarget &other);
400 /**
401 *
402 */
403 virtual ~XmppEventTarget();
406 //###########################
407 //# M E S S A G E S
408 //###########################
411 /**
412 * Send an error message to all subscribers
413 */
414 void error(char *fmt, ...);
417 /**
418 * Send a status message to all subscribers
419 */
420 void status(char *fmt, ...);
422 //###########################
423 //# LISTENERS
424 //###########################
426 /**
427 *
428 */
429 virtual void dispatchXmppEvent(const XmppEvent &event);
431 /**
432 *
433 */
434 virtual void addXmppEventListener(const XmppEventListener &listener);
436 /**
437 *
438 */
439 virtual void removeXmppEventListener(const XmppEventListener &listener);
441 /**
442 *
443 */
444 virtual void clearXmppEventListeners();
446 /**
447 *
448 */
449 void eventQueueEnable(bool val);
451 /**
452 *
453 */
454 int eventQueueAvailable();
456 /**
457 *
458 */
459 XmppEvent eventQueuePop();
462 private:
464 std::vector<XmppEventListener *> listeners;
466 std::vector<XmppEvent> eventQueue;
467 bool eventQueueEnabled;
469 static const int targetWriteBufLen = 2048;
471 char targetWriteBuf[targetWriteBufLen];
472 };
478 //########################################################################
479 //# X M P P C L I E N T
480 //########################################################################
483 class TcpSocket;
484 class XmppChat;
485 class XmppGroupChat;
486 class XmppStream;
488 class XmppClient : public XmppEventTarget
489 {
491 public:
493 //###########################
494 //# CONSTRUCTORS
495 //###########################
497 /**
498 *
499 */
500 XmppClient();
502 /**
503 *
504 */
505 XmppClient(const XmppClient &other);
507 /**
508 *
509 */
510 void assign(const XmppClient &other);
512 /**
513 *
514 */
515 virtual ~XmppClient();
518 //###########################
519 //# UTILITY
520 //###########################
522 /**
523 *
524 */
525 virtual bool pause(unsigned long millis);
527 //###########################
528 //# CONNECTION
529 //###########################
531 /**
532 *
533 */
534 virtual bool connect();
536 /**
537 *
538 */
539 virtual bool connect(DOMString host, int port,
540 DOMString userName,
541 DOMString password,
542 DOMString resource);
544 /**
545 *
546 */
547 virtual bool disconnect();
550 /**
551 *
552 */
553 virtual bool write(char *fmt, ...);
555 /**
556 *
557 */
558 virtual bool isConnected()
559 { return connected; }
561 /**
562 *
563 */
564 virtual DOMString getHost()
565 { return host; }
567 /**
568 *
569 */
570 virtual void setHost(const DOMString &val)
571 { host = val; }
573 /**
574 *
575 */
576 virtual DOMString getRealm()
577 { return realm; }
579 /**
580 *
581 */
582 virtual void setRealm(const DOMString &val)
583 { realm = val; }
585 /**
586 *
587 */
588 virtual int getPort()
589 { return port; }
591 /**
592 *
593 */
594 virtual void setPort(int val)
595 { port = val; }
597 /**
598 *
599 */
600 virtual DOMString getUsername();
602 /**
603 *
604 */
605 virtual void setUsername(const DOMString &val);
607 /**
608 *
609 */
610 virtual DOMString getPassword()
611 { return password; }
613 /**
614 *
615 */
616 virtual void setPassword(const DOMString &val)
617 { password = val; }
619 /**
620 *
621 */
622 virtual DOMString getResource()
623 { return resource; }
625 /**
626 *
627 */
628 virtual void setResource(const DOMString &val)
629 { resource = val; }
631 /**
632 *
633 */
634 virtual DOMString getJid()
635 { return jid; }
636 /**
637 *
638 */
639 virtual int getMsgId()
640 { return msgId++; }
642 /**
643 *
644 */
645 bool processMessage(Element *root);
647 /**
648 *
649 */
650 bool processPresence(Element *root);
652 /**
653 *
654 */
655 bool processIq(Element *root);
657 /**
658 *
659 */
660 virtual bool receiveAndProcess();
662 /**
663 *
664 */
665 virtual bool receiveAndProcessLoop();
667 //#######################
668 //# ROSTER
669 //#######################
671 /**
672 *
673 */
674 bool rosterAdd(const DOMString &rosterGroup,
675 const DOMString &otherJid,
676 const DOMString &name);
678 /**
679 *
680 */
681 bool rosterDelete(const DOMString &otherJid);
683 /**
684 *
685 */
686 std::vector<XmppUser> getRoster();
689 //#######################
690 //# CHAT (individual)
691 //#######################
693 /**
694 *
695 */
696 virtual bool message(const DOMString &user, const DOMString &subj,
697 const DOMString &text);
699 /**
700 *
701 */
702 virtual bool message(const DOMString &user, const DOMString &text);
704 /**
705 *
706 */
707 virtual bool presence(const DOMString &presence);
709 //#######################
710 //# GROUP CHAT
711 //#######################
713 /**
714 *
715 */
716 virtual bool groupChatCreate(const DOMString &groupJid);
718 /**
719 *
720 */
721 virtual void groupChatDelete(const DOMString &groupJid);
723 /**
724 *
725 */
726 bool groupChatExists(const DOMString &groupJid);
728 /**
729 *
730 */
731 virtual void groupChatsClear();
733 /**
734 *
735 */
736 virtual void groupChatUserAdd(const DOMString &groupJid,
737 const DOMString &nick);
739 /**
740 *
741 */
742 virtual void groupChatUserDelete(const DOMString &groupJid,
743 const DOMString &nick);
745 /**
746 *
747 */
748 virtual std::vector<XmppUser>
749 groupChatGetUserList(const DOMString &groupJid);
751 /**
752 *
753 */
754 virtual bool groupChatJoin(const DOMString &groupJid,
755 const DOMString &nick,
756 const DOMString &pass);
758 /**
759 *
760 */
761 virtual bool groupChatLeave(const DOMString &groupJid,
762 const DOMString &nick);
764 /**
765 *
766 */
767 virtual bool groupChatMessage(const DOMString &groupJid,
768 const DOMString &msg);
770 /**
771 *
772 */
773 virtual bool groupChatPrivateMessage(const DOMString &groupJid,
774 const DOMString &toNick,
775 const DOMString &msg);
777 /**
778 *
779 */
780 virtual bool groupChatPresence(const DOMString &groupJid,
781 const DOMString &nick,
782 const DOMString &presence);
785 //#######################
786 //# STREAMS
787 //#######################
789 typedef enum
790 {
791 STREAM_AVAILABLE,
792 STREAM_OPENING,
793 STREAM_OPEN,
794 STREAM_CLOSING,
795 STREAM_CLOSED,
796 STREAM_ERROR
797 } StreamStates;
799 /**
800 *
801 */
802 virtual int outputStreamOpen(const DOMString &jid,
803 const DOMString &streamId);
805 /**
806 *
807 */
808 virtual int outputStreamWrite(int streamId,
809 const unsigned char *buf, unsigned long len);
811 /**
812 *
813 */
814 virtual int outputStreamClose(int streamId);
816 /**
817 *
818 */
819 virtual int inputStreamOpen(const DOMString &jid,
820 const DOMString &streamId,
821 const DOMString &iqId);
823 /**
824 *
825 */
826 virtual int inputStreamAvailable(int streamId);
828 /**
829 *
830 */
831 virtual std::vector<unsigned char> inputStreamRead(int streamId);
833 /**
834 *
835 */
836 virtual bool inputStreamClosing(int streamId);
838 /**
839 *
840 */
841 virtual int inputStreamClose(int streamId);
844 //#######################
845 //# FILE TRANSFERS
846 //#######################
848 /**
849 *
850 */
851 virtual bool fileSend(const DOMString &destJid,
852 const DOMString &offeredName,
853 const DOMString &fileName,
854 const DOMString &description);
856 /**
857 *
858 */
859 virtual bool fileSendBackground(const DOMString &destJid,
860 const DOMString &offeredName,
861 const DOMString &fileName,
862 const DOMString &description);
864 /**
865 *
866 */
867 virtual bool fileReceive(const DOMString &fromJid,
868 const DOMString &iqId,
869 const DOMString &streamId,
870 const DOMString &fileName,
871 long fileSize,
872 const DOMString &fileHash);
873 /**
874 *
875 */
876 virtual bool fileReceiveBackground(const DOMString &fromJid,
877 const DOMString &iqId,
878 const DOMString &streamId,
879 const DOMString &fileName,
880 long fileSize,
881 const DOMString &fileHash);
884 private:
886 void init();
888 DOMString host;
890 /**
891 * will be same as host, unless username is
892 * user@realm
893 */
894 DOMString realm;
896 int port;
898 DOMString username;
900 DOMString password;
902 DOMString resource;
904 DOMString jid;
906 int msgId;
908 TcpSocket *sock;
910 bool connected;
912 bool createSession();
914 bool checkConnect();
916 DOMString readStanza();
918 bool saslMd5Authenticate();
920 bool saslPlainAuthenticate();
922 bool saslAuthenticate();
924 bool iqAuthenticate(const DOMString &streamId);
926 bool keepGoing;
928 static const int writeBufLen = 2048;
930 unsigned char writeBuf[writeBufLen];
932 std::vector<XmppGroupChat *>groupChats;
934 static const int outputStreamCount = 16;
936 XmppStream *outputStreams[outputStreamCount];
938 static const int inputStreamCount = 16;
940 XmppStream *inputStreams[inputStreamCount];
942 static const int fileSendCount = 16;
944 XmppStream *fileSends[fileSendCount];
946 std::vector<XmppUser>roster;
947 };
952 //########################################################################
953 //# X M P P G R O U P C H A T
954 //########################################################################
956 /**
957 *
958 */
959 class XmppGroupChat
960 {
961 public:
963 /**
964 *
965 */
966 XmppGroupChat(const DOMString &groupJid);
968 /**
969 *
970 */
971 XmppGroupChat(const XmppGroupChat &other);
973 /**
974 *
975 */
976 virtual ~XmppGroupChat();
978 /**
979 *
980 */
981 virtual DOMString getGroupJid();
983 /**
984 *
985 */
986 virtual void userAdd(const DOMString &jid, const DOMString &nick);
988 /**
989 *
990 */
991 virtual void userDelete(const DOMString &jid, const DOMString &nick);
993 /**
994 *
995 */
996 virtual std::vector<XmppUser> getUserList() const;
999 private:
1001 DOMString groupJid;
1003 std::vector<XmppUser>userList;
1005 };
1016 } //namespace Pedro
1018 #endif /* __XMPP_H__ */
1020 //########################################################################
1021 //# E N D O F F I L E
1022 //########################################################################