1
\chapter{Using the stub-generator: an example}\label{chap:stubgen-example}
2
\index{stub-generator} 
3
4
\section{Introduction}
5
In this chapter we'll redo the Caesar-Cypher example of
6
chapter~\ref{chap:h-in-example}, now using the stub-generator. You will see
7
that it saves quite a bit of work. Also, as the emphasis is less on byte-level
8
details, it's easier to think about what our ANs and SNs should actually
9
accomplish.
10
11
\section{Writing the service definition}
12
\subsection{Messages and types}
13
Let's look at the messages for the Caesar Cypher again. Using the shorthand
14
notation that we invented in the previous chapter, they would look something
15
like:
16
\begin{verbatim}
17
   in:  [0x0001] caesar_crypt_req       (nota:bdata text, nota:int8 shift);
18
   out: [0x0002] caesar_crypt_rsp       (nota:bdata text);
19
   out: [0x0003] caesar_crypt_error_rsp (caesar:error_t code);
20
\end{verbatim}
21
So, we define three messages, one to be implemented by the SN, and the two
22
others to be implemented by the AN.
23
24
Furthermore, we define on custom type, \texttt{caesar:status\_t}, which
25
describes an error code.
26
27
\subsection{Writing some XML}
28
The next step is to rewrite our shorthand notation into the proper service
29
file syntax. 
30
31
\subsubsection{Definitions}
32
First, we need to write the \texttt{definitions}-element; as we mentioned in
33
the previous chapter, it's attributes are ignored for now, but for
34
informational value, we fill in the \texttt{name}-attribute:
35
\begin{verbatim}
36
    <definitions name="caesar">
37
\end{verbatim}
38
39
\subsubsection{Types}
40
Then comes the \texttt{types}-section, for custom types. In this case, we only
41
have one custom type, \texttt{caesar:error\_t}, which is a simple enumeration;
42
we write:
43
\begin{lstlisting}[language=XML]
44
  <types>
45
    <simpleType name="caesar:error_t">
46
      <restriction base="nota:uns8">
47
      <enumeration value="0x1000">E_GENERAL_ERROR</enumeration>
48
      <enumeration value="0x1010">E_INVALID_DATA</enumeration>
49
      <enumeration value="0x1020">E_INVALID_SHIFT</enumeration>      
50
      </restriction>
51
    </simpleType>
52
  </types>
53
\end{lstlisting}
54
55
\subsubsection{Messages}
56
Now all that is left is to write down the XML for \texttt{caesar\_crypt\_req},
57
\texttt{caesar\_crypt\_rsp} and \texttt{caesar\_crypt\_error\_rsp}. With what
58
we have learned so far, we think the definition of these messages should be
59
pretty straightforward.
60
61
\begin{lstlisting}[language=XML]
62
  <message name="caesar_crypt_req" code="0x0001" direction="in">
63
    <documentation>
64
     request Caesar crypt operation on data
65
    </documentation>
66
    <part name="text" type="nota:bdata">
67
      <documentation>
68
        Data to crypt or encrypt
69
      </documentation>
70
    </part>
71
    <part name="shift" type="nota:int8">
72
      <documentation>
73
	Positions to shift (rotate) 
74
      </documentation>
75
    </part>
76
  </message>
77
  
78
  <message name="caesar_crypt_cnf" code="0x0002" direction="out">
79
    <documentation>
80
      Return the encrypted or decrypted data
81
    </documentation>
82
    <part name="text" type="nota:bdata">
83
      <documentation>
84
        Encrypted or decrypted data
85
      </documentation>
86
    </part>
87
  </message>
88
    
89
  <message name="caesar_crypt_error_rsp" code="0x0003" direction="out">
90
    <documentation>
91
      Return an error code
92
    </documentation>
93
    <part name="code" type="caesar:error_t">
94
      <documentation>
95
	Error code in case some encryption/decryption operation went wrong
96
      </documentation>
97
    </part>
98
  </message>
99
\end{lstlisting}
100
101
And that was all. You can find the complete \texttt{caesar.xml} in appendix~\ref{chap:example}.
102
103
\section{Generating the stubs}
104
As discussed in chapter~\ref{chap:stubgen}, we can use the stub-generator to
105
generate stubs\index{stub}, i.e. machine generated source code files that take
106
care of lot of the low-level plumbing code. Let's see what happens.
107
108
\begin{lstlisting}[language=sh]
109
   nota-stubgen3.pl -platform posix . ./caesar.xml
110
\end{lstlisting}
111
112
will create:
113
\begin{itemize}
114
\item For the application node: \texttt{caesar\_user.c} and
115
  \texttt{caesar\_user.h}. 
116
117
  For each message in the service description with
118
  \texttt{direction=\"in\"}, a wrapper function is generated. For messages
119
  with \texttt{direction=\"out\"} a declaration is generated, for which we
120
  need to write an implementation. In both cases, the stub-generator takes
121
  care of translating the bytes in function arguments and vice versa;
122
  
123
\item For the Service Node: \texttt{caesar\_service.c} and
124
  \texttt{caesar\_service.h}.
125
126
  The code that is generated is similar to that for application node, but with
127
  the \texttt{direction=\"in\"} and \texttt{direction=\"out\"} swapped'
128
129
\item \texttt{caesar\_common.h}: common definitions for \texttt{user} and
130
  \texttt{service}.
131
 
132
\end{itemize}
133
134
\section{Writing the Service Node}
135
Now, let's take a look at the implementing the service node. As seen in the
136
previous section, we have \texttt{caesar\_service.c} and
137
\texttt{caesar\_service.h}. Looking at the header file
138
(\texttt{caesar\_service.h}), we find the following\footnote{if you worry
139
  about the double \texttt{caesar\_}-prefix: this is due to the message having
140
  caesar in their names, and also as the overall namespace. Nothing to worry
141
  about}
142
\begin{lstlisting}[language=c,caption={\texttt{caesar\_service.h} (fragment)}]
143
/* Stubs that can be used to send messages */
144
145
/*       Return the encrypted or decrypted data */
146
/*         Encrypted or decrypted data */
147
int caesar_caesar_crypt_cnf( struct context_pointer* context, uns8* text, 
148
			     uns16 text_len );
149
150
/*       Return an error code */
151
/*      Error code in case some encryption/decryption operation went wrong */
152
int caesar_caesar_crypt_error_rsp( struct context_pointer* context, 
153
				   error_code_t code );
154
155
156
/* Skeleton prototypes; user must implement them. */
157
void caesar_caesar_crypt_req_process( struct context_pointer* context, 
158
				      uns8* text, uns16 text_len, int8 shift );
159
160
\end{lstlisting}
161
162
So, all we need to do is implement the last function
163
\texttt{caesar\_caesar\_crypt\_req\_process}.
164
165
\texttt{caesar\_service.c} contains the plumbing code, and you \textbf{could}
166
add your implementation there. However, it's better to put your own
167
implementation in a separate \texttt{.c}-file. This is much easier if your
168
WSDL ever changes and you need to regenerate the stubs.
169
170
In general, it is not a very good idea to change the WSDL after your code has
171
left the development phase - interfaces should be stable. If you \emph{do}
172
change interfaces that are used by others, make sure you don't leave your name
173
in the source code.
174
175
It's also a good idea to put the service-startup code in a separate file; so,
176
we add two files: \texttt{caesar\_service\_impl.c} (with our implementation of
177
the \texttt{caesar\_service.h}-functions) and  \texttt{caesar-sn.c}, which
178
contains \texttt{main()} and the starts the service.
179
180
\section{Writing an application node}
181
182
\begin{lstlisting}[language=c,caption={\texttt{caesar\_user.h}(fragment)}]
183
/* Stubs that can be used to send messages */
184
185
/*      request Caesar crypt operation on data */
186
/*         Data to crypt or encrypt */
187
/*      Positions to shift (rotate)  */
188
int caesar_caesar_crypt_req( struct context_pointer* context, uns8* text, 
189
			     uns16 text_len, int8 shift );
190
191
192
/* Skeleton prototypes; user must implement them. */
193
void caesar_caesar_crypt_cnf_process( struct context_pointer* context, 
194
				      uns8* text, uns16 text_len );
195
196
void caesar_caesar_crypt_error_rsp_process( struct context_pointer* context, 
197
					    error_code_t code );
198
199
\end{lstlisting}
200
201
Analogous to what we did for the SN, we add two files:
202
\texttt{caesar\_user\_impl.c} (with our implementation of the
203
\texttt{caesar\_user.h}-functions) and \texttt{caesar-an.c}, which contains
204
\texttt{main()} and the starts the application node.
205
206
We need to implement So, all we need to do is implement the last function
207
\texttt{caesar\_caesar\_crypt\_cnf\_process} and
208
\texttt{caesar\_caesar\_crypt\_error\_rsp\_process}.
209
210
211
\section{Building and running}
212
Now that we have written the code for AN and SN, it'd be nice to compile and
213
run them.
214
215
\subsection{Makefile}
216
The easiest way to build the AN and SN is by creating a \texttt{Makefile}. The
217
details of writing Makefiles is out of the scope of this guide, 
218
219
220
\subsection{running}
221
222
223
\section{Questions}
224
To test your understanding of this chapter, you could try to answer some of
225
these questions. You can find the answers to these question in
226
appendix~\ref{chap:answers}.
227
\begin{enumerate}
228
\item Why is it not a good idea to add you own code to
229
  \texttt{caesar\_service.c} or \texttt{caesar\_user.c}?
230
\end{enumerate}