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