func (caller *endpoint) Invite(callee *endpoint) error { // Starting a dialog. callid := "thisisacall" + string(caller.dialogIx) tagString := fmt.Sprintf("tag.%s.%s", caller.username, caller.host) branch := "z9hG4bK.callbranch.INVITE" caller.dialog.callId = callid caller.dialog.from_tag = base.String{tagString} caller.dialog.currentTx = txInfo{} caller.dialog.currentTx.branch = branch invite := base.NewRequest( base.INVITE, &base.SipUri{ User: &callee.username, Host: callee.host, }, "SIP/2.0", []base.SipHeader{ Via(caller, branch), To(callee, caller.dialog.to_tag), From(caller, caller.dialog.from_tag), Contact(caller), CSeq(caller.dialog.cseq, base.INVITE), CallId(callid), ContentLength(0), }, "", ) caller.dialog.cseq += 1 log.Info("Sending: %v", invite.Short()) tx := caller.tm.Send(invite, fmt.Sprintf("%v:%v", callee.host, callee.port)) caller.dialog.currentTx.tx = transaction.Transaction(tx) for { select { case r := <-tx.Responses(): log.Info("Received response: %v", r.Short()) log.Debug("Full form:\n%v\n", r.String()) // Get To tag if present. tag, ok := r.Headers("To")[0].(*base.ToHeader).Params.Get("tag") if ok { caller.dialog.to_tag = tag.(base.String) } switch { case r.StatusCode >= 300: // Call setup failed. return fmt.Errorf("callee sent negative response code %v.", r.StatusCode) case r.StatusCode >= 200: // Ack 200s manually. log.Info("Sending Ack") tx.Ack() return nil } case e := <-tx.Errors(): log.Warn(e.Error()) return e } } }
func (caller *endpoint) nonInvite(callee *endpoint, method base.Method) error { caller.dialog.currentTx.branch = "z9hG4bK.callbranch." + string(method) request := base.NewRequest( method, &base.SipUri{ User: &callee.username, Host: callee.host, }, "SIP/2.0", []base.SipHeader{ Via(caller, caller.dialog.currentTx.branch), To(callee, caller.dialog.to_tag), From(caller, caller.dialog.from_tag), Contact(caller), CSeq(caller.dialog.cseq, method), CallId(caller.dialog.callId), ContentLength(0), }, "", ) caller.dialog.cseq += 1 log.Info("Sending: %v", request.Short()) tx := caller.tm.Send(request, fmt.Sprintf("%v:%v", callee.host, callee.port)) caller.dialog.currentTx.tx = transaction.Transaction(tx) for { select { case r := <-tx.Responses(): log.Info("Received response: %v", r.Short()) log.Debug("Full form:\n%v\n", r.String()) switch { case r.StatusCode >= 300: // Failure (or redirect). return fmt.Errorf("callee sent negative response code %v.", r.StatusCode) case r.StatusCode >= 200: // Success. log.Info("Successful transaction") return nil } case e := <-tx.Errors(): log.Warn(e.Error()) return e } } }