1 /*
2  * SNAC base classes
3  *
4  * Copyright (C) 2001 Barnaby Gray <barnaby@beedesign.co.uk>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  *
20  */
21 
22 #include "SNAC-base.h"
23 #include "TLV.h"
24 
25 #include "buffer.h"
26 
27 namespace ICQ2000 {
28 
29   // ------------------ Abstract SNACs ---------------
30 
SNAC()31   SNAC::SNAC()
32     : m_flags(0x0000), m_requestID(0x00000000) { }
33 
Flags() const34   unsigned short SNAC::Flags() const {
35     return m_flags;
36   }
37 
RequestID() const38   unsigned int SNAC::RequestID() const {
39     return m_requestID;
40   }
41 
setRequestID(unsigned int id)42   void SNAC::setRequestID(unsigned int id) {
43     m_requestID = id;
44   }
45 
setFlags(unsigned short fl)46   void SNAC::setFlags(unsigned short fl) {
47     m_flags = fl;
48   }
49 
Version() const50   unsigned short InSNAC::Version() const {
51     return m_version;
52   }
53 
Parse(Buffer & b)54   void InSNAC::Parse(Buffer& b) {
55     b >> m_flags
56       >> m_requestID;
57     m_version = 0;
58     if (m_flags & 0x8000) { // contains version TLV
59 	unsigned short dataLen = 0;
60 	b >> dataLen;
61 	unsigned int pos = b.pos();
62 
63 	if (dataLen >= 2) {
64 	    unsigned short tlvType = 0;
65 	    b >> tlvType;
66 	    if (tlvType == 1) {
67 		unsigned short tlvLen = 0;
68     		b >> tlvLen;
69 		if (tlvLen >= 2) {
70 		    b >> m_version;
71 		}
72 	    }
73 	}
74 	b.setPos(pos + dataLen);
75     }
76     ParseBody(b);
77   }
78 
Output(Buffer & b) const79   void OutSNAC::Output(Buffer& b) const {
80     OutputHeader(b);
81     OutputBody(b);
82   }
83 
OutputHeader(Buffer & b) const84   void OutSNAC::OutputHeader(Buffer& b) const {
85     b << Family();
86     b << Subtype();
87     b << Flags();
88     b << RequestID();
89   }
90 
91   // --------------- Raw SNAC ---------------------------
92 
RawSNAC(unsigned short f,unsigned short t)93   RawSNAC::RawSNAC(unsigned short f, unsigned short t)
94     : m_family(f), m_subtype(t) { }
95 
ParseBody(Buffer & b)96   void RawSNAC::ParseBody(Buffer& b) {
97     b.advance(b.size());
98   }
99 
initCodeDescriptions()100   void ErrorSNAC::initCodeDescriptions() {
101     codeDescriptions[0x01] = "Invalid SNAC header";
102     codeDescriptions[0x02] = "Server rate limit exceeded";
103     codeDescriptions[0x03] = "Client rate limit exceeded";
104     codeDescriptions[0x04] = "Recipient is not logged in";
105     codeDescriptions[0x05] = "Requested service unavailable";
106     codeDescriptions[0x06] = "Requested service not defined";
107     codeDescriptions[0x07] = "You sent obsolete SNAC";
108     codeDescriptions[0x08] = "Not supported by server";
109     codeDescriptions[0x09] = "Not supported by client";
110     codeDescriptions[0x0A] = "Refused by client";
111     codeDescriptions[0x0B] = "Reply too big";
112     codeDescriptions[0x0C] = "Responses lost";
113     codeDescriptions[0x0D] = "Request denied";
114     codeDescriptions[0x0E] = "Incorrect SNAC format";
115     codeDescriptions[0x0F] = "Insufficient rights";
116     codeDescriptions[0x10] = "In local permit/deny (recipient blocked)";
117     codeDescriptions[0x11] = "Sender too evil";
118     codeDescriptions[0x12] = "Receiver too evil";
119     codeDescriptions[0x13] = "User temporarily unavailable";
120     codeDescriptions[0x14] = "No match";
121     codeDescriptions[0x15] = "List overflow";
122     codeDescriptions[0x16] = "Request ambiguous";
123     codeDescriptions[0x17] = "Server queue full";
124     codeDescriptions[0x18] = "Not while on AOL";
125   }
126 
ErrorInSNAC(unsigned short f,unsigned short t)127   ErrorInSNAC::ErrorInSNAC(unsigned short f, unsigned short t)
128     : m_family(f), m_subtype(t) { }
129 
getErrorDescription()130   std::string ErrorSNAC::getErrorDescription() {
131     if( codeDescriptions.empty() ) {
132       initCodeDescriptions();
133     }
134     std::string desc;
135     if( codeDescriptions.count(m_error_code) == 0 ) {
136       desc = "Unknown error";
137     } else {
138       desc = codeDescriptions[m_error_code];
139     }
140     return desc;
141   }
142 
ParseBody(Buffer & b)143   void ErrorInSNAC::ParseBody(Buffer& b) {
144   	b >> m_error_code;
145 	TLVList list;
146 	list.Parse(b, TLV_ParseMode_Channel02, 1);
147   }
148 
operator <<(Buffer & b,const ICQ2000::OutSNAC & snac)149   Buffer& operator<<(Buffer& b, const ICQ2000::OutSNAC& snac) { snac.Output(b); return b; }
150 
151 }
152 
153