X-Git-Url: https://git.rohieb.name/skm-ma-ws1314.git/blobdiff_plain/d188e97fccbdedb3fa7e2f4801ad2df14be4bdfd..48f414cd2758feacf54935385c7c2813463d7b6f:/presentation.tex?ds=sidebyside

diff --git a/presentation.tex b/presentation.tex
new file mode 100644
index 0000000..4318d88
--- /dev/null
+++ b/presentation.tex
@@ -0,0 +1,545 @@
+\documentclass{beamer}
+\usepackage[utf8]{inputenc}
+\usepackage[english]{babel}
+\usepackage{todonotes}
+\usepackage{inconsolata}
+%\usepackage{multicol}
+\usepackage{array}
+\usepackage{tikz}
+\usetikzlibrary{arrows}
+\usetikzlibrary{arrows}
+\usetikzlibrary{positioning}
+\usetikzlibrary{shapes.symbols}
+%\usepackage[usenames,dvipsnames]{color}
+
+%\presetkeys{todonotes}{inline}{}
+\newcommand{\code}[1]{\texttt{#1}}
+\definecolor{green}{RGB}{137,164,0}  % from tubslatex
+
+\title{Chatty Things}
+\subtitle{Making the Internet of Things Readily Usable for the Masses with XMPP}
+\author{Roland Hieber}
+\institute[IBR, TU-BS]{Institute of Operating Systems and Computer Networks}
+\date[SKM-13/14]{Seminar Communications and Multimedia, WS 2013/14}
+
+\begin{document}
+
+\begin{frame}[plain]
+\maketitle
+\end{frame}
+
+\begin{frame}{Contents}
+\tableofcontents
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Motivation}
+\begin{frame}{Motivation}
+\begin{block}{The IoT Vision}
+	\begin{itemize}
+		\item plentitude of smart objects
+		\item interoperability between devices
+		\item easy accessibility for users
+	\end{itemize}
+\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}<1>[label=subgoals]{Motivation: Subgoals}
+	\begin{block}{But how do we\ldots}
+		\begin{itemize}
+			\item configure our devices?
+				\begin{itemize}
+					\invisible<1-1>{\item[\color{green}\checkmark]\color{green}
+						Link-Local Addressing, Stateless Address Autoconfiguration}
+				\end{itemize}
+			\item find other nodes to talk to?
+				\begin{itemize}
+					\invisible<1-2>{\item[\color{green}\checkmark]\color{green}
+						DNS-SD + mDNS}
+				\end{itemize}
+			\item talk to other nodes or users?
+				\begin{itemize}
+					\invisible<1-3>{\item[\color{green}\checkmark]\color{green} XMPP
+						Serverless Messaging}
+				\end{itemize}
+			\item filter relevant information?
+				\begin{itemize}
+					\invisible<1-4>{\item[\color{green}\checkmark]\color{green} ``Traffic
+						Lights'', Temporary Subscription for Presence}
+				\end{itemize}
+		\end{itemize}
+	\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Technologies for Distributed Networking}
+\begin{frame}{Address Allocation}
+IPv4 Link-Local Addessing (``APIPA'', ``Zeroconf'', RFC 3927)
+\begin{itemize}
+	\item subnet \code{169.254.0.0/16}
+\end{itemize}
+IPv6 Stateless Address Autoconfiguration (RFC 4862)
+\begin{itemize}
+	\item subnet \code{fe80::/64} (link-local)
+	\item subnet \code{fc00::/11} (unique-local, if configured)
+	\item or global address (if configured)
+\end{itemize}
+
+\begin{block}{Algorithm}
+\begin{enumerate}
+	\item choose (random) IP address in subnet
+	\item ask if anyone uses that address
+	\item if not, we're fine
+	\item else, retry
+\end{enumerate}
+\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\againframe<2>{subgoals}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{Multicast DNS (RFC 6762)}
+\begin{itemize}
+\item distributed DNS database
+\item uses multicast address \code{224.0.0.251} (IPv4) and \code{ff02::fb}
+	(IPv6), UDP port 5353
+\item standard DNS packet format
+\item hosts announce their own resources
+\item hosts respond to queries if queried resource is known
+\end{itemize}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{DNS-Based Service Discovery (RFC 6763)}
+Two-step process:
+\begin{enumerate}
+	\item Service Instance Enumeration
+	\begin{itemize}
+		\item query PTR records of form \code{\_service.\_proto.domain}
+		\item results: instance names of form \code{name.\_service.\_proto.domain}
+	\end{itemize}
+	\item Service Instance Resolution
+	\begin{itemize}
+		\item query instance names as SRV records
+		\item result gives host name, port, priority, weight
+	\end{itemize}
+\end{enumerate}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}[fragile]{Example: mDNS + DNS-SD}
+\tikzset{font=\fontsize{7.5pt}{1em}\selectfont, >=latex, thick, y=3.5em}
+%\tikzstyle{iconlabel}=[text width=2cm, align=center,
+	%font=\fontsize{7.5pt}{1em}\selectfont]
+\tikzstyle{label}=[font=\fontsize{7pt}{1em}\selectfont]
+\tikzstyle{pkt}=[font=\fontsize{6pt}{0.7em}\selectfont,
+	draw,fill=white,dash pattern=on 2pt off 2pt, align=center,
+	inner sep=2pt]
+\def\xhalf{.45\textwidth}
+\def\nodeskip{2.2em}
+\begin{enumerate}
+	\item Service Instance Enumeration
+	\begin{tikzpicture}
+		\node[cloud,draw,fill=gray!20,aspect=2] (thecloud) at (0,0) {multicast};
+		\def\nodelist{
+			node/{(-\xhalf,0)}/{},
+			juliet/{(\xhalf,0)}/juliet,
+			romeo/{(\xhalf,-1)}/romeo,
+			mercutio/{(\xhalf,1)}/mercutio%
+		}
+		\foreach \name/\pos/\text in \nodelist {
+			\node (\name) at \pos { \includegraphics[width=3em]{icon-computer.pdf} };
+			\node[below=\nodeskip of \name.north,label] (\name text) { \text };
+		}
+		\draw[->] (node) -- (thecloud) node[pkt,pos=0.5]{
+			\verb+_presence._tcp.local+\\PTR? };
+		\draw[->] (juliet) -- (thecloud) node[pkt,pos=0.4]{
+			\verb+juliet._presence.+\\\verb+_tcp.local+ };
+		\draw[->] (romeo) -- (thecloud) node[pkt,pos=0.4]{
+			\verb+romeo._presence.+\\\verb+_tcp.local+ };
+		\draw[->] (mercutio) -- (thecloud) node[pkt,pos=0.4]{
+			\verb+mercutio._presence.+\\\verb+_tcp.local+ };
+	\end{tikzpicture}
+
+	\item Service Instance Resolution
+	\begin{tikzpicture}
+		\node[cloud,draw,fill=gray!20,aspect=2] (thecloud) at (0,0) {multicast};
+		\node (node) at (-\xhalf,0) { \includegraphics[width=3em]{icon-computer.pdf} };
+		\node (juliet) at (\xhalf,0) { \includegraphics[width=3em]{icon-computer.pdf} };
+		\node[below=\nodeskip of juliet.north,label] (juliet text) { juliet };
+		\draw[->] (node) -- (thecloud) node[pkt,pos=0.5]{
+			\verb+juliet._presence._tcp.local+\\SRV? };
+		\draw[->] (juliet) -- (thecloud) node[pkt,pos=0.5]{
+			\verb+juliet.local, port 5222,+\\\verb+prio 0, weight 0+ };
+	\end{tikzpicture}
+\end{enumerate}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\againframe<3>{subgoals}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{XMPP (RFC 6122)}
+\begin{columns}[c]
+	\column{.55\textwidth}
+	\begin{onlyenv}<1>
+		\begin{block}{Extensible Messaging and Presence Protocol}
+		\begin{itemize}
+			\item XML-based
+			\item Federated architecture
+			\begin{itemize}
+				\item modeled after E-Mail
+			\end{itemize}
+			\item publish-subscribe mechanism
+			\item XMPP Extension Protocols (XEPs), e.\,g.
+			\begin{itemize}
+				\item Multi-User Chats % (XEP-0045)
+				\item Serverless Messaging %(XEP-0174)
+				\item recently, also XEPs for the IoT %(XEP-0323 through -0326)
+			\end{itemize}
+		\end{itemize}
+		\end{block}
+	\end{onlyenv}
+	\begin{onlyenv}<2>
+		\begin{block}{Serverless XMPP (XEP-0174)}
+		\begin{itemize}
+			\item Clients communicate directly, no server needed
+			\item service discovery via mDNS/DNS-SD
+		\end{itemize}
+		\end{block}
+	\end{onlyenv}
+
+	\column{.45\textwidth}
+	\tikzset{node distance=0pt, >=stealth, thick, x=3.5em, y=2.8em}
+	\tikzstyle{iconlabel}=[text width=2.5cm, align=center,
+		font=\fontsize{7.5pt}{1em}\selectfont]
+	\tikzstyle{label}=[font=\fontsize{7pt}{1em}\selectfont]
+	\begin{overprint}
+		\begin{figure}
+		\begin{tikzpicture}[remember picture]
+			\input{fig-xmpparch.tex}
+		\end{tikzpicture}
+		\end{figure}
+		\tikz[remember picture,overlay]
+			\draw<2>[<->,dotted] (juliet) -- node[anchor=south,label]{serverless} (romeo);
+	\end{overprint}
+\end{columns}
+\end{frame}
+
+\begin{frame}{XMPP (RFC 6122)}
+	\begin{block}{XEPs for the Internet of Things}
+		\begin{itemize}
+			\item XEP-0323 Sensor Data
+			\begin{itemize}
+				\item format for sensor data, query modes
+			\end{itemize}
+			\item XEP-0324 Provisioning
+			\begin{itemize}
+				\item defining access rights and user privileges
+			\end{itemize}
+			\item XEP-0325 Control
+			\begin{itemize}
+				\item get/set control prameters on a (group of) sensor node(s)
+			\end{itemize}
+			\item XEP-0326 Concentrators
+			\begin{itemize}
+				\item implement proxies for a subnet of the WSN
+			\end{itemize}
+		\end{itemize}
+	\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\againframe<4>{subgoals}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Chatty Things}
+\begin{frame}{Chatty Things}
+\begin{itemize}
+	\item use serverless XMPP + mDNS + DNS-SD for communication
+	\item interaction using a standard XMPP client
+	\item prevent information overflow
+	\begin{itemize}
+		\item ``Traffic lights'': status icon in roster represents threshold value
+		\item \emph{Temporary Subscription for Presence (TSP)}
+	\end{itemize}
+	%\item working prototype for Contiki on MSP430
+\end{itemize}
+\begin{block}{Prototype}
+	\begin{itemize}
+		\item \emph{uBonjour} for mDNS + DNS-SD
+		\item \emph{uXMPP} for XMPP
+		\item 12~kB of ROM, 0.6 kB of RAM with Contiki on MSP-430
+	\end{itemize}
+\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{Temporary Subscription for Presence}
+	\begin{block}{Problem}
+		\begin{itemize}
+			\item node must manually subscribe to get information
+			\item users can move quickly out of the network
+			\item subscriptions become outdated
+			\item renewing/canceling subscriptions needs bandwidth
+			\item data publishers also get updates
+		\end{itemize}
+	\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{Temporary Subscription for Presence}
+\begin{block}{Solution: Multi-User Chats}
+	\begin{itemize}
+		\item create one chat room per topic
+		\item users subscribe to information by entering the chat room
+		\item server only sends information to nodes who want it
+		\begin{itemize}
+			\item Chatty Things send a flag that they're uninterested
+		\end{itemize}
+	\end{itemize}
+\end{block}
+\begin{block}{Drawbacks}
+	\begin{itemize}
+		\item only works with central XMPP server
+		\begin{itemize}
+			\item XEP-0045 is not (yet) specified for serverless XMPP
+		\end{itemize}
+		\item XMPP server needs to handle TSP
+	\end{itemize}
+\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{Bootstrapping}
+\begin{block}{At Boot}
+	\begin{enumerate}
+		\item activate uBonjour
+		\item try to discover a central XMPP server
+		\begin{itemize}
+			\item DNS-SD: \code{\_xmpp-client.\_tcp.local}
+		\end{itemize}
+		\item if an XMPP server is discovered: \emph{Infrastructure mode}
+		\begin{itemize}
+			\item connect with ANONYMOUS login (XEP-0175)
+			\item join topic-based chats
+			\item deactivate uBonjour
+		\end{itemize}
+		\item if no server is found: \emph{Ad hoc mode}
+		\begin{itemize}
+			\item activate serverless messaging
+		\end{itemize}
+	\end{enumerate}
+\end{block}
+\end{frame}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}{Bootstrapping}
+\begin{block}{During Runtime}
+	\begin{itemize}
+		\item if server is lost, change to Ad hoc mode
+		\item if new server is found in Ad hod mode, try changing to Infrastructure
+			mode
+		\begin{itemize}
+			\item if that fails, stay in Ad hoc mode
+		\end{itemize}
+	\end{itemize}
+\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\againframe<5>{subgoals}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Related Approaches}
+\begin{frame}{Related Approaches}
+\begin{overprint}
+	\onslide<1>
+	\begin{block}{Chatty Things}
+	\end{block}
+	\onslide<2>
+	\begin{block}{Constrained Application Protocol (CoAP)}
+		\begin{itemize}
+			\item binary mapping to HTTP
+			\item UDP with confirmation and congestion control
+		\end{itemize}
+	\end{block}
+	\onslide<3>
+	\begin{block}{MQ Telemetry Transport (MQTT)}
+		\begin{itemize}
+			\item binary, only 2-byte header
+			\item focused on M2M communication
+		\end{itemize}
+	\end{block}
+	\onslide<4>
+	\begin{block}{Web Service for Devices (WS4D)}
+		\begin{itemize}
+			\item SOAP (XML-based) over HTTP
+		\end{itemize}
+	\end{block}
+\end{overprint}
+\begin{table}
+	\small\centering
+	\begin{tabular}{|>{\onslide<1->}l||>{\onslide<1->}l|>{\onslide<2->}l|
+		>{\onslide<3->}l|>{\onslide<4->}l<{\onslide}|}
+		\hline
+		Feature & Chatty Things & CoAP & MQTT & WS4D \\
+	 \hline\hline
+		application gateways & - & yes & yes & - \\ \hline
+		usable with standard clients & yes & - & - & (yes) \\ \hline
+		discovery support & yes & yes & - & yes\\ \hline
+		IPv6/6LoWPAN ready & yes & yes & ? & partial \\ \hline
+		asynchronous messages & yes & yes & ? & ? \\ \hline
+		protocol overhead & moderate & low & low & high \\ \hline
+	\end{tabular}
+\end{table}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Conclusion}
+\begin{frame}{Conclusion}
+\begin{block}{Advantages of Chatty Things}
+	\begin{itemize}
+		\item no need for central infrastructure
+		\item self-configuration and auto-discovery
+		\item interaction over standard chat clients
+		\item protocol flexibility for enhancements
+	\end{itemize}
+\end{block}
+\begin{block}{Disadvantages of Chatty Things}
+	\begin{itemize}
+		\item XMPP introduces some complexity
+		\item topic filtering only possible with central server
+	\end{itemize}
+\end{block}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}
+\vfill
+\centering\LARGE{Questions?}
+\vfill
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section*{Example}
+\def\bot{-7.5}
+\def\nearlybot{-7}
+\def\top{0}
+\def\nearlytop{-0.5}
+\def\dev{-5}
+\def\cli{5}
+\newlength{\ypos}
+\newlength{\yypos}
+\newcommand{\advanceby}[1]{%
+	\addtolength{\ypos}{#1}%
+	\addtolength{\yypos}{#1}%
+	\global\ypos=\ypos% // see https://tex.stackexchange.com/questions/119730
+	\global\yypos=\yypos%
+}
+\tikzstyle{pkt}=[
+  fill,
+  below=-.5\baselineskip,
+  font=\scriptsize,
+  draw,
+  dash pattern=on 2pt off 2pt,
+]
+\tikzstyle{clipkt}=[pkt,
+  below left=-.5\baselineskip and 0cm,
+  pos=0.05,
+]
+\tikzstyle{devpkt}=[pkt,
+  below right=-.5\baselineskip and 0cm,
+  pos=0.05,
+]
+%%%%%%%%%
+\begin{frame}[fragile,plain,t]{Example: Sensor Data}
+\begin{tikzpicture}[
+  every node/.style={fill=white, font=\small},
+  every picture/.style=ultra thin,
+  >=latex,
+  semithick
+]
+\setlength{\ypos}{0cm}
+\setlength{\yypos}{.5cm}
+%% Header
+\draw (\cli,\top) node[draw]{Client} -- (\cli,\nearlybot);
+\draw[dashed] (\cli,\nearlybot) -- (\cli,\bot);
+\draw (\dev,\top) node[draw]{Device} -- (\dev,\nearlybot);
+\draw[dashed] (\dev,\nearlybot) -- (\dev,\bot);
+
+\advanceby{.75cm}
+\draw[->] (\cli,-\ypos) -- (\dev,-\yypos) node[clipkt]{\verb+<stream>+};
+\advanceby{1cm}
+\draw[->] (\dev,-\ypos) -- (\cli,-\yypos) node[devpkt]{\verb+<stream>+};
+
+\advanceby{1cm}
+\draw[->] (\cli,-\ypos) -- (\dev,-\yypos) node[clipkt,align=left]{
+\verb+<iq type='get' id='1'+\\
+\verb+    to='dev@device.local/res'+\\
+\verb+    from='client@client.local'>+\\
+\verb+  <req xmlns='urn:xmpp:sn' seqnr='1'+\\
+\verb+      momentary='true'>+\\
+\verb+    <node nodeId='Device04'/>+\\
+\verb+    <field name='+{\color{red}\code{Energy}}\verb+'/>+\\
+\verb+    <field name='+{\color{blue}\code{Power}}\verb+'/>+\\
+\verb+  </req> </iq>+
+%\end{verbatim}
+\advanceby{9\baselineskip}
+};
+
+\advanceby{0.3cm}
+\draw[->] (\dev,-\ypos) -- (\cli,-\yypos) node[devpkt,align=left]{
+\verb+<iq type='result' id='1'+\\
+\verb+    from='dev@device.local'+\\
+\verb+    to='client@client.local/res'>+\\
+\verb+  <accepted xmlns='urn:xmpp:sn' seqnr='1'/>+\\
+\verb+</iq>+
+\advanceby{4\baselineskip}
+};
+\end{tikzpicture}
+\end{frame}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}[fragile,plain,t]{Example: Sensor Data (cont.)}
+\begin{tikzpicture}[
+  every node/.style={fill=white, font=\small},
+  every picture/.style=ultra thin,
+  >=latex,
+  semithick
+]
+\setlength{\ypos}{0cm}
+\setlength{\yypos}{.5cm}
+%% Header
+\draw[dashed] (\cli,\top) node[draw]{Client} -- (\cli,\nearlytop);
+\draw (\cli,\nearlytop) -- (\cli,\bot);
+\draw[dashed] (\dev,\top) node[draw]{Device} -- (\dev,\nearlytop);
+\draw (\dev,\nearlytop) -- (\dev,\bot);
+
+\advanceby{.75cm}
+%\advanceby{1cm}
+\draw[->] (\dev,-\ypos) -- (\cli,-\yypos) node[devpkt,align=left]{
+\verb+<message from='dev@device.local'+\\
+\verb+    to='client@client.local/res'>+\\
+\verb+  <fields xmlns='urn:xmpp:sn' seqnr='1' done='true'>+\\
+\verb+    <node nodeId='Device04'>+\\
+\verb+      <timestamp value='2013-03-07T22:03:15'>+\\
+\verb+        <numeric name='+{\color{red}\code{Energy}}\verb+' momentary='true'+\\
+\verb+          value='+{\color{red}\code{167.5}}\verb+' unit='+{\color{red}\code{kWh}}\verb+'/>+\\
+\verb+        <numeric name='+{\color{blue}\code{Power}}\verb+' momentary='true'+\\
+\verb+          value='+{\color{blue}\code{239.4}}\verb+' unit='+{\color{blue}\code{W}}\verb+'/>+\\
+\verb+      </timestamp>+\\
+\verb+    </node>+\\
+\verb+  </fields>+\\
+\verb+</message>+
+\advanceby{12\baselineskip}
+};
+
+\advanceby{1cm}
+\draw[->] (\cli,-\ypos) -- (\dev,-\yypos) node[clipkt]{\verb+</stream>+};
+\advanceby{1cm}
+\draw[->] (\dev,-\ypos) -- (\cli,-\yypos) node[devpkt]{\verb+</stream>+};
+\end{tikzpicture}
+\end{frame}
+\end{document}
