From 057ad9738a30bd261f6ea03dbaba9a3ce9c77744 Mon Sep 17 00:00:00 2001 From: demotomohiro Date: Sun, 6 Dec 2020 09:56:35 +0900 Subject: [PATCH 1/3] Add simple test code for libnice --- examples/gtk3/libnice_simple_test.nim | 122 ++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 examples/gtk3/libnice_simple_test.nim diff --git a/examples/gtk3/libnice_simple_test.nim b/examples/gtk3/libnice_simple_test.nim new file mode 100644 index 0000000..f177026 --- /dev/null +++ b/examples/gtk3/libnice_simple_test.nim @@ -0,0 +1,122 @@ +# nim c libnice_simple_test.nim +# +# Test code for libnice. +# If test succeeded, it prints "Test success". +# You don't need to run 2 processes of this program to test. + +when (compiles do: import gintro/gtk): + import gintro/[gtk, glib, gobject, gio, nice] +else: + import gintro/[dummygtk, glib, gobject, gio, nice] # For system has glib but no gtk + +import strformat + +const + ltestMessage = "some test message" + rtestMessage = "random text for test" + +var + gloop: glib.MainLoop + lagent, ragent: nice.Agent + lstreamId, rstreamId: int + gatheringCount, recvCount: int + +proc toIntVal(i: int): Value = + let gtype = typeFromName("gint") + discard init(result, gtype) + setInt(result, i) + +proc cbCandidateGatheringDone(agent: nice.Agent; streamId: int) = + proc copyCandidates(src, dst: nice.Agent; srcStreamId, dstStreamId: int) = + var + ufrag: string + password: string + + doAssert src.getLocalCredentials(srcStreamId, ufrag, password) + doAssert dst.setRemoteCredentials(dstStreamId, ufrag, password) + var cands: seq[Candidate] = src.getLocalCandidates(srcStreamId, 1) + for c in cands.mitems: + c.setStreamID(dstStreamId.uint32) + c.setComponentID(1) + doAssert cands.len != 0 + doAssert dst.setRemoteCandidates(dstStreamId, 1, cands) > 0 + + doAssert agent == lagent or agent == ragent + doAssert gatheringCount in (0..1) + + if gatheringCount == 1: + copyCandidates(lagent, ragent, lstreamId, rstreamId) + copyCandidates(ragent, lagent, rstreamId, lstreamId) + + inc gatheringCount + +proc cbComponentStateChanged(agent: nice.Agent; streamId: int; componentId: int; state: int) = + doAssert agent == lagent or agent == ragent + + let stat = ComponentState(state) + echo &"SIGNAL: state changed {streamId}, {componentId}, {stat}" + + case stat + of ComponentState.ready: + if agent == lagent: + doAssert agent.send(streamId, componentId, ltestMessage.len, ltestMessage.cstring) == ltestMessage.len + else: + doAssert agent.send(streamId, componentId, rtestMessage.len, rtestMessage.cstring) == rtestMessage.len + of ComponentState.failed: + gloop.quit + else: + discard + +proc cbNiceRecv(agent: nice.Agent; streamID: cuint; componentID: cuint; len: cuint; buf: cstring) = + doAssert agent.impl == lagent.impl or agent.impl == ragent.impl + if agent.impl == lagent.impl: + doAssert len == rtestMessage.len + doAssert equalMem(buf, rtestMessage.cstring, len) + echo "lagent received test message" + else: + doAssert len == ltestMessage.len + doAssert equalMem(buf, ltestMessage.cstring, len) + echo "ragent received test message" + + doAssert recvCount in (0..1) + if recvCount == 1: + gloop.quit + inc recvCount + +proc main = + gio.networkingInit() + + + gloop = newMainLoop(nil, false) + + lagent = nice.newAgent(glib.getContext(gloop), nice.CompatibilityRfc5245) + ragent = nice.newAgent(glib.getContext(gloop), nice.CompatibilityRfc5245) + + doAssert lagent != nil and ragent != nil + + lagent.setProperty("controlling-mode", toIntVal(0)) + ragent.setProperty("controlling-mode", toIntVal(1)) + + lagent.connect("candidate-gathering-done", cbCandidateGatheringDone) + ragent.connect("candidate-gathering-done", cbCandidateGatheringDone) + lagent.connect("component-state-changed", cbComponentStateChanged) + ragent.connect("component-state-changed", cbComponentStateChanged) + + lstreamId = lagent.addStream(1) + rstreamId = ragent.addStream(1) + doAssert lstreamId != 0 and rstreamId != 0 + + lagent.attachRecv(lstreamId.cuint, 1, getContext(gloop), cbNiceRecv) + ragent.attachRecv(rstreamId.cuint, 1, getContext(gloop), cbNiceRecv) + + doAssert gatherCandidates(lagent, lstreamId) + doAssert gatherCandidates(ragent, rstreamId) + + gloop.run + + doAssert gatheringCount == 2 + doAssert recvCount == 2 + + echo "Test success" + +main() From 24b5adab30beffec8ccf302d9707d89befff8dcd Mon Sep 17 00:00:00 2001 From: demotomohiro Date: Sun, 6 Dec 2020 20:18:32 +0900 Subject: [PATCH 2/3] libnice_simple_test.nim prints selected pair --- examples/gtk3/libnice_simple_test.nim | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/gtk3/libnice_simple_test.nim b/examples/gtk3/libnice_simple_test.nim index f177026..a4ffb71 100644 --- a/examples/gtk3/libnice_simple_test.nim +++ b/examples/gtk3/libnice_simple_test.nim @@ -9,7 +9,7 @@ when (compiles do: import gintro/gtk): else: import gintro/[dummygtk, glib, gobject, gio, nice] # For system has glib but no gtk -import strformat +import strformat, nativesockets const ltestMessage = "some test message" @@ -26,6 +26,9 @@ proc toIntVal(i: int): Value = discard init(result, gtype) setInt(result, i) +proc addrString(niceAddr: Address): string = + getAddrString(unsafeAddr niceAddr.`addr`) + proc cbCandidateGatheringDone(agent: nice.Agent; streamId: int) = proc copyCandidates(src, dst: nice.Agent; srcStreamId, dstStreamId: int) = var @@ -50,6 +53,9 @@ proc cbCandidateGatheringDone(agent: nice.Agent; streamId: int) = inc gatheringCount +proc cbNewSelectedPairFull(self: Agent; streamId: int; componentId: int; lcandidate: Candidate; rcandidate: Candidate) = + echo &"SIGNAL: selected pair ({lcandidate.impl.`addr`.addrString}:{lcandidate.impl.`addr`.port} {rcandidate.impl.`addr`.addrString}:{rcandidate.impl.`addr`.port})" + proc cbComponentStateChanged(agent: nice.Agent; streamId: int; componentId: int; state: int) = doAssert agent == lagent or agent == ragent @@ -57,6 +63,13 @@ proc cbComponentStateChanged(agent: nice.Agent; streamId: int; componentId: int; echo &"SIGNAL: state changed {streamId}, {componentId}, {stat}" case stat + of ComponentState.connected: + var + local = Candidate(ignoreFinalizer: true) + remote = Candidate(ignoreFinalizer: true) + ## Get current selected candidate pair and print IP address used + if getSelectedPair(agent, streamId, componentId, local, remote): + echo &"Negotiation complete: ({local.impl.`addr`.addrString}:{local.impl.`addr`.port} {remote.impl.`addr`.addrString}:{remote.impl.`addr`.port})" of ComponentState.ready: if agent == lagent: doAssert agent.send(streamId, componentId, ltestMessage.len, ltestMessage.cstring) == ltestMessage.len @@ -99,6 +112,8 @@ proc main = lagent.connect("candidate-gathering-done", cbCandidateGatheringDone) ragent.connect("candidate-gathering-done", cbCandidateGatheringDone) + lagent.connect("new-selected-pair-full", cbNewSelectedPairFull) + ragent.connect("new-selected-pair-full", cbNewSelectedPairFull) lagent.connect("component-state-changed", cbComponentStateChanged) ragent.connect("component-state-changed", cbComponentStateChanged) From 9e21b6543eba2dc42fe818bb97b1562f8ccaaf29 Mon Sep 17 00:00:00 2001 From: demotomohiro Date: Sun, 6 Dec 2020 20:27:34 +0900 Subject: [PATCH 3/3] Remove empty line --- examples/gtk3/libnice_simple_test.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/gtk3/libnice_simple_test.nim b/examples/gtk3/libnice_simple_test.nim index a4ffb71..3bd1652 100644 --- a/examples/gtk3/libnice_simple_test.nim +++ b/examples/gtk3/libnice_simple_test.nim @@ -98,8 +98,7 @@ proc cbNiceRecv(agent: nice.Agent; streamID: cuint; componentID: cuint; len: cui proc main = gio.networkingInit() - - + gloop = newMainLoop(nil, false) lagent = nice.newAgent(glib.getContext(gloop), nice.CompatibilityRfc5245)