/** * 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. }