Ejemplo n.º 1
0
        /// <summary>
        /// Enqueues a SNAC for transmission with the appropriate RateClass
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <remarks>
        /// <para>
        /// This needs commenting
        /// </para>
        /// </remarks>
        public static void BuildFLAP(DataPacket dp)
        {
            // Build the FLAP header
            dp.FLAP.DatagramSequenceNumber = 0; // Gets bound in Connection.cs
            dp.FLAP.Channel = (byte)FLAPChannels.SNACData;

            // Build the size of the data to be sent, not counting the FLAP header
            dp.FLAP.DataSize = (ushort)(10 + dp.Data.GetByteCount());
            dp.Data.PrependOscarHeaders(dp.FLAP, dp.SNAC);
            SNACFunctions.DispatchToRateClass(dp);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Notifies the BOS server that the client is ready to go online -- SNAC(01,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <remarks>
        /// The client sends this SNAC to notify the server that it is ready to receive messages
        /// and online notifications.
        /// <para>
        /// This SNAC must be sent within 30 seconds of connection, or the connection
        /// will drop. This should not ever be a problem, barring a lost connection well below
        /// the level of this library.
        /// </para>
        /// </remarks>
        public static void SendReadyNotification(DataPacket dp)
        {
            // Build SNAC(01,02)
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.ClientOnline;
            sh.Flags           = 0x0000;
            sh.RequestID       = Session.GetNextRequestID();

            ConnectionManager cm = dp.ParentSession.Connections;

            ushort[]      families = cm.GetFamilies(dp.ParentConnection);
            FamilyManager fm       = dp.ParentSession.Families;

            Array.Sort(families);
            Array.Reverse(families);

            bool isChatRoomConnection = false;
            bool isChatNavService     = false;

            ByteStream stream = new ByteStream();

            DataPacket[][] delayedframes = new DataPacket[families.Length][];

            for (int i = 0; i < families.Length; i++)
            {
                ushort family = families[i];
                delayedframes[i] = dp.ParentSession.Connections.GetDelayedPackets(family);

                stream.WriteUshort(family);
                stream.WriteUshort(fm.GetFamilyVersion(family));
                stream.WriteUshort(fm.GetFamilyToolID(family));
                stream.WriteUshort(fm.GetFamilyToolVersion(family));

                if (family == 0x000D)
                {
                    isChatNavService = true;
                }
                else if (family == 0x000E)
                {
                    isChatRoomConnection = true;
                }
            }

            /*
             * The initial service connection has to send SNAC(01,1E) before it actually
             * sends SNAC(01,02), thus the check for the initial connection here
             * and after it gets sent.
             */
            Session sess = dp.ParentSession;

            if (!sess.LoggedIn)
            {
                SetExtendedStatus(sess, sess.AvailableMessage, ICQFlags.Normal, ICQStatus.Online);
                SetExtendedStatus(sess, null, ICQFlags.Normal, ICQStatus.Online);
            }

            // The connection is done, so start sending keepalives
            dp.ParentConnection.Connecting   = false;
            dp.ParentConnection.ReadyForData = true;

            // Build and send a new DataPacket instead of re-using the originator;
            // SNAC(01,02) was getting sent twice on child connections with the reuse
            DataPacket dp2 = Marshal.BuildDataPacket(dp.ParentSession, sh, stream);

            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            /*
             * If this is a new service connection, there is probably at least one
             * delayed packet. Process those packets. Additionally, if the new connection is
             * a chatroom connection, query the Rendezvous manager to see if it is the result
             * of an explict room creation (or implict, as in accepting a chat invitation).
             * If it was explict, notify the user that it's done
             */
            if (sess.LoggedIn)
            {
                foreach (DataPacket[] list in delayedframes)
                {
                    if (list == null)
                    {
                        continue;
                    }
                    foreach (DataPacket dp_delay in list)
                    {
                        dp_delay.ParentConnection = dp.ParentConnection;
                        SNACFunctions.DispatchToRateClass(dp_delay);
                    }
                }

                if (isChatNavService)
                {
                    sess.ChatRooms.OnChatNavServiceAvailable();
                }
                else if (isChatRoomConnection)
                {
                    ChatRoom chatRoom = sess.Connections.GetChatByConnection((ChatConnection)dp.ParentConnection);
                    sess.ChatRooms.OnChatRoomConnectionAvailable(chatRoom);
                }
            }
        }