@@ -34,12 +34,13 @@ func pushCallback(pn *registry.PNParams, payload map[string]string) error {
3434
3535// B2BUA .
3636type B2BUA struct {
37- stack * stack.SipStack
38- ua * ua.UserAgent
39- accounts map [string ]string
40- registry registry.Registry
41- calls []* B2BCall
42- rfc8599 * registry.RFC8599
37+ stack * stack.SipStack
38+ ua * ua.UserAgent
39+ accounts map [string ]string
40+ registry registry.Registry
41+ callBridges []* CallBridge
42+ calls map [* session.Session ]* Call
43+ rfc8599 * registry.RFC8599
4344}
4445
4546var (
@@ -62,6 +63,7 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
6263 registry : registry .Registry (registry .NewMemoryRegistry ()),
6364 accounts : make (map [string ]string ),
6465 rfc8599 : registry .NewRFC8599 (pushCallback ),
66+ calls : make (map [* session.Session ]* Call ),
6567 }
6668
6769 var authenticator * auth.ServerAuthorizer = nil
@@ -125,12 +127,21 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
125127 if from .DisplayName != nil {
126128 displayName = from .DisplayName .String ()
127129 }
128- call := & B2BCall {src : sess , ua : ua }
129130
130- call .Init ()
131+ offer := & Desc {Type : "offer" , SDP : sess .RemoteSdp ()}
132+ sdpSess , _ := offer .Parse ()
133+ transType := ParseTransportType (sdpSess )
131134
132- offer := sess .RemoteSdp ()
133- call .SetALegOffer (& Desc {Type : "offer" , SDP : offer })
135+ trackInfos , err := ParseTrackInfos (sdpSess )
136+ if err != nil {
137+ logger .Errorf ("ParseTrackInfos error: %v" , err )
138+ return
139+ }
140+
141+ src := & Call {sess : sess }
142+ src .Init (transType , trackInfos )
143+ src .OnOffer (offer )
144+ b .calls [sess ] = src
134145
135146 // Create a temporary profile. In the future, it will support reading profiles from files or data
136147 // For example: use a specific ip or sip account as outbound trunk
@@ -140,23 +151,28 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
140151 if err2 != nil {
141152 logger .Error (err2 )
142153 }
143- var tpType = TransportTypeSIP
154+ var tpType = TransportTypeStandard
144155 if instance .SupportIce () {
145- tpType = TransportTypeRTC
156+ tpType = TransportTypeWebRTC
146157 }
147- bLegOffer , _ := call .CreateBLegOffer (tpType )
148158
149- dest , err := ua .Invite (profile , called , recipient , & bLegOffer .SDP )
159+ dest := & Call {}
160+ dest .Init (tpType , trackInfos )
161+ destOffer , _ := dest .CreateOffer ()
162+
163+ dsess , err := ua .Invite (profile , called , recipient , & destOffer .SDP )
150164 if err != nil {
151165 logger .Errorf ("B-Leg session error: %v" , err )
152166 return
153167 }
154168
155- call .dest = dest
156-
157- b .calls = append (b .calls , call )
169+ dest .sess = dsess
170+ b .calls [dsess ] = dest
158171
159- call .SetState (Connecting )
172+ bridge := & CallBridge {src : src , dest : dest , bType : B2BCall }
173+ bridge .Init ()
174+ bridge .SetState (Connecting )
175+ b .callBridges = append (b .callBridges , bridge )
160176 }
161177
162178 // Try to find online contact records.
@@ -183,6 +199,7 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
183199 return
184200 }
185201
202+ logger .Warnf ("Not found any records for %v" , called )
186203 // Could not found any records
187204 sess .Reject (404 , fmt .Sprintf ("%v Not found" , called ))
188205
@@ -198,36 +215,28 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
198215
199216 // Handle 1XX
200217 case session .EarlyMedia :
201- fallthrough
218+ //bridge.SetState(EarlyMedia)
219+ //bridge.src.Provisional((*resp).StatusCode(), (*resp).Reason())
202220 case session .Provisional :
203221 call := b .findCall (sess )
204- if call != nil && call . dest == sess {
222+ if call != nil {
205223 //answer := call.dest.RemoteSdp()
206-
207- //call.SetBLegAnswer(&Desc{Type: "answer", SDP: answer})
208-
224+ //call.OnAnswer(&Desc{Type: "answer", SDP: answer})
209225 }
210-
211226 // Handle 200OK or ACK
212227 case session .Confirmed :
213228 //TODO: Add support for forked calls
214229 call := b .findCall (sess )
215- if call != nil && call . dest == sess {
216- answer := call .dest .RemoteSdp ()
217- call .SetBLegAnswer (& Desc {Type : "answer" , SDP : answer })
218- if aLegAnswer , err := call . CreateALegAnswer (); err != nil {
219- logger . Errorf ( "Create A-Leg Answer failed: %v" , err )
220- return
221- } else {
222- replaceCodec ( aLegAnswer , answer )
223- call . src . ProvideAnswer ( aLegAnswer . SDP )
230+ if call != nil && sess . Direction () == session . Outgoing {
231+ answer := call .sess .RemoteSdp ()
232+ call .OnAnswer (& Desc {Type : "answer" , SDP : answer })
233+ bridge := b . findBridgedCall ( sess )
234+ if bridge != nil && bridge . dest . sess == sess && bridge . bType == B2BCall {
235+ bridge . dest . OnAnswer ( & Desc { Type : "answer" , SDP : answer })
236+ bridge . src . Accept ( answer )
237+ BridgeMediaStream ( bridge . src . mediaTransport , bridge . dest . mediaTransport )
238+ bridge . SetState ( Confirmed )
224239 }
225-
226- //call.SetState(EarlyMedia)
227- //call.src.Provisional((*resp).StatusCode(), (*resp).Reason())
228- call .src .Accept (200 )
229- call .BridgeMediaStream ()
230- call .SetState (Confirmed )
231240 }
232241
233242 // Handle 4XX+
@@ -237,13 +246,11 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
237246 fallthrough
238247 case session .Terminated :
239248 //TODO: Add support for forked calls
249+ bridge := b .findBridgedCall (sess )
240250 call := b .findCall (sess )
241- if call != nil {
242- call .Terminate (sess )
251+ if bridge != nil && call != nil {
252+ bridge .Terminate (call )
243253 }
244-
245- b .removeCall (sess )
246-
247254 }
248255 }
249256
@@ -257,23 +264,30 @@ func NewB2BUA(disableAuth bool, enableTLS bool) *B2BUA {
257264 return b
258265}
259266
260- func (b * B2BUA ) Calls () []* B2BCall {
261- return b .calls
267+ func (b * B2BUA ) findCall (sess * session.Session ) * Call {
268+ if call , found := b .calls [sess ]; found {
269+ return call
270+ }
271+ return nil
272+ }
273+
274+ func (b * B2BUA ) BridgedCalls () []* CallBridge {
275+ return b .callBridges
262276}
263277
264- func (b * B2BUA ) findCall (sess * session.Session ) * B2BCall {
265- for _ , call := range b .calls {
266- if call .src == sess || call .dest == sess {
278+ func (b * B2BUA ) findBridgedCall (sess * session.Session ) * CallBridge {
279+ for _ , call := range b .callBridges {
280+ if call .src . sess == sess || call .dest . sess == sess {
267281 return call
268282 }
269283 }
270284 return nil
271285}
272286
273- func (b * B2BUA ) removeCall (sess * session.Session ) {
274- for idx , call := range b .calls {
275- if call .src == sess || call .dest == sess {
276- b .calls = append (b .calls [:idx ], b .calls [idx + 1 :]... )
287+ func (b * B2BUA ) removeCallBridge (sess * session.Session ) {
288+ for idx , call := range b .callBridges {
289+ if call .src . sess == sess || call .dest . sess == sess {
290+ b .callBridges = append (b .callBridges [:idx ], b .callBridges [idx + 1 :]... )
277291 return
278292 }
279293 }
@@ -282,6 +296,59 @@ func (b *B2BUA) removeCall(sess *session.Session) {
282296// Originate .
283297func (b * B2BUA ) Originate (source string , destination string ) {
284298 logger .Infof ("Originate %s => %s" , source , destination )
299+ /*
300+ doInvite := func(recipient sip.SipUri, tpType TransportType) {
301+ displayName := ""
302+ caller, _ := parser.ParseUri("sip:" + source)
303+ call := &CallBridge{}
304+
305+ call.Init()
306+
307+ offer := sess.RemoteSdp()
308+ call.SetALegOffer(&Desc{Type: "offer", SDP: offer})
309+
310+ // Create a temporary profile. In the future, it will support reading profiles from files or data
311+ // For example: use a specific ip or sip account as outbound trunk
312+ profile := account.NewProfile(caller, displayName, nil, 0, b.stack)
313+
314+ bLegOffer, _ := call.CreateBLegOffer(tpType)
315+
316+ dest, err := b.ua.Invite(profile, caller, recipient, &bLegOffer.SDP)
317+ if err != nil {
318+ logger.Errorf("Can't send invite, error: %v", err)
319+ return
320+ }
321+
322+ call.dest = dest
323+ }
324+
325+ srcUri, err := parser.ParseUri("sip:" + source)
326+ if err != nil {
327+ logger.Error(err)
328+ return
329+ }
330+
331+ destUri, err := parser.ParseSipUri("sip:" + destination)
332+ if err != nil {
333+ logger.Error(err)
334+ return
335+ }
336+
337+ // Try to find online contact records.
338+ if contacts, found := b.registry.GetContacts(srcUri); found {
339+ for _, instance := range *contacts {
340+ var tpType = TransportTypeSIP
341+ if instance.SupportIce() {
342+ tpType = TransportTypeRTC
343+ }
344+ recipient, err2 := parser.ParseSipUri("sip:" + instance.Contact.Address.User().String() + "@" + instance.Source + ";transport=" + instance.Transport)
345+ if err2 != nil {
346+ logger.Error(err2)
347+ }
348+ doInvite(recipient, tpType)
349+ }
350+ return
351+ }*/
285352}
286353
287354// Shutdown .
0 commit comments