diff --git a/openbsc/contrib/rtp/rtp_replay_shared.st b/openbsc/contrib/rtp/rtp_replay_shared.st index cfb66bb4d..dd32aed7a 100644 --- a/openbsc/contrib/rtp/rtp_replay_shared.st +++ b/openbsc/contrib/rtp/rtp_replay_shared.st @@ -4,19 +4,58 @@ Simple UDP replay from the state files PackageLoader fileInPackage: #Sockets. +Object subclass: SDPUtils [ + "Look into using PetitParser." + SDPUtils class >> findPort: aSDP [ + aSDP linesDo: [:line | + (line startsWith: 'm=audio ') ifTrue: [ + | stream | + stream := line readStream + skip: 'm=audio ' size; + yourself. + ^ Number readFrom: stream. + ] + ]. + + ^ self error: 'Not found'. + ] + + SDPUtils class >> findHost: aSDP [ + aSDP linesDo: [:line | + (line startsWith: 'c=IN IP4 ') ifTrue: [ + | stream | + ^ stream := line readStream + skip: 'c=IN IP4 ' size; + upToEnd. + ] + ]. + + ^ self error: 'Not found'. + ] +] + Object subclass: RTPReplay [ - | filename | + | filename socket | RTPReplay class >> on: aFile [ ^ self new + initialize; file: aFile; yourself ] + initialize [ + socket := Sockets.DatagramSocket new. + ] + file: aFile [ filename := aFile ] + localPort [ + ^ socket port + ] + streamAudio: aHost port: aPort [ - | file last_time last_image udp_send socket dest | + | file last_time last_image udp_send dest | last_time := nil. last_image := nil. @@ -24,7 +63,6 @@ Object subclass: RTPReplay [ "Send the payload" dest := Sockets.SocketAddress byName: aHost. - socket := Sockets.DatagramSocket new. udp_send := [:payload | | datagram | datagram := Sockets.Datagram data: payload contents address: dest port: aPort. socket nextPut: datagram @@ -57,7 +95,8 @@ Object subclass: RTPReplay [ "How long to wait?" wait_image := last_image + ((time - last_time) * 1000). - [ wait_image > Time millisecondClockValue ] whileTrue: []. + [ wait_image > Time millisecondClockValue ] + whileTrue: [Processor yield]. udp_send value: data. last_time := time. diff --git a/openbsc/contrib/rtp/rtp_replay_sip.st b/openbsc/contrib/rtp/rtp_replay_sip.st new file mode 100644 index 000000000..5f844df1d --- /dev/null +++ b/openbsc/contrib/rtp/rtp_replay_sip.st @@ -0,0 +1,87 @@ +""" +Create a SIP connection and then stream... +""" + +PackageLoader + fileInPackage: #OsmoSIP. + +"Load for the replay code" +FileStream fileIn: 'rtp_replay_shared.st'. + + +Osmo.SIPCall subclass: StreamCall [ + | sem stream | + + createCall: aSDP [ + | sdp | + stream := RTPReplay on: 'rtp_ssrc6976010.240.240.1_to_10.240.240.50.state'. + sdp := aSDP % {stream localPort}. + ^ super createCall: sdp. + ] + + sem: aSemaphore [ + sem := aSemaphore + ] + + sessionNew [ + | host port | + Transcript nextPutAll: 'The call has started'; nl. + Transcript nextPutAll: sdp_result; nl. + + host := SDPUtils findHost: sdp_result. + port := SDPUtils findPort: sdp_result. + + [ + stream streamAudio: host port: port. + Transcript nextPutAll: 'Streaming has finished.'; nl. + ] fork. + ] + + sessionFailed [ + sem signal + ] + + sessionEnd [ + sem signal + ] +] + +Eval [ + | transport agent call sem sdp_fr sdp_amr | + + + sdp_fr := (WriteStream on: String new) + nextPutAll: 'v=0'; cr; nl; + nextPutAll: 'o=twinkle 1739517580 1043400482 IN IP4 127.0.0.1'; cr; nl; + nextPutAll: 's=-'; cr; nl; + nextPutAll: 'c=IN IP4 127.0.0.1'; cr; nl; + nextPutAll: 't=0 0'; cr; nl; + nextPutAll: 'm=audio %1 RTP/AVP 0 101'; cr; nl; + nextPutAll: 'a=rtpmap:0 PCMU/8000'; cr; nl; + nextPutAll: 'a=rtpmap:101 telephone-event/8000'; cr; nl; + nextPutAll: 'a=fmtp:101 0-15'; cr; nl; + nextPutAll: 'a=ptime:20'; cr; nl; + contents. + + sem := Semaphore new. + transport := Osmo.SIPUdpTransport + startOn: '0.0.0.0' port: 5066. + agent := Osmo.SIPUserAgent createOn: transport. + transport start. + + call := (StreamCall + fromUser: 'sip:1000@sip.zecke.osmocom.org' + host: '127.0.0.1' + port: 5060 + to: 'sip:123456@127.0.0.1' + on: agent) + sem: sem; yourself. + + call createCall: sdp_fr. + + + "Wait for the stream to have ended" + sem wait. + + (Delay forSeconds: 4) wait. +]