447df7868e06c5906ef1aa6d1e97e16d87a7c4a6
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 };
91 /**
92 * Class that emits information from a client
93 */
94 class XmppEvent
95 {
97 public:
99 /**
100 * People might want to refer to these docs to understand
101 * the XMPP terminology used here.
102 * http://www.ietf.org/rfc/rfc3920.txt -- Xmpp Core
103 * http://www.ietf.org/rfc/rfc3921.txt -- Messaging and presence
104 * http://www.jabber.org/jeps/jep-0077.html -- In-Band registration
105 * http://www.jabber.org/jeps/jep-0045.html -- Multiuser Chat
106 * http://www.jabber.org/jeps/jep-0047.html -- In-Band byte streams
107 * http://www.jabber.org/jeps/jep-0096.html -- File transfer
108 */
110 /**
111 * No event type. Default
112 */
113 static const int EVENT_NONE = 0;
115 /**
116 * Client emits a status message. Message is in getData().
117 */
118 static const int EVENT_STATUS = 1;
120 /**
121 * Client emits an error message. Message is in getData().
122 */
123 static const int EVENT_ERROR = 2;
125 /**
126 * Client has connected to a host. Host name is in getData().
127 */
128 static const int EVENT_CONNECTED = 10;
130 /**
131 * Client has disconnected from a host. Host name is in getData().
132 */
133 static const int EVENT_DISCONNECTED = 11;
135 /**
136 * Client has successfully registered a new account on a server.
137 * The server is in getFrom(), the user in getTo()
138 */
139 static const int EVENT_REGISTRATION_NEW = 20;
141 /**
142 * Client has successfully modified an existing account on a server.
143 * The server is in getFrom(), the user in getTo()
144 */
145 static const int EVENT_REGISTRATION_MODIFY = 21;
147 /**
148 * Client has successfully cancelled an existing account on a server.
149 * The server is in getFrom(), the user in getTo()
150 */
151 static const int EVENT_REGISTRATION_CANCEL = 22;
153 /**
154 * A <presence> packet has been received.
155 * getFrom() returns the full jabber id
156 * getPresence() returns the available/unavailable boolean
157 * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc
158 * getStatus() returns a status message, sent from a client
159 * Note: if a presence packet is determined to be MUC, it is
160 * rather sent as an EVENT_MUC_JOIN, LEAVE, or PRESENCE
161 */
162 static const int EVENT_PRESENCE = 30;
164 /**
165 * Client has just received a complete roster. The collected information
166 * can be found at client.getRoster(), and is a std::vector of XmppUser
167 * records.
168 */
169 static const int EVENT_ROSTER = 31;
171 /**
172 * Client has just received a message packet.
173 * getFrom() returns the full jabber id of the sender
174 * getData() returns the text of the message
175 * getDom() returns the DOM treelet for this stanza. This is provided
176 * to make message extension easier.
177 * Note: if a message packet is determined to be MUC, it is
178 * rather sent as an EVENT_MUC_MESSAGE
179 */
180 static const int EVENT_MESSAGE = 32;
182 /**
183 * THIS user has just joined a multi-user chat group.
184 * getGroup() returns the group name
185 * getFrom() returns the nick of the user in the group
186 * getPresence() returns the available/unavailable boolean
187 * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc
188 * getStatus() returns a status message, sent from a client
189 */
190 static const int EVENT_MUC_JOIN = 40;
192 /**
193 * THIS user has just left a multi-user chat group.
194 * getGroup() returns the group name
195 * getFrom() returns the nick of the user in the group
196 * getPresence() returns the available/unavailable boolean
197 * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc
198 * getStatus() returns a status message, sent from a client
199 */
200 static const int EVENT_MUC_LEAVE = 41;
202 /**
203 * Presence for another user in a multi-user chat room.
204 * getGroup() returns the group name
205 * getFrom() returns the nick of the user in the group
206 * getPresence() returns the available/unavailable boolean
207 * getShow() returns the jabber 'show' string: 'show', 'away', 'xa', etc
208 * getStatus() returns a status message, sent from a client
209 */
210 static const int EVENT_MUC_PRESENCE = 42;
212 /**
213 * Client has just received a message packet from a multi-user chat room
214 * getGroup() returns the group name
215 * getFrom() returns the full jabber id of the sender
216 * getData() returns the text of the message
217 * getDom() returns the DOM treelet for this stanza. This is provided
218 * to make message extension easier.
219 */
220 static const int EVENT_MUC_MESSAGE = 43;
222 /**
223 * Client has begun receiving a stream
224 */
225 static const int EVENT_STREAM_RECEIVE_INIT = 50;
227 /**
228 * Client receives another stream packet.
229 */
230 static const int EVENT_STREAM_RECEIVE = 51;
232 /**
233 * Client has received the end of a stream
234 */
235 static const int EVENT_STREAM_RECEIVE_CLOSE = 52;
237 /**
238 * Other client has accepted a file.
239 */
240 static const int EVENT_FILE_ACCEPTED = 60;
242 /**
243 * This client has just received a file.
244 */
245 static const int EVENT_FILE_RECEIVE = 61;
247 /**
248 *
249 */
250 XmppEvent(int type);
252 /**
253 *
254 */
255 XmppEvent(const XmppEvent &other);
257 /**
258 *
259 */
260 virtual XmppEvent &operator=(const XmppEvent &other);
262 /**
263 *
264 */
265 virtual ~XmppEvent();
267 /**
268 *
269 */
270 virtual void assign(const XmppEvent &other);
272 /**
273 *
274 */
275 virtual int getType() const;
278 /**
279 *
280 */
281 virtual DOMString getIqId() const;
284 /**
285 *
286 */
287 virtual void setIqId(const DOMString &val);
289 /**
290 *
291 */
292 virtual DOMString getStreamId() const;
295 /**
296 *
297 */
298 virtual void setStreamId(const DOMString &val);
300 /**
301 *
302 */
303 virtual bool getPresence() const;
306 /**
307 *
308 */
309 virtual void setPresence(bool val);
311 /**
312 *
313 */
314 virtual DOMString getShow() const;
317 /**
318 *
319 */
320 virtual void setShow(const DOMString &val);
322 /**
323 *
324 */
325 virtual DOMString getStatus() const;
327 /**
328 *
329 */
330 virtual void setStatus(const DOMString &val);
332 /**
333 *
334 */
335 virtual DOMString getTo() const;
337 /**
338 *
339 */
340 virtual void setTo(const DOMString &val);
342 /**
343 *
344 */
345 virtual DOMString getFrom() const;
347 /**
348 *
349 */
350 virtual void setFrom(const DOMString &val);
352 /**
353 *
354 */
355 virtual DOMString getGroup() const;
357 /**
358 *
359 */
360 virtual void setGroup(const DOMString &val);
362 /**
363 *
364 */
365 virtual Element *getDOM() const;
368 /**
369 *
370 */
371 virtual void setDOM(const Element *val);
373 /**
374 *
375 */
376 virtual std::vector<XmppUser> getUserList() const;
378 /**
379 *
380 */
381 virtual void setUserList(const std::vector<XmppUser> &userList);
383 /**
384 *
385 */
386 virtual DOMString getFileName() const;
389 /**
390 *
391 */
392 virtual void setFileName(const DOMString &val);
395 /**
396 *
397 */
398 virtual DOMString getFileDesc() const;
401 /**
402 *
403 */
404 virtual void setFileDesc(const DOMString &val);
407 /**
408 *
409 */
410 virtual long getFileSize() const;
413 /**
414 *
415 */
416 virtual void setFileSize(long val);
418 /**
419 *
420 */
421 virtual DOMString getFileHash() const;
423 /**
424 *
425 */
426 virtual void setFileHash(const DOMString &val);
428 /**
429 *
430 */
431 virtual DOMString getData() const;
434 /**
435 *
436 */
437 virtual void setData(const DOMString &val);
439 private:
441 int eventType;
443 DOMString iqId;
445 DOMString streamId;
447 bool presence;
449 DOMString show;
451 DOMString status;
453 DOMString to;
455 DOMString from;
457 DOMString group;
459 DOMString data;
461 DOMString fileName;
462 DOMString fileDesc;
463 long fileSize;
464 DOMString fileHash;
466 Element *dom;
468 std::vector<XmppUser>userList;
470 };
473 //########################################################################
474 //# X M P P E V E N T L I S T E N E R
475 //########################################################################
477 class XmppEventListener
478 {
479 public:
481 /**
482 *
483 */
484 XmppEventListener()
485 {}
487 /**
488 *
489 */
490 XmppEventListener(const XmppEventListener &other)
491 {}
494 /**
495 *
496 */
497 virtual ~XmppEventListener()
498 {}
500 /**
501 *
502 */
503 virtual void processXmppEvent(const XmppEvent &event)
504 {}
506 };
510 //########################################################################
511 //# X M P P E V E N T T A R G E T
512 //########################################################################
514 class XmppEventTarget
515 {
516 public:
518 /**
519 *
520 */
521 XmppEventTarget();
523 /**
524 *
525 */
526 XmppEventTarget(const XmppEventTarget &other);
528 /**
529 *
530 */
531 virtual ~XmppEventTarget();
534 //###########################
535 //# M E S S A G E S
536 //###########################
539 /**
540 * Send an error message to all subscribers
541 */
542 void error(char *fmt, ...);
545 /**
546 * Send a status message to all subscribers
547 */
548 void status(char *fmt, ...);
550 //###########################
551 //# LISTENERS
552 //###########################
554 /**
555 *
556 */
557 virtual void dispatchXmppEvent(const XmppEvent &event);
559 /**
560 *
561 */
562 virtual void addXmppEventListener(const XmppEventListener &listener);
564 /**
565 *
566 */
567 virtual void removeXmppEventListener(const XmppEventListener &listener);
569 /**
570 *
571 */
572 virtual void clearXmppEventListeners();
574 /**
575 *
576 */
577 void eventQueueEnable(bool val);
579 /**
580 *
581 */
582 int eventQueueAvailable();
584 /**
585 *
586 */
587 XmppEvent eventQueuePop();
590 private:
592 std::vector<XmppEventListener *> listeners;
594 std::vector<XmppEvent> eventQueue;
595 bool eventQueueEnabled;
597 static const int targetWriteBufLen = 2048;
599 char targetWriteBuf[targetWriteBufLen];
600 };
606 //########################################################################
607 //# X M P P C L I E N T
608 //########################################################################
611 class TcpSocket;
612 class XmppChat;
613 class XmppGroupChat;
614 class XmppStream;
616 class XmppClient : public XmppEventTarget
617 {
619 public:
621 //###########################
622 //# CONSTRUCTORS
623 //###########################
625 /**
626 *
627 */
628 XmppClient();
630 /**
631 *
632 */
633 XmppClient(const XmppClient &other);
635 /**
636 *
637 */
638 void assign(const XmppClient &other);
640 /**
641 *
642 */
643 virtual ~XmppClient();
646 //###########################
647 //# UTILITY
648 //###########################
650 /**
651 *
652 */
653 virtual bool pause(unsigned long millis);
655 /**
656 *
657 */
658 DOMString toXml(const DOMString &str);
660 //###########################
661 //# CONNECTION
662 //###########################
664 /**
665 *
666 */
667 virtual bool connect();
669 /**
670 *
671 */
672 virtual bool connect(DOMString host, int port,
673 DOMString userName,
674 DOMString password,
675 DOMString resource);
677 /**
678 *
679 */
680 virtual bool disconnect();
683 /**
684 *
685 */
686 virtual bool write(char *fmt, ...);
688 //#######################
689 //# V A R I A B L E S
690 //#######################
692 /**
693 *
694 */
695 virtual bool isConnected()
696 { return connected; }
698 /**
699 *
700 */
701 virtual DOMString getHost()
702 { return host; }
704 /**
705 *
706 */
707 virtual void setHost(const DOMString &val)
708 { host = val; }
710 /**
711 *
712 */
713 virtual DOMString getRealm()
714 { return realm; }
716 /**
717 *
718 */
719 virtual void setRealm(const DOMString &val)
720 { realm = val; }
722 /**
723 *
724 */
725 virtual int getPort()
726 { return port; }
728 /**
729 *
730 */
731 virtual void setPort(int val)
732 { port = val; }
734 /**
735 *
736 */
737 virtual DOMString getUsername();
739 /**
740 *
741 */
742 virtual void setUsername(const DOMString &val);
744 /**
745 *
746 */
747 virtual DOMString getPassword()
748 { return password; }
750 /**
751 *
752 */
753 virtual void setPassword(const DOMString &val)
754 { password = val; }
756 /**
757 *
758 */
759 virtual DOMString getResource()
760 { return resource; }
762 /**
763 *
764 */
765 virtual void setResource(const DOMString &val)
766 { resource = val; }
768 /**
769 *
770 */
771 virtual DOMString getJid()
772 { return jid; }
774 /**
775 *
776 */
777 virtual int getMsgId()
778 { return msgId++; }
780 /**
781 *
782 */
783 virtual void setDoRegister(bool val)
784 { doRegister = val; }
787 /**
788 *
789 */
790 virtual bool getDoRegister()
791 { return doRegister; }
795 //#######################
796 //# P R O C E S S I N G
797 //#######################
800 /**
801 *
802 */
803 bool processMessage(Element *root);
805 /**
806 *
807 */
808 bool processPresence(Element *root);
810 /**
811 *
812 */
813 bool processIq(Element *root);
815 /**
816 *
817 */
818 virtual bool receiveAndProcess();
820 /**
821 *
822 */
823 virtual bool receiveAndProcessLoop();
825 //#######################
826 //# ROSTER
827 //#######################
829 /**
830 *
831 */
832 bool rosterAdd(const DOMString &rosterGroup,
833 const DOMString &otherJid,
834 const DOMString &name);
836 /**
837 *
838 */
839 bool rosterDelete(const DOMString &otherJid);
841 /**
842 *
843 */
844 std::vector<XmppUser> getRoster();
846 /**
847 *
848 */
849 virtual void rosterShow(const DOMString &jid, const DOMString &show);
851 //#######################
852 //# CHAT (individual)
853 //#######################
855 /**
856 *
857 */
858 virtual bool message(const DOMString &user, const DOMString &subj,
859 const DOMString &text);
861 /**
862 *
863 */
864 virtual bool message(const DOMString &user, const DOMString &text);
866 /**
867 *
868 */
869 virtual bool presence(const DOMString &presence);
871 //#######################
872 //# GROUP CHAT
873 //#######################
875 /**
876 *
877 */
878 virtual bool groupChatCreate(const DOMString &groupJid);
880 /**
881 *
882 */
883 virtual void groupChatDelete(const DOMString &groupJid);
885 /**
886 *
887 */
888 bool groupChatExists(const DOMString &groupJid);
890 /**
891 *
892 */
893 virtual void groupChatsClear();
895 /**
896 *
897 */
898 virtual void groupChatUserAdd(const DOMString &groupJid,
899 const DOMString &nick,
900 const DOMString &jid);
901 /**
902 *
903 */
904 virtual void groupChatUserShow(const DOMString &groupJid,
905 const DOMString &nick,
906 const DOMString &show);
908 /**
909 *
910 */
911 virtual void groupChatUserDelete(const DOMString &groupJid,
912 const DOMString &nick);
914 /**
915 *
916 */
917 virtual std::vector<XmppUser>
918 XmppClient::groupChatGetUserList(const DOMString &groupJid);
920 /**
921 *
922 */
923 virtual bool groupChatJoin(const DOMString &groupJid,
924 const DOMString &nick,
925 const DOMString &pass);
927 /**
928 *
929 */
930 virtual bool groupChatLeave(const DOMString &groupJid,
931 const DOMString &nick);
933 /**
934 *
935 */
936 virtual bool groupChatMessage(const DOMString &groupJid,
937 const DOMString &msg);
939 /**
940 *
941 */
942 virtual bool groupChatPrivateMessage(const DOMString &groupJid,
943 const DOMString &toNick,
944 const DOMString &msg);
946 /**
947 *
948 */
949 virtual bool groupChatPresence(const DOMString &groupJid,
950 const DOMString &nick,
951 const DOMString &presence);
954 //#######################
955 //# STREAMS
956 //#######################
958 typedef enum
959 {
960 STREAM_AVAILABLE,
961 STREAM_OPENING,
962 STREAM_OPEN,
963 STREAM_CLOSING,
964 STREAM_CLOSED,
965 STREAM_ERROR
966 } StreamStates;
968 /**
969 *
970 */
971 virtual int outputStreamOpen(const DOMString &jid,
972 const DOMString &streamId);
974 /**
975 *
976 */
977 virtual int outputStreamWrite(int streamId,
978 const unsigned char *buf, unsigned long len);
980 /**
981 *
982 */
983 virtual int outputStreamClose(int streamId);
985 /**
986 *
987 */
988 virtual int inputStreamOpen(const DOMString &jid,
989 const DOMString &streamId,
990 const DOMString &iqId);
992 /**
993 *
994 */
995 virtual int inputStreamAvailable(int streamId);
997 /**
998 *
999 */
1000 virtual std::vector<unsigned char> inputStreamRead(int streamId);
1002 /**
1003 *
1004 */
1005 virtual bool inputStreamClosing(int streamId);
1007 /**
1008 *
1009 */
1010 virtual int inputStreamClose(int streamId);
1013 //#######################
1014 //# FILE TRANSFERS
1015 //#######################
1017 /**
1018 *
1019 */
1020 virtual bool fileSend(const DOMString &destJid,
1021 const DOMString &offeredName,
1022 const DOMString &fileName,
1023 const DOMString &description);
1025 /**
1026 *
1027 */
1028 virtual bool fileSendBackground(const DOMString &destJid,
1029 const DOMString &offeredName,
1030 const DOMString &fileName,
1031 const DOMString &description);
1033 /**
1034 *
1035 */
1036 virtual bool fileReceive(const DOMString &fromJid,
1037 const DOMString &iqId,
1038 const DOMString &streamId,
1039 const DOMString &fileName,
1040 long fileSize,
1041 const DOMString &fileHash);
1042 /**
1043 *
1044 */
1045 virtual bool fileReceiveBackground(const DOMString &fromJid,
1046 const DOMString &iqId,
1047 const DOMString &streamId,
1048 const DOMString &fileName,
1049 long fileSize,
1050 const DOMString &fileHash);
1053 private:
1055 void init();
1057 DOMString host;
1059 /**
1060 * will be same as host, unless username is
1061 * user@realm
1062 */
1063 DOMString realm;
1065 int port;
1067 DOMString username;
1069 DOMString password;
1071 DOMString resource;
1073 DOMString jid;
1075 int msgId;
1077 TcpSocket *sock;
1079 bool connected;
1081 bool createSession();
1083 bool checkConnect();
1085 DOMString readStanza();
1087 bool saslMd5Authenticate();
1089 bool saslPlainAuthenticate();
1091 bool saslAuthenticate();
1093 bool iqAuthenticate(const DOMString &streamId);
1095 bool inBandRegistration();
1097 bool keepGoing;
1099 bool doRegister;
1101 static const int writeBufLen = 2048;
1103 unsigned char writeBuf[writeBufLen];
1105 std::vector<XmppGroupChat *>groupChats;
1107 static const int outputStreamCount = 16;
1109 XmppStream *outputStreams[outputStreamCount];
1111 static const int inputStreamCount = 16;
1113 XmppStream *inputStreams[inputStreamCount];
1115 static const int fileSendCount = 16;
1117 XmppStream *fileSends[fileSendCount];
1119 std::vector<XmppUser>roster;
1120 };
1125 //########################################################################
1126 //# X M P P G R O U P C H A T
1127 //########################################################################
1129 /**
1130 *
1131 */
1132 class XmppGroupChat
1133 {
1134 public:
1136 /**
1137 *
1138 */
1139 XmppGroupChat(const DOMString &groupJid);
1141 /**
1142 *
1143 */
1144 XmppGroupChat(const XmppGroupChat &other);
1146 /**
1147 *
1148 */
1149 virtual ~XmppGroupChat();
1151 /**
1152 *
1153 */
1154 virtual DOMString getGroupJid();
1156 /**
1157 *
1158 */
1159 virtual void userAdd(const DOMString &nick,
1160 const DOMString &jid);
1161 /**
1162 *
1163 */
1164 virtual void userShow(const DOMString &nick,
1165 const DOMString &show);
1167 /**
1168 *
1169 */
1170 virtual void userDelete(const DOMString &nick);
1172 /**
1173 *
1174 */
1175 virtual std::vector<XmppUser> getUserList() const;
1178 private:
1180 DOMString groupJid;
1182 std::vector<XmppUser>userList;
1184 };
1195 } //namespace Pedro
1197 #endif /* __XMPP_H__ */
1199 //########################################################################
1200 //# E N D O F F I L E
1201 //########################################################################