--- /dev/null
+\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}