1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
---|
2 | <HTML>
|
---|
3 | <HEAD>
|
---|
4 | <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
|
---|
5 | <TITLE>YAZ User's Guide and Reference: The COMSTACK Module</TITLE>
|
---|
6 | <LINK HREF="yaz-7.html" REL=next>
|
---|
7 | <LINK HREF="yaz-5.html" REL=previous>
|
---|
8 | <LINK HREF="yaz.html#toc6" REL=contents>
|
---|
9 | </HEAD>
|
---|
10 | <BODY>
|
---|
11 | <A HREF="yaz-7.html">Next</A>
|
---|
12 | <A HREF="yaz-5.html">Previous</A>
|
---|
13 | <A HREF="yaz.html#toc6">Contents</A>
|
---|
14 | <HR>
|
---|
15 | <H2><A NAME="comstack"></A> <A NAME="s6">6. The COMSTACK Module</A></H2>
|
---|
16 |
|
---|
17 | <H2><A NAME="ss6.1">6.1 Introduction</A>
|
---|
18 | </H2>
|
---|
19 |
|
---|
20 | <P>The <B>COMSTACK</B>
|
---|
21 | subsystem provides a transparent interface to different types of transport
|
---|
22 | stacks for the exchange of BER-encoded data. At present, the
|
---|
23 | RFC1729 method (BER over TCP/IP), and Peter Furniss' XTImOSI
|
---|
24 | stack are supported, but others may be added in time. The philosophy of the
|
---|
25 | module is to provide a simple interface by hiding unused options and
|
---|
26 | facilities of the underlying libraries. This is always done at the risk
|
---|
27 | of losing generality, and it may prove that the interface will need
|
---|
28 | extension later on.
|
---|
29 | <P>The interface is implemented in such a fashion that only the
|
---|
30 | sub-layers constructed to the transport methods that you wish to
|
---|
31 | use in your application are linked in.
|
---|
32 | <P>You will note that even though simplicity was a goal in the design,
|
---|
33 | the interface is still orders of magnitudes more complex than the
|
---|
34 | transport systems found in many other packages. One reason is that
|
---|
35 | the interface needs to support the somewhat different requirements of
|
---|
36 | the different lower-layer communications stacks; another important reason is
|
---|
37 | that the interface seeks to provide a more or less industrial-strength
|
---|
38 | approach to asynchronous event-handling. When no function is allowed
|
---|
39 | to block, things get more complex - particularly on the server
|
---|
40 | side. We urge you to have a look at the demonstration client and server
|
---|
41 | provided with the package. They are meant to be easily readable and
|
---|
42 | instructive, while still being at least moderately useful.
|
---|
43 | <P>
|
---|
44 | <H2><A NAME="ss6.2">6.2 Common Functions</A>
|
---|
45 | </H2>
|
---|
46 |
|
---|
47 | <H3>Managing Endpoints</H3>
|
---|
48 |
|
---|
49 | <P>
|
---|
50 | <BLOCKQUOTE><CODE>
|
---|
51 | <PRE>
|
---|
52 | COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
|
---|
53 | </PRE>
|
---|
54 | </CODE></BLOCKQUOTE>
|
---|
55 | <P>Creates an instance of the protocol stack - a communications endpoint.
|
---|
56 | The
|
---|
57 | <CODE>type</CODE>
|
---|
58 | parameter determines the mode of communication. At present, the
|
---|
59 | values
|
---|
60 | <CODE>tcpip_type</CODE>
|
---|
61 | and
|
---|
62 | <CODE>mosi_type</CODE>
|
---|
63 | are recognized. The function returns a null-pointer if a system error
|
---|
64 | occurs. The <CODE>blocking</CODE> parameter should be one if you wish the
|
---|
65 | association to operate in blocking mode, zero otherwise. The
|
---|
66 | <CODE>protocol</CODE> field should be one of <CODE>PROTO_SR</CODE> or <CODE>PROTO_Z3950</CODE>.
|
---|
67 | <P>
|
---|
68 | <BLOCKQUOTE><CODE>
|
---|
69 | <PRE>
|
---|
70 | int cs_close(COMSTACK handle);
|
---|
71 | </PRE>
|
---|
72 | </CODE></BLOCKQUOTE>
|
---|
73 | <P>Closes the connection (as elegantly as the lower layers will permit),
|
---|
74 | and releases the resouces pointed to by the
|
---|
75 | <CODE>handle</CODE>
|
---|
76 | parameter. The
|
---|
77 | <CODE>handle</CODE>
|
---|
78 | should not be referenced again after this call.
|
---|
79 | <P><I>NOTE:
|
---|
80 | We really need a soft disconnect, don't we?</I>
|
---|
81 | <P>
|
---|
82 | <H3>Data Exchange</H3>
|
---|
83 |
|
---|
84 | <P>
|
---|
85 | <BLOCKQUOTE><CODE>
|
---|
86 | <PRE>
|
---|
87 | int cs_put(COMSTACK handle, char *buf, int len);
|
---|
88 | </PRE>
|
---|
89 | </CODE></BLOCKQUOTE>
|
---|
90 | <P>Sends
|
---|
91 | <CODE>buf</CODE>
|
---|
92 | down the wire. In blocking mode, this function will return only when a
|
---|
93 | full buffer has been written, or an error has occurred. In nonblocking
|
---|
94 | mode, it's possible that the function will be unable to send the full
|
---|
95 | buffer at once, which will be indicated by a return value of 1. The
|
---|
96 | function will keep track of the number of octets already written; you
|
---|
97 | should call it repeatedly with the same values of <CODE>buf</CODE> and
|
---|
98 | <CODE>len</CODE>, until the buffer has been transmitted. When a full buffer
|
---|
99 | has been sent, the function will return 0 for success. -1 indicates
|
---|
100 | an error condition (see below).
|
---|
101 | <P>
|
---|
102 | <BLOCKQUOTE><CODE>
|
---|
103 | <PRE>
|
---|
104 | int cs_get(COMSTACK handle, char **buf, int *size);
|
---|
105 | </PRE>
|
---|
106 | </CODE></BLOCKQUOTE>
|
---|
107 | <P>Receives a PDU from the peer. Returns the number of bytes
|
---|
108 | read. In nonblocking mode, it is possible that not all of the packet can be
|
---|
109 | read at once. In this case, the function returns 1. To simplify the
|
---|
110 | interface, the function is
|
---|
111 | responsible for managing the size of the buffer. It will be reallocated
|
---|
112 | if necessary to contain large packages, and will sometimes be moved
|
---|
113 | around internally by the subsystem when partial packages are read. Before
|
---|
114 | calling
|
---|
115 | <CODE>cs_get</CODE>
|
---|
116 | for the fist time, the buffer can be initialized to the null pointer,
|
---|
117 | and the length should also be set to 0 - cs_get will perform a
|
---|
118 | <CODE>malloc</CODE>(2)
|
---|
119 | on the buffer for you. When a full buffer has been read, the size of
|
---|
120 | the package is returned (which will always be greater than 1). -1
|
---|
121 | indicates an error condition.
|
---|
122 | <P>See also the
|
---|
123 | <CODE>cs_more()</CODE>
|
---|
124 | function below.
|
---|
125 | <P>
|
---|
126 | <BLOCKQUOTE><CODE>
|
---|
127 | <PRE>
|
---|
128 | int cs_more(COMSTACK handle);
|
---|
129 | </PRE>
|
---|
130 | </CODE></BLOCKQUOTE>
|
---|
131 | <P>The <CODE>cs_more()</CODE> function should be used in conjunction with
|
---|
132 | <CODE>cs_get</CODE>
|
---|
133 | and
|
---|
134 | <CODE>select</CODE>(2).
|
---|
135 | The <CODE>cs_get()</CODE> function will sometimes (notably in the TCP/IP mode) read
|
---|
136 | more than a single protocol package off the network. When this
|
---|
137 | happens, the extra package is stored by the subsystem. After calling
|
---|
138 | <CODE>cs_get()</CODE>, and before waiting for more input,
|
---|
139 | You should always call
|
---|
140 | <CODE>cs_more()</CODE>
|
---|
141 | to check if there's a full protocol package already read. If
|
---|
142 | <CODE>cs_more()</CODE>
|
---|
143 | returns 1,
|
---|
144 | <CODE>cs_get()</CODE>
|
---|
145 | can be used to immediately fetch the new package. For the
|
---|
146 | mOSI
|
---|
147 | subsystem, the function should always return 0, but if you want your
|
---|
148 | stuff to be protocol independent, you should use it.
|
---|
149 | <P><I>NOTE: The <CODE>cs_more()</CODE>
|
---|
150 | function is required because the
|
---|
151 | RFC1729-method
|
---|
152 | does not provide a way of separating individual PDUs, short of
|
---|
153 | partially decoding the BER. Some other implementations will carefully
|
---|
154 | nibble at the packet by calling
|
---|
155 | <CODE>read</CODE>(2)
|
---|
156 | several times. This was felt to be too inefficient (or at least
|
---|
157 | clumsy) - hence the call for this extra function.</I>
|
---|
158 | <P>
|
---|
159 | <BLOCKQUOTE><CODE>
|
---|
160 | <PRE>
|
---|
161 | int cs_look(COMSTACK handle);
|
---|
162 | </PRE>
|
---|
163 | </CODE></BLOCKQUOTE>
|
---|
164 | <P>This function is useful when you're operating in nonblocking
|
---|
165 | mode. Call it when
|
---|
166 | <CODE>select</CODE>(2)
|
---|
167 | tells you there's something happening on the line. It returns one of
|
---|
168 | the following values:
|
---|
169 | <P>
|
---|
170 | <DL>
|
---|
171 | <DT><B>CS_NONE</B><DD><P>No event is pending. The data found on the line was
|
---|
172 | not a complete package.
|
---|
173 | <DT><B>CS_CONNECT</B><DD><P>A response to your connect request has been received. Call
|
---|
174 | <CODE>cs_rcvconnect</CODE>
|
---|
175 | to process the event and to finalize the connection establishment.
|
---|
176 | <DT><B>CS_DISCON</B><DD><P>The other side has closed the connection (or maybe
|
---|
177 | sent a disconnect
|
---|
178 | request - but do we care? Maybe later). Call
|
---|
179 | <CODE>cs_close</CODE> To close your end of the association as well.
|
---|
180 | <DT><B>CS_LISTEN</B><DD><P>A connect request has been received. Call
|
---|
181 | <CODE>cs_listen</CODE>
|
---|
182 | to process the event.
|
---|
183 | <DT><B>CS_DATA</B><DD><P>There's data to be found on the line. Call
|
---|
184 | <CODE>cs_get</CODE>
|
---|
185 | to get it.
|
---|
186 | </DL>
|
---|
187 | <P><I>NOTE:
|
---|
188 | You should be aware that even if
|
---|
189 | <CODE>cs_look()</CODE>
|
---|
190 | tells you that there's an event event pending, the corresponding
|
---|
191 | function may still return and tell you there was nothing to be found.
|
---|
192 | This means that only part of a package was available for reading. The
|
---|
193 | same event will show up again, when more data has arrived.</I>
|
---|
194 | <P>
|
---|
195 | <BLOCKQUOTE><CODE>
|
---|
196 | <PRE>
|
---|
197 | int cs_fileno(COMSTACK h);
|
---|
198 | </PRE>
|
---|
199 | </CODE></BLOCKQUOTE>
|
---|
200 | <P>Returns the file descriptor of the association. Use this when
|
---|
201 | file-level operations on the endpoint are required (<CODE>select</CODE>(2)
|
---|
202 | operations, specifically).
|
---|
203 | <P>
|
---|
204 | <H2><A NAME="ss6.3">6.3 Client Side</A>
|
---|
205 | </H2>
|
---|
206 |
|
---|
207 | <P>
|
---|
208 | <BLOCKQUOTE><CODE>
|
---|
209 | <PRE>
|
---|
210 | int cs_connect(COMSTACK handle, void *address);
|
---|
211 | </PRE>
|
---|
212 | </CODE></BLOCKQUOTE>
|
---|
213 | <P>Initiate a connection with the target at <CODE>address</CODE> (more on
|
---|
214 | addresses below). The function will return 0 on success, and 1 if
|
---|
215 | the operation does not complete immediately (this will only
|
---|
216 | happen on a nonblocking endpoint). In this case, use
|
---|
217 | <CODE>cs_rcvconnect</CODE> to complete the operation, when <CODE>select</CODE>(2)
|
---|
218 | reports input pending on the association.
|
---|
219 | <P>
|
---|
220 | <BLOCKQUOTE><CODE>
|
---|
221 | <PRE>
|
---|
222 | int cs_rcvconnect(COMSTACK handle);
|
---|
223 | </PRE>
|
---|
224 | </CODE></BLOCKQUOTE>
|
---|
225 | <P>Complete a connect operation initiated by <CODE>cs_connect()</CODE>. It will
|
---|
226 | return 0 on success; 1 if the operation has not yet completed (in this
|
---|
227 | case, call the function again later); -1 if an error has occured.
|
---|
228 | <P>
|
---|
229 | <H2><A NAME="ss6.4">6.4 Server Side</A>
|
---|
230 | </H2>
|
---|
231 |
|
---|
232 | <P>To establish a server under the <CODE>inetd</CODE> server, you can use
|
---|
233 | <P>
|
---|
234 | <BLOCKQUOTE><CODE>
|
---|
235 | <PRE>
|
---|
236 | COMSTACK cs_createbysocket(int socket, CS_TYPE type, int blocking,
|
---|
237 | int protocol);
|
---|
238 | </PRE>
|
---|
239 | </CODE></BLOCKQUOTE>
|
---|
240 | <P>The <I>socket</I> parameter is an established socket (when your
|
---|
241 | application is invoked from <CODE>inetd</CODE>, the socket will typically be
|
---|
242 | 0. The following parameters are identical to the ones for
|
---|
243 | <CODE>cs_create</CODE>.
|
---|
244 | <P>
|
---|
245 | <BLOCKQUOTE><CODE>
|
---|
246 | <PRE>
|
---|
247 | int cs_bind(COMSTACK handle, void *address, int mode)
|
---|
248 | </PRE>
|
---|
249 | </CODE></BLOCKQUOTE>
|
---|
250 | <P>Binds a local address to the endpoint. Read about addresses below. The
|
---|
251 | <CODE>mode</CODE> parameter should be either <CODE>CS_CLIENT</CODE> or <CODE>CS_SERVER</CODE>.
|
---|
252 | <P>
|
---|
253 | <BLOCKQUOTE><CODE>
|
---|
254 | <PRE>
|
---|
255 | int cs_listen(COMSTACK handle, char *addr, int *addrlen);
|
---|
256 | </PRE>
|
---|
257 | </CODE></BLOCKQUOTE>
|
---|
258 | <P>Call this to process incoming events on an endpoint that has been
|
---|
259 | bound in listening mode. It will return 0 to indicate that the connect
|
---|
260 | request has been received, 1 to signal a partial reception, and -1 to
|
---|
261 | indicate an error condition.
|
---|
262 | <P>
|
---|
263 | <BLOCKQUOTE><CODE>
|
---|
264 | <PRE>
|
---|
265 | COMSTACK cs_accept(COMSTACK handle);
|
---|
266 | </PRE>
|
---|
267 | </CODE></BLOCKQUOTE>
|
---|
268 | <P>This finalises the server-side association establishment, after
|
---|
269 | cs_listen has completed successfully. It returns a new connection
|
---|
270 | endpoint, which represents the new association. The application will
|
---|
271 | typically wish to fork off a process to handle the association at this
|
---|
272 | point, and continue listen for new connections on the old <CODE>handle</CODE>.
|
---|
273 | <P>You can use the call
|
---|
274 | <P>
|
---|
275 | <BLOCKQUOTE><CODE>
|
---|
276 | <PRE>
|
---|
277 | char *cs_addrstr(COMSTACK);
|
---|
278 | </PRE>
|
---|
279 | </CODE></BLOCKQUOTE>
|
---|
280 | <P>on an established connection to retrieve the hostname of the remote host.
|
---|
281 | <P><I>NOTE: You may need to use this function with some care if your
|
---|
282 | name server service is slow or unreliable</I>
|
---|
283 | <P>
|
---|
284 | <H2><A NAME="ss6.5">6.5 Addresses</A>
|
---|
285 | </H2>
|
---|
286 |
|
---|
287 | <P>The low-level format of the addresses are different depending on the
|
---|
288 | mode of communication you have chosen. A function is provided by each
|
---|
289 | of the lower layers to map a user-friendly string-form address to the
|
---|
290 | binary form required by the lower layers.
|
---|
291 | <P>
|
---|
292 | <BLOCKQUOTE><CODE>
|
---|
293 | <PRE>
|
---|
294 | struct sockaddr_in *tcpip_strtoaddr(char *str);
|
---|
295 |
|
---|
296 | struct netbuf *mosi_strtoaddr(char *str);
|
---|
297 | </PRE>
|
---|
298 | </CODE></BLOCKQUOTE>
|
---|
299 | <P>The format for TCP/IP addresses is straightforward:
|
---|
300 | <P>
|
---|
301 | <BLOCKQUOTE><CODE>
|
---|
302 | <PRE>
|
---|
303 | <host> [ ':' <portnum> ]
|
---|
304 | </PRE>
|
---|
305 | </CODE></BLOCKQUOTE>
|
---|
306 | <P>The <CODE>hostname</CODE> can be either a domain name or an IP address. The
|
---|
307 | port number, if omitted, defaults to 210.
|
---|
308 | <P>For OSI, the format is
|
---|
309 | <P>
|
---|
310 | <BLOCKQUOTE><CODE>
|
---|
311 | <PRE>
|
---|
312 | [ <t-selector> '/' ] <host> [ ':' <port> ]
|
---|
313 | </PRE>
|
---|
314 | </CODE></BLOCKQUOTE>
|
---|
315 | <P>The transport selector is given as an even number of hex digits.
|
---|
316 | <P>You'll note that the address format for the OSI mode are just a subset
|
---|
317 | of full presentation addresses. We use presentation addresses because
|
---|
318 | xtimosi doesn't, in itself, allow access to the X.500 Directory
|
---|
319 | service. We use a limited form, because we haven't yet come across an
|
---|
320 | implementation that used more of the elements of a full p-address. It
|
---|
321 | is a fairly simple matter to add the rest of the elements to the
|
---|
322 | address format as needed, however: Xtimosi <I>does</I> support the full
|
---|
323 | P-address structure.
|
---|
324 | <P>In both transport modes, the special hostname "@" is mapped
|
---|
325 | to any local address (the manifest constant INADDR_ANY). It is used
|
---|
326 | to establish local listening endpoints in the server role.
|
---|
327 | <P>When a connection has been established, you can use
|
---|
328 | <P>
|
---|
329 | <BLOCKQUOTE><CODE>
|
---|
330 | <PRE>
|
---|
331 | char cs_addrstr(COMSTACK h);
|
---|
332 | </PRE>
|
---|
333 | </CODE></BLOCKQUOTE>
|
---|
334 | <P>to retrieve the host name of the peer system. The function returns a pointer
|
---|
335 | to a static area, which is overwritten on the next call to the function.
|
---|
336 | <P><I>NOTE: We have left the issue of X.500 name-to-address mapping open, for the
|
---|
337 | moment. It would be a simple matter to provide a table-based mapping,
|
---|
338 | if desired. Alternately, we could use the X.500 client-function that
|
---|
339 | is provided with the ISODE (although this would defeat some of the
|
---|
340 | purpose of using ThinOSI in the first place. We have been told that it
|
---|
341 | should be within the realm of the possible to implement a lightweight
|
---|
342 | implementation of the necessary X.500 client capabilities on top of
|
---|
343 | ThinOSI. This would be the ideal solution, we feel. On the other hand, it
|
---|
344 | still remains to be seen just what role the Directory will play in a world
|
---|
345 | populated by ThinOSI and other pragmatic solutions.</I>
|
---|
346 | <P>
|
---|
347 | <H2><A NAME="ss6.6">6.6 Diagnostics</A>
|
---|
348 | </H2>
|
---|
349 |
|
---|
350 | <P>All functions return -1 if an error occurs. Typically, the functions
|
---|
351 | will return 0 on success, but the data exchange functions
|
---|
352 | (<CODE>cs_get</CODE>, <CODE>cs_put</CODE>, <CODE>cs_more</CODE>)
|
---|
353 | follow special rules. Consult their descriptions.
|
---|
354 | <P>When a function (including the data exchange functions) reports an
|
---|
355 | error condition,
|
---|
356 | use the function
|
---|
357 | <CODE>cs_errno()</CODE>
|
---|
358 | to determine the cause of the
|
---|
359 | problem. The function
|
---|
360 | <P>
|
---|
361 | <BLOCKQUOTE><CODE>
|
---|
362 | <PRE>
|
---|
363 | void cs_perror(COMSTACK handle char *message);
|
---|
364 | </PRE>
|
---|
365 | </CODE></BLOCKQUOTE>
|
---|
366 | <P>works like
|
---|
367 | <CODE>perror</CODE>(2)
|
---|
368 | and prints the
|
---|
369 | <CODE>message</CODE>
|
---|
370 | argument, along with a system message, to
|
---|
371 | <CODE>stderr</CODE>.
|
---|
372 | Use the character array
|
---|
373 | <P>
|
---|
374 | <BLOCKQUOTE><CODE>
|
---|
375 | <PRE>
|
---|
376 | extern const char *cs_errlist[];
|
---|
377 | </PRE>
|
---|
378 | </CODE></BLOCKQUOTE>
|
---|
379 | <P>to get hold of the message, if you want to process it differently.
|
---|
380 | The function
|
---|
381 | <P>
|
---|
382 | <BLOCKQUOTE><CODE>
|
---|
383 | <PRE>
|
---|
384 | const char *cs_stackerr(COMSTACK handle);
|
---|
385 | </PRE>
|
---|
386 | </CODE></BLOCKQUOTE>
|
---|
387 | <P>Returns an error message from the lower layer, if one has been
|
---|
388 | provided.
|
---|
389 | <P>
|
---|
390 | <H2><A NAME="ss6.7">6.7 Enabling OSI Communication</A>
|
---|
391 | </H2>
|
---|
392 |
|
---|
393 | <H3>Installing Xtimosi</H3>
|
---|
394 |
|
---|
395 | <P>Although you will have to download Peter Furniss' XTI/mOSI
|
---|
396 | implementation for yourself, we've tried to make the integration as
|
---|
397 | simple as possible.
|
---|
398 | <P>The latest version of xtimosi will generally be under
|
---|
399 | <P>
|
---|
400 | <BLOCKQUOTE><CODE>
|
---|
401 | <PRE>
|
---|
402 | ftp://pluto.ulcc.ac.uk/ulcc/thinosi/xtimosi/
|
---|
403 | </PRE>
|
---|
404 | </CODE></BLOCKQUOTE>
|
---|
405 | <P>When you have downloaded and unpacked the archive, it will (we assume)
|
---|
406 | have created a directory called <CODE>xtimosi</CODE>. We suggest that you place
|
---|
407 | this directory <I>in the same directory</I> where you unpacked the
|
---|
408 | <B>YAZ</B>
|
---|
409 | distribution. This way, you shouldn't have to fiddle with the
|
---|
410 | makefiles of <CODE>YAZ</CODE> beyond uncommenting a few lines.
|
---|
411 | <P>Go to <CODE>xtimosi/src</CODE>, and type "<CODE>make libmosi.a</CODE>".
|
---|
412 | This should generally
|
---|
413 | create the library, ready to use.
|
---|
414 | <P><B>CAVEAT</B>
|
---|
415 | <P><I>The currently available release of xtimosi has some inherent
|
---|
416 | problems that make it disfunction on certain platforms - eg. the
|
---|
417 | Digital OSF/1 workstations. It is supposedly primarily a
|
---|
418 | compiler problem, and we hope to see a release that is generally
|
---|
419 | portable. While we can't guarantee that it can be brought to work
|
---|
420 | on your platform, we'll be happy to talk to you about problems
|
---|
421 | that you might see, and relay information to the author of the
|
---|
422 | software. There are some signs that the <B>gcc</B> compiler is more
|
---|
423 | likely to produce a fully functional library, but this hasn't
|
---|
424 | been verified (we think that the problem is limited to the use
|
---|
425 | of hexadecimal escape-codes used in strings, which are silently
|
---|
426 | ignored by some compilers).</I>
|
---|
427 | <P><I>A problem has been encountered in the communication with
|
---|
428 | ISODE-based applications. If the ISODE presentation-user calls
|
---|
429 | <CODE>PReadRequest()</CODE> with a timeout value different from <CODE>OK</CODE> or <CODE>NOTOK</CODE>,
|
---|
430 | he will get an immediate TIMEOUT abort when receiving large (>2041
|
---|
431 | bytes, which is the SPDU-size that the ISODE likes to work with) packages
|
---|
432 | from an xtimosi-based implementation (probably most
|
---|
433 | other implementations as well, in fact). It seems to be a flaw in the
|
---|
434 | ISODE API, and the workaround (for ISODE users) is to either not
|
---|
435 | use an explicit timeout (switching to either blocking or
|
---|
436 | nonblocking mode), or to check that the timer really has expired
|
---|
437 | before closing the connection.</I>
|
---|
438 | <P>The next step in the installation is to modify the makefile in the toplevel
|
---|
439 | <B>YAZ</B>
|
---|
440 | directory. The place to change is in the top of the file, and is
|
---|
441 | clearly marked with a comment.
|
---|
442 | <P>Now run <CODE>make</CODE> in the <B>YAZ</B> toplevel directory (do a
|
---|
443 | "<CODE>make clean</CODE>" first, if the
|
---|
444 | system has been previously made without OSI support). Use the <B>YAZ</B>
|
---|
445 | <B>ztest</B>
|
---|
446 | and <B>client</B> demo programs to verify that OSI communication works OK. Then,
|
---|
447 | you can go ahead and try to talk to other implementations.
|
---|
448 | <P><I>NOTE: Our interoperability experience is limited to version
|
---|
449 | 7 of the Nordic SR-Nett package, which has had several
|
---|
450 | protocol errors fixed from the earlier releases. If you have
|
---|
451 | problems or successes in interoperating with other
|
---|
452 | implementations, we'd be glad to hear about it, or to help
|
---|
453 | you make things work, as our resources allow.</I>
|
---|
454 | <P>If you write your own applications based on <B>YAZ</B>, and you wish to
|
---|
455 | include OSI support, the procedure is equally simple. You should
|
---|
456 | include the <CODE>xmosi.h</CODE> header file in addition to <CODE>comstack.h</CODE>.
|
---|
457 | <CODE>xmosi.h</CODE>
|
---|
458 | will define the manifest constant <CODE>mosi_type</CODE>, which you should pass
|
---|
459 | to the <CODE>cs_create()</CODE> function. In
|
---|
460 | addition, you should use the function <CODE>mosi_strtoaddr()</CODE> rather than
|
---|
461 | <CODE>tcpip_strtoaddr()</CODE> when you need to prepare an address.
|
---|
462 | <P>When you link your application, you should include (after the
|
---|
463 | <CODE>libyaz.a</CODE>
|
---|
464 | library) the <CODE>libmosi.a</CODE> library, and the <CODE>librfc.a</CODE> library
|
---|
465 | provided with
|
---|
466 | <B>YAZ</B> (for OSI transport).
|
---|
467 | <P>As always, it can be very useful, if not essential, to have a look at the
|
---|
468 | example applications
|
---|
469 | to see how things are done.
|
---|
470 | <P>
|
---|
471 | <H3>OSI Transport</H3>
|
---|
472 |
|
---|
473 | <P>Xtimosi requires an implementation of the OSI transport service under
|
---|
474 | the X/OPEN XTI API. We provide an implementation of the RFC1006
|
---|
475 | encapsulation of OSI/TP0 in TCP/IP (through the Berkeley Sockets API),
|
---|
476 | as an independent part of <B>YAZ</B> (it's found under the <CODE>rfc1006</CODE>
|
---|
477 | directory). If you have access to an OSI transport provider under XTI,
|
---|
478 | you should be able to make that work too, although it may require
|
---|
479 | tinkering with the <CODE>mosi_strtoaddr()</CODE> function.
|
---|
480 | <P>
|
---|
481 | <H3>Presentation Context Management</H3>
|
---|
482 |
|
---|
483 | <P>To simplify the implementation, we use Peter Furniss' alternative (PRF)
|
---|
484 | option format
|
---|
485 | for the Control of the presentation negotiation phase. This format
|
---|
486 | is enabled by default when you
|
---|
487 | compile xtimosi.
|
---|
488 | <P>The current version of <B>YAZ</B> does <I>not</I> support presentation-layer
|
---|
489 | negotiation of response record formats. The primary reason is that we
|
---|
490 | have had access to no other SR or Z39.50 implementations over OSI that
|
---|
491 | used this
|
---|
492 | method. Secondarily, we believe that the EXPLAIN facility is a superior
|
---|
493 | mechanism for relaying target capabilities in this respect. This is not to
|
---|
494 | say that we have no intentions of supporting presentation context
|
---|
495 | negotiation - we have just hitherto given it a lower priority than other
|
---|
496 | aspects of the protocol.
|
---|
497 | <P>One thing is certain: The addition of this capability to <B>YAZ</B> should
|
---|
498 | have only a minimal impact on existing applications, and on the
|
---|
499 | interface to the software in general. Most likely, we will add an extra
|
---|
500 | layer of interface to the processing of EXPLAIN records, which will
|
---|
501 | convert back and forth between <CODE>oident</CODE> records (see section
|
---|
502 | <A HREF="yaz-3.html#oid">Object Identifiers</A>) and direct or indirect
|
---|
503 | references, given the current association setup. Implementations based
|
---|
504 | on any of the higher-level interfaces will most likely not have to be
|
---|
505 | changed at all.
|
---|
506 | <P>
|
---|
507 | <H2><A NAME="ss6.8">6.8 Summary and Synopsis</A>
|
---|
508 | </H2>
|
---|
509 |
|
---|
510 | <P>
|
---|
511 | <BLOCKQUOTE><CODE>
|
---|
512 | <PRE>
|
---|
513 | #include <comstack.h>
|
---|
514 |
|
---|
515 | #include <tcpip.h> /* this is for TCP/IP support */
|
---|
516 | #include <xmosi.h> /* and this is for mOSI support */
|
---|
517 |
|
---|
518 | COMSTACK cs_create(CS_TYPE type, int blocking, int protocol);
|
---|
519 |
|
---|
520 | COMSTACK cs_createbysocket(int s, CS_TYPE type, int blocking,
|
---|
521 | int protocol);
|
---|
522 |
|
---|
523 | int cs_bind(COMSTACK handle, int mode);
|
---|
524 |
|
---|
525 | int cs_connect(COMSTACK handle, void *address);
|
---|
526 |
|
---|
527 | int cs_rcvconnect(COMSTACK handle);
|
---|
528 |
|
---|
529 | int cs_listen(COMSTACK handle);
|
---|
530 |
|
---|
531 | COMSTACK cs_accept(COMSTACK handle);
|
---|
532 |
|
---|
533 | int cs_put(COMSTACK handle, char *buf, int len);
|
---|
534 |
|
---|
535 | int cs_get(COMSTACK handle, char **buf, int *size);
|
---|
536 |
|
---|
537 | int cs_more(COMSTACK handle);
|
---|
538 |
|
---|
539 | int cs_close(COMSTACK handle);
|
---|
540 |
|
---|
541 | int cs_look(COMSTACK handle);
|
---|
542 |
|
---|
543 | struct sockaddr_in *tcpip_strtoaddr(char *str);
|
---|
544 |
|
---|
545 | struct netbuf *mosi_strtoaddr(char *str);
|
---|
546 |
|
---|
547 | extern int cs_errno;
|
---|
548 |
|
---|
549 | void cs_perror(COMSTACK handle char *message);
|
---|
550 |
|
---|
551 | const char *cs_stackerr(COMSTACK handle);
|
---|
552 |
|
---|
553 | extern const char *cs_errlist[];
|
---|
554 | </PRE>
|
---|
555 | </CODE></BLOCKQUOTE>
|
---|
556 | <P>
|
---|
557 | <HR>
|
---|
558 | <A HREF="yaz-7.html">Next</A>
|
---|
559 | <A HREF="yaz-5.html">Previous</A>
|
---|
560 | <A HREF="yaz.html#toc6">Contents</A>
|
---|
561 | </BODY>
|
---|
562 | </HTML>
|
---|