Beispiel #1
0
func (this *SIPResponse) CreateRequest(requestURI address.SipURI, via *header.Via, cseq *header.CSeq) *SIPRequest {
	newRequest := NewSIPRequest()
	method := cseq.GetMethod()
	newRequest.SetMethod(method)
	newRequest.SetRequestURI(requestURI)
	if (method == "ACK" || method == "CANCEL") && this.GetTopmostVia().GetBranch() != "" {
		// Use the branch id from the OK.
		//try {
		via.SetBranch(this.GetTopmostVia().GetBranch())
		//} catch (ParseException ex) {}
	}
	newRequest.SetHeader(via)
	newRequest.SetHeader(cseq)

	for headerIterator := this.getHeaders().Front(); headerIterator != nil; headerIterator = headerIterator.Next() {
		nextHeader := headerIterator.Value.(header.Header)
		// Some headers do not belong in a Request ....
		if this.IsResponseHeader(nextHeader) {
			continue
		}
		if _, ok := nextHeader.(*header.ViaList); ok {
			continue
		}
		if _, ok := nextHeader.(*header.CSeq); ok {
			continue
		}
		if _, ok := nextHeader.(*header.ContentType); ok {
			continue
		}
		if _, ok := nextHeader.(*header.RecordRouteList); ok {
			continue
		}
		// if _, ok:=nextHeader.(*header.To); ok{
		//     nextHeader = nextHeader.clone();
		// }
		// else if (nextHeader instanceof From)
		//     nextHeader = (SIPHeader)nextHeader.clone();
		// try {
		newRequest.AttachHeader2(nextHeader, false)
		// } catch(SIPDuplicateHeaderException e){
		//     e.printStackTrace();
		// }
	}
	return newRequest
}
Beispiel #2
0
/**
 * Generate (compute) a transaction ID for this SIP message.
 * @return A string containing the concatenation of various
 * portions of the From,To,Via and RequestURI portions
 * of this message as specified in RFC 2543:
 * All responses to a request contain the same values in
 * the Call-ID, CSeq, To, and From fields
 * (with the possible addition of  a tag in the To field
 * (section 10.43)). This allows responses to be matched with requests.
 * Incorporates a bug fix  for a bug sent in by Gordon Ledgard of
 * IPera for generating transactionIDs when no port is present in the
 * via header.
 * Incorporates a bug fix for a bug report sent in by Chris Mills
 * of Nortel Networks (converts to lower case when returning the
 * transaction identifier).
 *
 *@return a string that can be used as a transaction identifier
 *  for this message. This can be used for matching responses and
 *  requests (i.e. an outgoing request and its matching response have
 *	the same computed transaction identifier).
 */
func (this *SIPMessage) GetTransactionId() string {
	var topVia *header.Via
	if this.GetViaHeaders().Len() > 0 {
		topVia = this.GetViaHeaders().Front().Value.(*header.Via)
	}
	// Have specified a branch Identifier so we can use it to identify
	// the transaction. BranchId is not case sensitive.
	// Branch Id prefix is not case sensitive.
	if topVia != nil && topVia.GetBranch() != "" &&
		strings.Contains(strings.ToUpper(topVia.GetBranch()),
			strings.ToUpper(header.SIPConstants_BRANCH_MAGIC_COOKIE)) {
		// Bis 09 compatible branch assignment algorithm.
		// implies that the branch id can be used as a transaction
		// identifier.
		return strings.ToLower(topVia.GetBranch())
	} else {
		// Old style client so construct the transaction identifier
		// from various fields of the request.
		var retval bytes.Buffer
		from := this.GetFrom().(*header.From)
		to := this.GetTo().(*header.To)
		hpFrom := from.GetUserAtHostPort()
		retval.WriteString(hpFrom + ":")
		if from.HasTag() {
			retval.WriteString(from.GetTag() + ":")
		}
		hpTo := to.GetUserAtHostPort()
		retval.WriteString(hpTo + ":")
		cid := this.callIdHeader.GetCallId()
		retval.WriteString(cid + ":")
		retval.WriteRune(rune(this.cSeqHeader.GetSequenceNumber()))
		retval.WriteString(":" + this.cSeqHeader.GetMethod())
		if topVia != nil {
			retval.WriteString(":" + topVia.GetSentBy().String())
			if !topVia.GetSentBy().HasPort() {
				retval.WriteString(":")
				retval.WriteRune(5060)
			}
		}
		hc := ToHexString([]byte(strings.ToLower(retval.String())))
		if len(hc) < 32 {
			return hc
		} else {
			return hc[len(hc)-32 : len(hc)]
		}
	}
	// Convert to lower case -- bug fix as a result of a bug report
	// from Chris Mills of Nortel Networks.
}
Beispiel #3
0
/**  a parser for the essential part of the via header.
 */
func (this *ViaParser) ParseVia(v *header.Via) (ParseException error) {
	lexer := this.GetLexer()

	var protocolName, protocolVersion *core.Token
	// The protocol
	lexer.Match(TokenTypes_ID)

	if protocolName = lexer.GetNextToken(); protocolName.GetTokenValue() != "SIP" {
		return this.CreateParseException("Protcoal Not Supported error")
	}

	lexer.SPorHT()
	// consume the "/"
	lexer.Match('/')
	lexer.SPorHT()
	lexer.Match(TokenTypes_ID)
	lexer.SPorHT()
	if protocolVersion = lexer.GetNextToken(); protocolVersion.GetTokenValue() != "2.0" {
		return this.CreateParseException("Version Not Supported error")
	}

	lexer.SPorHT()

	// We consume the "/"
	lexer.Match('/')
	lexer.SPorHT()
	lexer.Match(TokenTypes_ID)
	lexer.SPorHT()

	transport := lexer.GetNextToken()
	lexer.SPorHT()

	protocol := header.NewProtocol()
	protocol.SetProtocolName(protocolName.GetTokenValue())
	protocol.SetProtocolVersion(protocolVersion.GetTokenValue())
	protocol.SetTransport(transport.GetTokenValue())
	v.SetSentProtocol(protocol)

	// sent-By
	hnp := core.NewHostNameParserFromLexer(this.GetLexer())

	var hostPort *core.HostPort
	if hostPort, ParseException = hnp.GetHostPort(); ParseException != nil {
		return ParseException
	}
	v.SetSentBy(hostPort)

	// Ignore blanks
	lexer.SPorHT()

	var la byte
	for la, _ = lexer.LookAheadK(0); la == ';'; la, _ = lexer.LookAheadK(0) {
		lexer.Match(';')
		lexer.SPorHT()

		var nameValue *core.NameValue
		if nameValue, ParseException = this.NameValue(); ParseException != nil {
			return ParseException
		}

		name := nameValue.GetName()
		nameValue.SetName(strings.ToLower(name))
		v.SetParameterFromNameValue(nameValue)
		lexer.SPorHT()
	}

	if la, _ = lexer.LookAheadK(0); la == '(' {
		lexer.SelectLexer("charLexer")
		lexer.ConsumeK(1)

		var comment bytes.Buffer
		for {
			ch, _ := lexer.LookAheadK(0)
			if ch == ')' {
				lexer.ConsumeK(1)
				break
			} else if ch == '\\' {
				// Escaped character
				tok := lexer.GetNextToken()
				comment.WriteString(tok.GetTokenValue())
				lexer.ConsumeK(1)
				tok = lexer.GetNextToken()
				comment.WriteString(tok.GetTokenValue())
				lexer.ConsumeK(1)
			} else if ch == '\n' {
				break
			} else {
				comment.WriteByte(ch)
				lexer.ConsumeK(1)
			}
		}
		v.SetComment(comment.String())
	}

	return nil

}