> ------
> // then, print what the packet sink receives.
> Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/
> 0/$ns3::PacketSink/Rx",
> MakeCallback (&SinkRx));
> // finally, print the ping rtts.
> Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
> MakeCallback (&PingRtt));
> ------
>
> Why is the first one called without context, and the latter one is?
>
> Second, the callback functions...
>
> static void SinkRx (Ptr<const Packet> p, const Address &ad)
> static void PingRtt (std::string context, Time rtt)
>
> fine, I think that this gives some sort of clue that "context" is
> some sort of std::string that gets passed to the PingRtt - however,
> what are the contents?
If you print it, you will see what it looks like and it should be fairly
self-explanatory. i.e., it's roughly a fully-resolved version of the
connection path you gave to ::Connect. It will tell you exactly which
object the event is coming from.
>
> Furthermore, where can I get these parameters that are being passed?
>
> packet-sink.cc has the following:
>
> .AddTraceSource ("Rx", "A packet has been received",
> MakeTraceSourceAccessor (&PacketSink::m_rxTrace))
>
> but I'm sort of baffled how this could mean two parameters.
In packet-sink.h:
TracedCallback<Ptr<const Packet>, const Address &> m_rxTrace;
i.e., first argument is a Ptr<const Packet> and second argument is a
const Address &.
>
> Other example is examples/tcp-large-transfer.cc - has
>
> Config::ConnectWithoutContext ("/NodeList/0/$ns3::TcpL4Protocol/
> SocketList/0/CongestionWindow", MakeCallback (&CwndTracer));
>
> and the function is
>
> static void
> CwndTracer (uint32_t oldval, uint32_t newval)
> {
> NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
> }
>
> Now, how am I supposed to find out what are the parameters here? tcp-
> socket-impl.cc again only has
>
> .AddTraceSource ("CongestionWindow",
> "The TCP connection's congestion window",
> MakeTraceSourceAccessor (&TcpSocketImpl::m_cWnd))
in tcp-socket-impl.h:
TracedValue<uint32_t> m_cWnd;
and, yes, this does not tell you much, even the doxygen for
ns3::TracedValue is not obvious, but you found out the answer yourself
below.
> which doesn't exacly suggest that both the old and new value get
> passed at same time.
both the old and new values are given to trace sinks of trace sources of
type TracedValue<T> and the type of both arguments is T.
>
> http://www.nsnam.org/doxygen/group___trace_source_list.html doesn't
> help here, either.
Patches to improve the documentation are more than welcome :)
Mathieu
in traced-value.h:
T m_v;
TracedCallback<T,T> m_cb;
in the same file, Set does the actual invocation of your sink ('v' is
new value, 'm_v' is old value):
void Set (const T &v) {
if (m_v != v)
{
m_cb (m_v, v);
m_v = v;
}
}
and the connection happens in Connect:
void Connect (const CallbackBase &cb, std::string path) {
m_cb.Connect (cb, path);
}
Now, m_cb is a TracedCallback (traced-callback.h):
typedef std::list<Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> >
CallbackList;
CallbackList m_callbackList;
and Connect:
void
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Connect (const CallbackBase &
callback, std::string path)
{
Callback<void,std::string,T1,T2,T3,T4,T5,T6,T7,T8> cb;
cb.Assign (callback);
Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> realCb = cb.Bind (path);
m_callbackList.push_back (realCb);
}
>
> Can you point out where in sources does this happen? I'm struggling
> to understand all the template built on templates...
>
> I mean, first you call
> MakeTraceSourceAccessor (&TcpSocketImpl::m_cWnd))
>
> which is
>
> template <typename T>
> Ptr<const TraceSourceAccessor> MakeTraceSourceAccessor (T a)
> {
> return DoMakeTraceSourceAccessor (a);
> }
>
> so effectively nothing happens here, and I'm with you so far (in
> this case the type is TracedValue<uint32_t>). But the trail for me
> stops there, DoMakeTraceSourceAccessor doesn't really make any sense
> for me.
>
> The virtual bool ConnectWithoutContext has
> (p->*m_source).ConnectWithoutContext (cb);
>
> which I guess does the actual connection.
Here, you are calling TracedValue<T>::ConnectWithoutContext which is
calling TracedCallback<T,T>::ConnectWithoutContext which is adding
another callback in the list of callbacks to invoke when
TracedCallback<>::operator () is called.
> I thought callbacks were basically templates where you have the
> reference to function and parameters you wish to pass for it, but I
> still can't find any sign that both old and new value get passed - or
> even the single one. Anyway, I couldn't find anyplace to indicate
> where both old and new val are passed, and I tried to check
>
> traced-callback.cc
> traced-value.h and .cc
> trace-source-accessor.h and .cc
>
> Anyway, thanks..feeling like I'm falling down a rabbit hole here.
> Can't write a documentation patch since I still fail to understand the
> code. Mostly I don't want to generalize - if it always passes both new
> and old val, it's ok, but it's clear that in the csma-ping-example
TracedValue<T> always passes old and new.
> only the current value is passed.
I am afraid that this piece of code is slightly tricky...
Mathieu