Пример #1
0
        /// <summary>
        /// This method sends a data_sm packet synchronously over to the peer.
        /// </summary>
        /// <param name="pdu">data_sm packet</param>
        /// <returns>data_sm response</returns>
        public data_sm_resp SendData(data_sm pdu)
        {
            data_sm_resp   response = null;
            PduSyncronizer sync     = AddWaitingPdu(pdu);

            if (sync != null)
            {
                if (IsBound && SendPdu(pdu))
                {
                    if (sync.WaitForResponse())
                    {
                        response = sync.PduResponse as data_sm_resp;
                        if (response == null)
                        {
                            response = new data_sm_resp(pdu.SequenceNumber, sync.PduResponse.Status);
                        }
                    }
                    else
                    {
                        response = new data_sm_resp(pdu.SequenceNumber, StatusCodes.ESME_RINVEXPIRY);
                    }
                }
                else
                {
                    response = new data_sm_resp(pdu.SequenceNumber, StatusCodes.ESME_RDELIVERYFAILURE);
                }
                FindAndRemoveWaitingPdu(pdu.SequenceNumber);
            }
            else
            {
                response = new data_sm_resp(pdu.SequenceNumber, StatusCodes.ESME_RMSGQFUL);
            }

            return(response);
        }
Пример #2
0
 /// <summary>
 /// This adds a PDU to our waiting list.
 /// </summary>
 /// <param name="pdu">PDU</param>
 /// <returns>True/False</returns>
 internal PduSyncronizer AddWaitingPdu(SmppPdu pdu)
 {
     lock (this.pendingRequests)
     {
         if (this.pendingRequests.Count < DefaultPendingRequestLimit)
         {
             PduSyncronizer sync = new PduSyncronizer(pdu, ResponseTimeout);
             this.pendingRequests.Add(pdu.SequenceNumber, sync);
             return(sync);
         }
     }
     return(null);
 }
Пример #3
0
        /// <summary>
        /// This locates and removes a PduSyncronizer.
        /// </summary>
        /// <param name="seqNum">Sequence number to locate</param>
        /// <returns>PduSyncronizer in question</returns>
        internal PduSyncronizer FindAndRemoveWaitingPdu(int seqNum)
        {
            PduSyncronizer sync = null;

            lock (this.pendingRequests)
            {
                if (this.pendingRequests.ContainsKey(seqNum))
                {
                    sync = this.pendingRequests[seqNum];
                    this.pendingRequests.Remove(seqNum);
                }
            }
            return(sync);
        }
Пример #4
0
        /// <summary>
        /// This method sends an enquire link
        /// </summary>
        /// <returns></returns>
        public enquire_link_resp EnquireLink()
        {
            SmppPdu           pdu      = new enquire_link();
            enquire_link_resp response = null;
            PduSyncronizer    sync     = AddWaitingPdu(pdu);

            if (sync != null)
            {
                if (IsBound && SendPdu(pdu))
                {
                    if (sync.WaitForResponse())
                    {
                        response = sync.PduResponse as enquire_link_resp;
                        if (response == null)
                        {
                            response = new enquire_link_resp(pdu.SequenceNumber, sync.PduResponse.Status);
                        }
                    }
                    else
                    {
                        response = new enquire_link_resp(pdu.SequenceNumber, StatusCodes.ESME_RINVEXPIRY);
                    }
                }
                else
                {
                    response = new enquire_link_resp(pdu.SequenceNumber, StatusCodes.ESME_RINVCMDID);
                }
                FindAndRemoveWaitingPdu(pdu.SequenceNumber);
            }
            else
            {
                response = new enquire_link_resp(pdu.SequenceNumber, StatusCodes.ESME_RMSGQFUL);
            }

            return(response);
        }
Пример #5
0
        /// <summary>
        /// This method is used to unbind our session synchronously.
        /// </summary>
        /// <returns>Unbind response PDU</returns>
        public unbind_resp UnBind()
        {
            unbind         pdu      = new unbind();
            unbind_resp    response = null;
            PduSyncronizer sync     = AddWaitingPdu(pdu);

            if (sync != null)
            {
                if (IsBound && SendPdu(pdu))
                {
                    if (sync.WaitForResponse())
                    {
                        response = sync.PduResponse as unbind_resp;
                        if (response == null)
                        {
                            response = new unbind_resp(pdu.SequenceNumber, sync.PduResponse.Status);
                        }
                    }
                    else
                    {
                        response = new unbind_resp(pdu.SequenceNumber, StatusCodes.ESME_RINVEXPIRY);
                    }
                }
                else
                {
                    response = new unbind_resp(pdu.SequenceNumber, StatusCodes.ESME_RINVBNDSTS);
                }
                FindAndRemoveWaitingPdu(pdu.SequenceNumber);
            }
            else
            {
                response = new unbind_resp(pdu.SequenceNumber, StatusCodes.ESME_RMSGQFUL);
            }

            return(response);
        }
Пример #6
0
        /// <summary>
        /// This method is called when data is received from our socket.
        /// </summary>
        /// <param name="sender">The socket which sent the data</param>
        /// <param name="args">Socket data</param>
        protected virtual void OnReceiveData(object sender, SocketEventArgs args)
        {
            SocketClient  socket       = (SocketClient)sender;
            ReadEventArgs re           = (ReadEventArgs)args;
            int           packetLength = SmppPdu.REQUIRED_SIZE;

            if (re.Length >= packetLength)
            {
                // Get the first DWORD from the buffer; this is the total size of the packet.
                packetLength = BitConverter.ToInt32(new byte[] { re.Buffer[3], re.Buffer[2], re.Buffer[1], re.Buffer[0] }, 0);
                if (re.Length >= packetLength)
                {
                    try
                    {
                        // Have the entire buffer; parse it out.
                        SmppPdu pdu = SmppPdu.Create(new SmppByteStream(re.Buffer));
                        SmppPduReceivedEventArgs ea = new SmppPduReceivedEventArgs(this, pdu);
                        FireEvent(EventType.PreProcessPdu, ea);

                        PduSyncronizer sync = null;
                        if (pdu is SmppResponse)
                        {
                            if ((sync = FindAndRemoveWaitingPdu(pdu.SequenceNumber)) != null)
                            {
                                ((SmppResponse)pdu).OriginalRequest = (SmppRequest)sync.PduRequest;
                            }
                            else
                            {
                                throw new SmppException("Invalid pdu response received with no pending request: " + pdu.ToString());
                            }
                        }

                        if (!ea.Handled)
                        {
                            try
                            {
                                ProcessPdu(pdu);
                            }
                            catch (InvalidSmppStateException)
                            {
                                if (pdu.RequiresResponse)
                                {
                                    SendPdu(new generic_nack(StatusCodes.ESME_RINVCMDID, pdu.SequenceNumber));
                                }
                            }
                        }

                        if (sync != null)
                        {
                            sync.PduResponse = pdu;
                        }
                    }
                    catch (PduException pduex)
                    {
                        SmppPdu pdu = (pduex.HasPDU) ? pduex.PDU : null;
                        if (pdu != null && pdu.RequiresResponse)
                        {
                            SendPdu(new generic_nack(StatusCodes.ESME_RINVCMDID, pdu.SequenceNumber));
                        }
                        FireEvent(EventType.Error, new SmppErrorEventArgs(this, pduex, pdu));
                    }
                    catch (Exception ex)
                    {
                        socket.Close(true);
                        FireEvent(EventType.SessionDisconnected, new SmppDisconnectEventArgs(this, ex));
                    }

                    // Reset the buffer
                    re.AppendToBuffer = false;
                    re.NextReadSize   = SmppPdu.REQUIRED_SIZE;
                    return;
                }
            }

            // Wait for more data to show up on the socket.
            re.AppendToBuffer = true;
            re.NextReadSize   = packetLength - re.Length;
        }