示例#1
0
        /// <summary>
        /// Parses a SIP response from a SIP message object.
        /// </summary>
        /// <param name="sipMessageBuffer">The SIP message to parse a response from.</param>
        /// <returns>A new SIP response object.</returns>
        public static SIPResponse ParseSIPResponse(SIPMessageBuffer sipMessageBuffer)
        {
            try
            {
                SIPResponse sipResponse = new SIPResponse();
                sipResponse.LocalSIPEndPoint  = sipMessageBuffer.LocalSIPEndPoint;
                sipResponse.RemoteSIPEndPoint = sipMessageBuffer.RemoteSIPEndPoint;
                string statusLine = sipMessageBuffer.FirstLine;

                int firstSpacePosn = statusLine.IndexOf(" ");

                sipResponse.SIPVersion   = statusLine.Substring(0, firstSpacePosn).Trim();
                statusLine               = statusLine.Substring(firstSpacePosn).Trim();
                sipResponse.StatusCode   = Convert.ToInt32(statusLine.Substring(0, 3));
                sipResponse.Status       = SIPResponseStatusCodes.GetStatusTypeForCode(sipResponse.StatusCode);
                sipResponse.ReasonPhrase = statusLine.Substring(3).Trim();

                sipResponse.Header = SIPHeader.ParseSIPHeaders(sipMessageBuffer.SIPHeaders);
                sipResponse.Body   = sipMessageBuffer.Body;

                return(sipResponse);
            }
            catch (SIPValidationException)
            {
                throw;
            }
            catch (Exception excp)
            {
                logger.LogError("Exception ParseSIPResponse. " + excp.Message);
                logger.LogError(sipMessageBuffer.RawMessage);
                throw new SIPValidationException(SIPValidationFieldsEnum.Response, "Error parsing SIP Response");
            }
        }
示例#2
0
        /// <summary>
        /// Attempts to extract SIP messages from the data that has been received on the SIP stream connection.
        /// </summary>
        /// <param name="recvChannel">The receiving SIP channel.</param>
        /// <param name="buffer">The buffer holding the current data from the stream. Note that the buffer can
        /// stretch over multiple receives.</param>
        /// <param name="bytesRead">The bytes that were read by the latest receive operation (the new bytes available).</param>
        public void ExtractSIPMessages(SIPChannel recvChannel, byte[] buffer, int bytesRead)
        {
            RecvEndPosn += bytesRead;

            int bytesSkipped = 0;

            byte[] sipMsgBuffer = SIPMessageBuffer.ParseSIPMessageFromStream(buffer, RecvStartPosn, RecvEndPosn, out bytesSkipped);

            while (sipMsgBuffer != null)
            {
                // A SIP message is available.
                if (SIPMessageReceived != null)
                {
                    LastTransmission = DateTime.Now;
                    SIPEndPoint localEndPoint  = new SIPEndPoint(ConnectionProtocol, StreamSocket.LocalEndPoint as IPEndPoint, recvChannel.ID, ConnectionID);
                    SIPEndPoint remoteEndPoint = new SIPEndPoint(ConnectionProtocol, RemoteEndPoint, recvChannel.ID, ConnectionID);
                    SIPMessageReceived(recvChannel, localEndPoint, remoteEndPoint, sipMsgBuffer);
                }

                RecvStartPosn += (sipMsgBuffer.Length + bytesSkipped);

                if (RecvStartPosn == RecvEndPosn)
                {
                    // All data has been successfully extracted from the receive buffer.
                    RecvStartPosn = RecvEndPosn = 0;
                    break;
                }
                else
                {
                    // Try and extract another SIP message from the receive buffer.
                    sipMsgBuffer = SIPMessageBuffer.ParseSIPMessageFromStream(buffer, RecvStartPosn, RecvEndPosn, out bytesSkipped);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Attempts to parse a SIP message from a single buffer that can only contain a single message.
        /// </summary>
        /// <param name="buffer">The buffer that will be parsed for a SIP message.</param>
        /// <param name="localSIPEndPoint">The end point the message was received on.</param>
        /// <param name="remoteSIPEndPoint">The end point the message was received from.</param>
        /// <returns>If successful a SIP message or null if not.</returns>
        public static SIPMessageBuffer ParseSIPMessage(byte[] buffer, SIPEndPoint localSIPEndPoint,
                                                       SIPEndPoint remoteSIPEndPoint)
        {
            string message = null;

            try
            {
                if (buffer == null || buffer.Length < m_minFirstLineLength)
                {
                    // Ignore.
                    return(null);
                }
                else if (buffer.Length > SIPConstants.SIP_MAXIMUM_RECEIVE_LENGTH)
                {
                    throw new ApplicationException(
                              "SIP message received that exceeded the maximum allowed message length, ignoring.");
                }
                else if (!BufferUtils.HasString(buffer, 0, buffer.Length, SIP_MESSAGE_IDENTIFIER, m_CRLF))
                {
                    // Message does not contain "SIP" anywhere on the first line, ignore.
                    return(null);
                }
                else
                {
                    message = ByteToStr(buffer, Encoding.UTF8);
                    if (message.ToUpper().Contains("ENCODING=\"GBK\"") ||
                        message.ToUpper().Contains("ENCODING=\"GB2312\""))
                    {
                        message = ByteToStr(buffer, Encoding.GetEncoding("GBK")); //兼容gbk,gb2312编码中文字符串
                    }

                    SIPMessageBuffer sipMessageBuffer = ParseSIPMessage(message, localSIPEndPoint, remoteSIPEndPoint);

                    if (sipMessageBuffer != null)
                    {
                        sipMessageBuffer.RawBuffer = buffer;
                        return(sipMessageBuffer);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            catch (Exception excp)
            {
                message = message.Replace("\n", "LF");
                message = message.Replace("\r", "CR");
                logger.LogError("Exception ParseSIPMessage. " + excp.Message + "\nSIP Message=" + message + ".");
                return(null);
            }
        }
示例#4
0
        public static SIPRequest ParseSIPRequest(SIPMessageBuffer sipMessage)
        {
            try
            {
                SIPRequest sipRequest = new SIPRequest();
                sipRequest.LocalSIPEndPoint  = sipMessage.LocalSIPEndPoint;
                sipRequest.RemoteSIPEndPoint = sipMessage.RemoteSIPEndPoint;

                string statusLine = sipMessage.FirstLine;

                int firstSpacePosn = statusLine.IndexOf(" ");

                string method = statusLine.Substring(0, firstSpacePosn).Trim();
                sipRequest.Method = SIPMethods.GetMethod(method);
                if (sipRequest.Method == SIPMethodsEnum.UNKNOWN)
                {
                    sipRequest.UnknownMethod = method;
                    logger.LogWarning("Unknown SIP method received " + sipRequest.UnknownMethod + ".");
                }

                statusLine = statusLine.Substring(firstSpacePosn).Trim();
                int secondSpacePosn = statusLine.IndexOf(" ");

                if (secondSpacePosn != -1)
                {
                    string uriStr = statusLine.Substring(0, secondSpacePosn);

                    sipRequest.URI        = SIPURI.ParseSIPURI(uriStr);
                    sipRequest.SIPVersion = statusLine.Substring(secondSpacePosn, statusLine.Length - secondSpacePosn)
                                            .Trim();
                    sipRequest.Header = SIPHeader.ParseSIPHeaders(sipMessage.SIPHeaders);
                    sipRequest.Body   = sipMessage.Body;

                    return(sipRequest);
                }
                else
                {
                    throw new SIPValidationException(SIPValidationFieldsEnum.Request, "URI was missing on Request.");
                }
            }
            catch (SIPValidationException)
            {
                throw;
            }
            catch (Exception excp)
            {
                logger.LogError("Exception parsing SIP Request. " + excp.Message);
                logger.LogError(sipMessage.RawMessage);
                throw new SIPValidationException(SIPValidationFieldsEnum.Request, "Unknown error parsing SIP Request");
            }
        }
示例#5
0
        public SIPEndPoint LocalSIPEndPoint;  // The local SIP socket the message was received on or sent from.

        /// <summary>
        /// Attempts to parse a SIP message from a single buffer that can only contain a single message.
        /// </summary>
        /// <param name="buffer">The buffer that will be parsed for a SIP message.</param>
        /// <param name="localSIPEndPoint">The end point the message was received on.</param>
        /// <param name="remoteSIPEndPoint">The end point the message was received from.</param>
        /// <returns>If successful a SIP message or null if not.</returns>
        public static SIPMessageBuffer ParseSIPMessage(byte[] buffer, SIPEndPoint localSIPEndPoint,
                                                       SIPEndPoint remoteSIPEndPoint)
        {
            string message = null;

            try
            {
                if (buffer == null || buffer.Length < m_minFirstLineLength)
                {
                    // Ignore.
                    return(null);
                }
                else if (buffer.Length > SIPConstants.SIP_MAXIMUM_RECEIVE_LENGTH)
                {
                    throw new ApplicationException(
                              "SIP message received that exceeded the maximum allowed message length, ignoring.");
                }
                else if (!ByteBufferInfo.HasString(buffer, 0, buffer.Length, SIP_MESSAGE_IDENTIFIER, m_CRLF))
                {
                    // Message does not contain "SIP" anywhere on the first line, ignore.
                    return(null);
                }
                else
                {
                    message = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                    SIPMessageBuffer sipMessageBuffer = ParseSIPMessage(message, localSIPEndPoint, remoteSIPEndPoint);

                    if (sipMessageBuffer != null)
                    {
                        sipMessageBuffer.RawBuffer = buffer;
                        return(sipMessageBuffer);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            catch (Exception excp)
            {
                message = message.Replace("\n", "LF");
                message = message.Replace("\r", "CR");
                Logger.Logger.Error("Exception ParseSIPMessage. ->" + excp.Message + "->SIP Message=" + message + ".");
                return(null);
            }
        }
示例#6
0
 public static SIPRequest ParseSIPRequest(string sipMessageStr)
 {
     try
     {
         SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(sipMessageStr, null, null);
         return(ParseSIPRequest(sipMessageBuffer));
     }
     catch (SIPValidationException)
     {
         throw;
     }
     catch (Exception excp)
     {
         Logger.Logger.Error("Exception ParseSIPRequest. ->" + sipMessageStr + "->" + excp.Message);
         throw new SIPValidationException(SIPValidationFieldsEnum.Request, "Unknown error parsing SIP Request");
     }
 }
示例#7
0
 /// <summary>
 /// Parses a SIP response from a string.
 /// </summary>
 /// <param name="sipMessageStr">The string to parse the SIP response from.</param>
 /// <returns>A new SIP response object.</returns>
 public static SIPResponse ParseSIPResponse(string sipMessageStr)
 {
     try
     {
         SIPMessageBuffer sipMessage = SIPMessageBuffer.ParseSIPMessage(sipMessageStr, null, null);
         return(SIPResponse.ParseSIPResponse(sipMessage));
     }
     catch (SIPValidationException)
     {
         throw;
     }
     catch (Exception excp)
     {
         logger.LogError("Exception ParseSIPResponse. " + excp.Message);
         logger.LogError(sipMessageStr);
         throw new SIPValidationException(SIPValidationFieldsEnum.Response, "Error parsing SIP Response");
     }
 }
示例#8
0
 public static SIPRequest ParseSIPRequest(string sipMessageStr, Encoding sipEncoding, Encoding sipBodyEncoding)
 {
     try
     {
         SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(sipMessageStr, sipEncoding, sipBodyEncoding, null, null);
         return(ParseSIPRequest(sipMessageBuffer, sipEncoding, sipBodyEncoding));
     }
     catch (SIPValidationException)
     {
         throw;
     }
     catch (Exception excp)
     {
         logger.LogError("Exception ParseSIPRequest. " + excp.Message);
         logger.LogError(sipMessageStr);
         throw new SIPValidationException(SIPValidationFieldsEnum.Request, "Unknown error parsing SIP Request");
     }
 }
        /// <summary>
        /// Attempts to extract SIP messages from the data that has been received on the client web socket SIP stream connection.
        /// </summary>
        /// <param name="recvChannel">The receiving SIP channel.</param>
        /// <param name="clientConn">The web socket client connection properties including pending receive buffer</param>
        /// <param name="buffer">The buffer holding the current data from the stream. Note that the buffer can
        /// stretch over multiple receives.</param>
        /// <param name="bytesRead">The bytes that were read by the latest receive operation (the new bytes available).</param>
        private void ExtractSIPMessages(SIPChannel recvChannel, ClientWebSocketConnection clientConn,
                                        ArraySegment <byte> buffer, int bytesRead)
        {
            if (bytesRead + clientConn.RecvEndPosn > clientConn.PendingReceiveBuffer.Length)
            {
                // Don't have enough space for the read. Throw away the pending buffer and hope the SIP transaction is re-attempted.
                clientConn.RecvStartPosn = clientConn.RecvEndPosn = 0;
            }

            Buffer.BlockCopy(buffer.ToArray(), 0, clientConn.PendingReceiveBuffer, clientConn.RecvEndPosn, bytesRead);
            clientConn.RecvEndPosn += bytesRead;

            int bytesSkipped = 0;

            byte[] sipMsgBuffer = SIPMessageBuffer.ParseSIPMessageFromStream(clientConn.PendingReceiveBuffer,
                                                                             clientConn.RecvStartPosn, clientConn.RecvEndPosn, out bytesSkipped);

            while (sipMsgBuffer != null)
            {
                // A SIP message is available.
                if (SIPMessageReceived != null)
                {
                    clientConn.LastTransmission = DateTime.Now;
                    SIPMessageReceived(recvChannel, clientConn.LocalEndPoint, clientConn.RemoteEndPoint, sipMsgBuffer)
                    .Wait();
                }

                clientConn.RecvStartPosn += (sipMsgBuffer.Length + bytesSkipped);

                if (clientConn.RecvStartPosn == clientConn.RecvEndPosn)
                {
                    // All data has been successfully extracted from the receive buffer.
                    clientConn.RecvStartPosn = clientConn.RecvEndPosn = 0;
                    break;
                }
                else
                {
                    // Try and extract another SIP message from the receive buffer.
                    sipMsgBuffer = SIPMessageBuffer.ParseSIPMessageFromStream(clientConn.PendingReceiveBuffer,
                                                                              clientConn.RecvStartPosn, clientConn.RecvEndPosn, out bytesSkipped);
                }
            }
        }
示例#10
0
        /// <summary>
        /// Attempts to parse a SIP message from a string containing a single SIP request or response.
        /// </summary>
        /// <param name="message">The string to parse.</param>
        /// <param name="localSIPEndPoint">The end point the message was received on.</param>
        /// <param name="remoteSIPEndPoint">The end point the message was received from.</param>
        /// <returns>If successful a SIP message or null if not.</returns>
        public static SIPMessageBuffer ParseSIPMessage(string message, SIPEndPoint localSIPEndPoint,
                                                       SIPEndPoint remoteSIPEndPoint)
        {
            try
            {
                SIPMessageBuffer sipMessage = new SIPMessageBuffer();
                sipMessage.LocalSIPEndPoint  = localSIPEndPoint;
                sipMessage.RemoteSIPEndPoint = remoteSIPEndPoint;

                // For connection oriented transports the same connection should be used for responses and subsequent requests.
                if (sipMessage.LocalSIPEndPoint != null && remoteSIPEndPoint.ConnectionID != null)
                {
                    sipMessage.LocalSIPEndPoint.ConnectionID = remoteSIPEndPoint.ConnectionID;
                }

                sipMessage.RawMessage = message;
                int endFistLinePosn = message.IndexOf(m_CRLF);

                if (endFistLinePosn != -1)
                {
                    sipMessage.FirstLine = message.Substring(0, endFistLinePosn);

                    if (sipMessage.FirstLine.Substring(0, 3) == SIP_RESPONSE_PREFIX)
                    {
                        sipMessage.SIPMessageType = SIPMessageTypesEnum.Response;
                    }
                    else
                    {
                        sipMessage.SIPMessageType = SIPMessageTypesEnum.Request;
                    }

                    int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF);
                    if (endHeaderPosn == -1)
                    {
                        // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body.
                        string headerString =
                            message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2);
                        sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString);
                    }
                    else
                    {
                        string headerString =
                            message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2);
                        sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString);

                        if (message.Length > endHeaderPosn + 4)
                        {
                            sipMessage.Body = message.Substring(endHeaderPosn + 4);
                        }
                    }

                    return(sipMessage);
                }
                else
                {
                    Logger.Logger.Warn(
                        "Error ParseSIPMessage, there were no end of line characters in the string being parsed.");
                    return(null);
                }
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception ParseSIPMessage. ->" + excp.Message + "->SIP Message=" + message + ".");
                return(null);
            }
        }
示例#11
0
 public static SIPRequest ParseSIPRequest(SIPMessageBuffer sipMessage) =>
 ParseSIPRequest(sipMessage, SIPConstants.DEFAULT_ENCODING, SIPConstants.DEFAULT_ENCODING);
示例#12
0
        /// <summary>
        /// Attempts to parse a SIP message from a single buffer that can only contain a single message.
        /// </summary>
        /// <param name="buffer">The buffer that will be parsed for a SIP message.</param>
        /// <param name="sipBodyEncoding">SIP payload encoding</param>
        /// <param name="localSIPEndPoint">The end point the message was received on.</param>
        /// <param name="remoteSIPEndPoint">The end point the message was received from.</param>
        /// <param name="sipEncoding">SIP protocol encoding, according to RFC should be UTF-8 </param>
        /// <returns>If successful a SIP message or null if not.</returns>
        public static SIPMessageBuffer ParseSIPMessage(
            byte[] buffer,
            Encoding sipEncoding,
            Encoding sipBodyEncoding,
            SIPEndPoint localSIPEndPoint,
            SIPEndPoint remoteSIPEndPoint)
        {
            if (buffer == null || buffer.Length < m_minFirstLineLength)
            {
                // Ignore.
                return(null);
            }
            else if (buffer.Length > SIPConstants.SIP_MAXIMUM_RECEIVE_LENGTH)
            {
                throw new ApplicationException("SIP message received that exceeded the maximum allowed message length, ignoring.");
            }
            else if (!BufferUtils.HasString(buffer, 0, buffer.Length, SIP_MESSAGE_IDENTIFIER, m_CRLF))
            {
                // Message does not contain "SIP" anywhere on the first line, ignore.
                return(null);
            }
            else
            {
                var sipMessage = new SIPMessageBuffer(sipEncoding, sipBodyEncoding);

                sipMessage.RawBuffer         = buffer;
                sipMessage.LocalSIPEndPoint  = localSIPEndPoint;
                sipMessage.RemoteSIPEndPoint = remoteSIPEndPoint;

                // For connection oriented transports the same connection should be used for responses and subsequent requests.
                if (sipMessage.LocalSIPEndPoint != null && remoteSIPEndPoint.ConnectionID != null)
                {
                    sipMessage.LocalSIPEndPoint.ConnectionID = remoteSIPEndPoint.ConnectionID;
                }

                string message         = sipEncoding.GetString(buffer);
                int    endFistLinePosn = message.IndexOf(m_CRLF);

                if (endFistLinePosn != -1)
                {
                    sipMessage.FirstLine = message.Substring(0, endFistLinePosn);

                    if (sipMessage.FirstLine.Substring(0, 3) == SIP_RESPONSE_PREFIX)
                    {
                        sipMessage.SIPMessageType = SIPMessageTypesEnum.Response;
                    }
                    else
                    {
                        sipMessage.SIPMessageType = SIPMessageTypesEnum.Request;
                    }

                    int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF);
                    if (endHeaderPosn == -1)
                    {
                        // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body.
                        string headerString = message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2);
                        sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString);
                    }
                    else
                    {
                        string headerString = message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2);
                        sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString);

                        if (message.Length > endHeaderPosn + 4)
                        {
                            sipMessage.Body = new byte[buffer.Length - (endHeaderPosn + 4)];
                            Buffer.BlockCopy(buffer, endHeaderPosn + 4, sipMessage.Body, 0, buffer.Length - (endHeaderPosn + 4));
                        }
                    }

                    return(sipMessage);
                }
                else
                {
                    logger.LogWarning("Error ParseSIPMessage, there were no end of line characters in the string being parsed.");
                    return(null);
                }
            }
        }
示例#13
0
 public static SIPResponse ParseSIPResponse(SIPMessageBuffer sipMessageBuffer) =>
 ParseSIPResponse(sipMessageBuffer, sipMessageBuffer.SIPEncoding, sipMessageBuffer.SIPBodyEncoding);