/// <summary> /// Reads the error code and subcode from a SNAC(XX,01) packet /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(XX,01)</param> /// <param name="errorCode">The main error code contained in the SNAC</param> /// <param name="subCode">The subcode contained in the SNAC, or 0 if there is no subcode present</param> public static void GetSNACErrorCodes(DataPacket dp, out ushort errorCode, out ushort subCode) { errorCode = dp.Data.ReadUshort(); subCode = 0; if (dp.Data.HasMoreData) { using (TlvBlock tlvs = dp.Data.ReadTlvBlockByLength(dp.Data.GetRemainingByteCount())) { if (tlvs.HasTlv(0x0008)) { subCode = tlvs.ReadUshort(0x0008); } } } }
public void TestChatRoomCreation() { ByteStream dataStream = new ByteStream(Data.SNAC_0D_09); using (TlvBlock tlvs = new TlvBlock(dataStream.ReadByteArrayToEnd())) { Assert.IsTrue(tlvs.HasTlv(0x0004), "TLV 0x0004 missing from data stream"); ChatRoom chatRoom = new ChatRoom(new ByteStream(tlvs.ReadByteArray(0x0004))); Assert.AreEqual(0x0004, chatRoom.Exchange); Assert.AreEqual("!aol://2719:10-4-chat9614646934270543373", chatRoom.FullName); Assert.AreEqual(0x0000, chatRoom.Instance); Assert.AreEqual("Chat 9614646934270543373", chatRoom.DisplayName); Assert.AreEqual(new DateTime(2007, 8, 5, 20, 9, 21, DateTimeKind.Utc), chatRoom.CreationTime); } }
/// <summary> /// Processes a login response -- SNAC(17,03) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,03)</param> public static void ProcessLoginResponse(DataPacket dp) { // Pull apart SNAC(17,03) Cookie cookie; string BOSaddress; using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { if (tlvs.HasTlv(0x0008)) { ushort errorcode = tlvs.ReadUshort(0x0008); dp.ParentSession.OnLoginFailed((LoginErrorCode)errorcode); return; } BOSaddress = tlvs.ReadString(0x0005, Encoding.ASCII); cookie = Cookie.GetReceivedCookie(tlvs.ReadByteArray(0x0006)); } // Shut down the authorization connection // Socket shutdown is initiated by the server dp.ParentSession.OnLoginStatusUpdate("Authorized", 0.33); dp.ParentConnection.DisconnectFromServer(false); // Create a new connection to the BOS server Connection newconn = dp.ParentSession.Connections.CreateNewConnection(0x0001); string[] bosinfo = BOSaddress.Split(':'); newconn.ServerConnectionCompleted += new ServerConnectionCompletedHandler(newconn_ServerConnnectionCompleted); newconn.Server = bosinfo[0]; newconn.Port = Int32.Parse(bosinfo[1]); newconn.Cookie = cookie; newconn.ConnectToServer(); // The connection process continues when the server sends SNAC(01,03) }
/// <summary> /// Processes a login response -- SNAC(17,03) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,03)</param> public static void ProcessLoginResponse(DataPacket dp) { // Pull apart SNAC(17,03) Cookie cookie; string BOSaddress; using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { if (tlvs.HasTlv(0x0008)) { ushort errorcode = tlvs.ReadUshort(0x0008); dp.ParentSession.OnLoginFailed((LoginErrorCode)errorcode); return; } BOSaddress = tlvs.ReadString(0x0005, Encoding.ASCII); cookie = Cookie.GetReceivedCookie(tlvs.ReadByteArray(0x0006)); } // Shut down the authorization connection // Socket shutdown is initiated by the server dp.ParentSession.OnLoginStatusUpdate("Authorized", 0.33); dp.ParentConnection.DisconnectFromServer(false); // Create a new connection to the BOS server Connection newconn = dp.ParentSession.Connections.CreateNewConnection(0x0001); string[] bosinfo = BOSaddress.Split(':'); newconn.ServerConnectionCompleted += new ServerConnectionCompletedHandler(newconn_ServerConnnectionCompleted); newconn.Server = bosinfo[0]; newconn.Port = Int32.Parse(bosinfo[1]); newconn.Cookie = cookie; newconn.ConnectToServer(); // The connection process continues when the server sends SNAC(01,03) }
/// <summary> /// Reads a <see cref="UserInfo"/> from the stream /// </summary> public UserInfo ReadUserInfo() { UserInfo retval = new UserInfo(); byte screenNameLength = ReadByte(); if (screenNameLength == 0) { return(null); } retval.ScreenName = ReadString(screenNameLength, Encoding.ASCII); retval.WarningLevel = ReadUshort(); using (TlvBlock tlvBlock = ReadTlvBlock(ReadUshort())) { retval.Class = (UserClass)tlvBlock.ReadUshort(0x0001); retval.CreateTime = tlvBlock.ReadDateTime(0x0002); retval.SignonTime = tlvBlock.ReadDateTime(0x0003); retval.IdleTime = tlvBlock.ReadUshort(0x0004); if (retval.IdleTime == 0xFFFF) { retval.IdleTime = 0; } retval.RegisterTime = tlvBlock.ReadDateTime(0x0005); retval.ICQUserStatus = tlvBlock.ReadUint(0x0006); retval.ExternalIPAddress = tlvBlock.ReadUint(0x000A); // Read the DC info from 0x000C retval.ClientCapabilities = CapabilityProcessor.ProcessCLSIDList(tlvBlock.ReadByteArray(0x000D)); retval.OnlineTime = tlvBlock.ReadUint(0x000F); if (tlvBlock.HasTlv(0x001D)) { ReadIconInfo(tlvBlock.ReadByteArray(0x001D), retval); } } return(retval); }
/// <summary> /// Processes a login response -- SNAC(17,03) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,03)</param> internal void ProcessLoginResponse(DataPacket dp) { // Pull apart SNAC(17,03) Cookie cookie; string BOSaddress; using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { if (tlvs.HasTlv(0x0008)) { ushort errorcode = tlvs.ReadUshort(0x0008); parent.OnLoginFailed((LoginErrorCode)errorcode); return; } BOSaddress = tlvs.ReadString(0x0005, Encoding.ASCII); cookie = Cookie.GetReceivedCookie(tlvs.ReadByteArray(0x0006)); } // Shut down the authorization connection // Socket shutdown is initiated by the server parent.OnLoginStatusUpdate("Authorized", 0.33); dp.ParentConnection.DisconnectFromServer(false); // Create a new connection to the BOS server Connection newconn = parent.Connections.CreateNewConnection(0x0001); string[] bosinfo = BOSaddress.Split(':'); newconn.ServerConnectionCompleted += delegate(Connection conn) { conn.ReadyForData = true; conn.ReadHeader(); }; newconn.Server = bosinfo[0]; if (bosinfo.Length == 2) newconn.Port = Int32.Parse(bosinfo[1]); else newconn.Port = dp.ParentConnection.Port; Logging.WriteString("Connect to Server after auth. Address from dp: {0} - Address to connect: {1}:{2}", BOSaddress, newconn.Server, newconn.Port); newconn.Cookie = cookie; newconn.ConnectToServer(); // The login process continues when the server sends SNAC(01,03) on the new connection }
/// <summary> /// Processes an incoming ICBM message on channel 1 -- SNAC(04,07) /// </summary> /// <param name="stream">A received <see cref="ByteStream"/></param> /// <param name="ui">The UserInfo block that came with this message</param> private void ProcessChannelOneMessage(ByteStream stream, UserInfo ui) { IM message = new IM(ui); using (TlvBlock tlvs = new TlvBlock(stream.ReadByteArrayToEnd())) { message.IsAutoResponse = tlvs.HasTlv(0x0004); // If this message was received offline, cast it to an OfflineIM if (tlvs.HasTlv(0x0006)) { message = new OfflineIM(message); if (tlvs.HasTlv(0x0016)) { ((OfflineIM)message).ReceivedOn = tlvs.ReadDateTime(0x0016); } } GetChannelOneMessage(new ByteStream(tlvs.ReadByteArray(0x0002)), ref message); } // Figure out what to do with it if (message is OfflineIM) { OfflineIM offlineMessage = message as OfflineIM; if (isRetrievingOfflineMessages) { // Queue it for delivery AcceptIcbmOIM(offlineMessage); } else { // A single offline message? Okay then if (OfflineMessagesReceived != null) { List<OfflineIM> tmpList = new List<OfflineIM>(1); tmpList.Add(offlineMessage); OfflineMessagesReceived(this, new OfflineMessagesReceivedEventArgs(parent.ScreenName, new Collection<OfflineIM>(tmpList))); } } // Offline messages don't get delivered via OnMessageReceived - if the offline messages event // isn't hooked up, tough stuff. return; } else { OnMessageReceived(message); } }
/// <summary> /// Processes the inner TLV list in TLV 0x0005 and returns a new DirectConnection /// </summary> private DirectConnection ProcessChannel2Tlv05(ByteStream stream, UserInfo ui, DataPacket dp) { byte[] invitemessage; Encoding encoding = Encoding.ASCII; string language = "en"; DirectConnection directconn = null; // Pull the type, cookie, and capability array RendezvousType rtype = RendezvousData.TypeFromUshort(stream.ReadUshort()); Cookie cookie = Cookie.GetReceivedCookie(stream.ReadByteArray(8)); byte[] capabilitiesArray = stream.ReadByteArray(16); Capabilities capabilities = CapabilityProcessor.ProcessCLSIDList(capabilitiesArray); // Create the correct type of connection based on the capability if (capabilities == Capabilities.SendFiles) { if ((directconn = parent.Connections.GetDirectConnectionByCookie(cookie)) == null) { directconn = parent.Connections.CreateNewFileTransferConnection( DirectConnectionMethod.Direct, DirectConnectRole.Receiver); } } else if (capabilities == Capabilities.DirectIM) { if ((directconn = parent.Connections.GetDirectConnectionByCookie(cookie)) == null) { directconn = parent.Connections.CreateNewDirectIMConnection( DirectConnectionMethod.Direct, DirectConnectRole.Receiver); } } else if (capabilities == Capabilities.Chat) { directconn = parent.Connections.CreateNewChatInvitationConnection(DirectConnectRole.Receiver); } else { // Currently unsupported parent.OnWarning(ServerErrorCode.UnknownRendezvousChannel, dp); return null; } directconn.Other = ui; directconn.Cookie = cookie; directconn.Type = rtype; ByteStream serviceData = null; Encoding serviceDataEncoding = Encoding.ASCII; // Process the inner TLV list using (TlvBlock tlvs = new TlvBlock(stream.ReadByteArrayToEnd())) { directconn.AOLProxyIP = tlvs.ReadIPAddress(DC_PROXY_IP_ADDRESS); // proxy ip directconn.ClientIP = tlvs.ReadIPAddress(DC_CLIENT_IP_ADDRESS); // internal ip directconn.VerifiedIP = tlvs.ReadIPAddress(0x0004); // external ip directconn.Port = tlvs.ReadUshort(DC_PORT); directconn.Sequence = RendezvousData.SequenceFromUshort(tlvs.ReadUshort(DC_SEQUENCE_NUMBER)); invitemessage = tlvs.ReadByteArray(DC_MESSAGE); if (tlvs.HasTlv(0x000D)) { encoding = Encoding.GetEncoding(tlvs.ReadString(0x000D, Encoding.ASCII)); } language = tlvs.ReadString(0x000E, Encoding.ASCII); directconn.Method = (tlvs.HasTlv(DC_USE_PROXY_FLAG)) ? DirectConnectionMethod.Proxied : DirectConnectionMethod.Direct; serviceData = new ByteStream(tlvs.ReadByteArray(0x2711)); if (tlvs.HasTlv(0x2712)) { serviceDataEncoding = Encoding.GetEncoding(tlvs.ReadString(0x2712, Encoding.ASCII)); } } if (invitemessage != null) { directconn.Message = encoding.GetString(invitemessage, 0, invitemessage.Length); } // Process the extra data, if necessary if (directconn is FileTransferConnection || directconn is DirectIMConnection) { ProcessDirectConnectionRequest(directconn, serviceData); } else if (directconn is ChatInvitationConnection) { ChatInvitationConnection cic = directconn as ChatInvitationConnection; cic.ChatInvite = new ChatInvitation(); cic.ChatInvite.Message = directconn.Message; cic.ChatInvite.Encoding = encoding; cic.ChatInvite.Language = language; ProcessChatInvitationRequest(cic, serviceData); } return directconn; }