]> git.evergreen-ils.org Git - working/Evergreen.git/blob - docs/admin/sip_server.adoc
Docs reorg: splitting action/triggers into command-line and staff-client manuals
[working/Evergreen.git] / docs / admin / sip_server.adoc
1 SIP Server
2 ----------
3
4 About the SIP Protocol
5 ~~~~~~~~~~~~~~~~~~~~~~
6
7 indexterm:[Automated Circulation System]
8 indexterm:[SelfCheck]
9 indexterm:[Automated Material Handling]
10
11 +SIP+, standing for +Standard Interchange Protocol+, was developed by the +3M corporation+ to be a common 
12 protocol for data transfer between ILS' (referred to in +SIP+ as an _ACS_, or _Automated Circulation System_)  and a 
13 third party device. Originally, the protocol was developed for use with _3M SelfCheck_ (often abbreviated SC, not to 
14 be confused with Staff Client) systems, but has since expanded to other companies and devices. It is now common 
15 to find +SIP+ in use in several other vendors' SelfCheck systems, as well as other non-SelfCheck devices. Some 
16 examples include:
17
18 * Patron Authentication (computer access, subscription databases) 
19 * Automated Material Handling (AMH) 
20 ** The automated sorting of items, often to bins or book carts, based on shelving location or other programmable 
21 criteria
22
23 Installing the SIP Server
24 ~~~~~~~~~~~~~~~~~~~~~~~~~
25
26
27
28 This is a rough intro to installing the +SIP+ server for Evergreen. 
29
30 Getting the code 
31 ^^^^^^^^^^^^^^^^
32
33 Current +SIP+ server code lives at in the Evergreen git repository:
34
35    cd /opt 
36    git clone git://git.evergreen-ils.org/SIPServer.git SIPServer 
37
38
39 Configuring the Server 
40 ^^^^^^^^^^^^^^^^^^^^^^
41
42 indexterm:[configuration files, oils_sip.xml]
43
44 . Type the following commands from the command prompt: 
45
46    $ sudo su opensrf 
47    $ cd /openils/conf 
48    $ cp oils_sip.xml.example oils_sip.xml 
49
50 . Edit oils_sip.xml. Change the commented out <server-params> section to this: 
51
52    <server-params
53       min_spare_servers='1' 
54       max_spare_servers='2' 
55       min_servers='3'
56       max_servers='25' 
57                 />
58
59 . max_servers will directly correspond to the number of allowed +SIP+ clients. Set the number accordingly, but 
60 bear in mind that too many connections can exhaust memory. On a 4G RAM/4 CPU server (that is also running 
61 evergreen), it is not recommended to exceed 100 +SIP+ client connections. 
62
63 Adding SIP Users
64 ^^^^^^^^^^^^^^^^
65
66 indexterm:[configuration files, oils_sip.xml]
67
68 . Type the following commands from the command prompt: 
69
70   $ sudo su opensrf 
71   $ cd /openils/conf
72
73 . In the +<accounts>+ section, add +SIP+ client login information. Make sure that all +<logins>+ use the same 
74 institution attribute, and make sure the institution is listed in +<institutions>+. All attributes in the 
75 +<login>+ section will be used by the +SIP+ client. 
76
77 . In Evergreen, create a new profile group called +SIP+. This group should be a sub-group of +Users+ (not +Staff+ 
78 or +Patrons+). Set _Editing Permission_ as *group_application.user.sip_client* and give the group the following 
79 permissions: 
80 +
81      COPY_CHECKIN 
82      COPY_CHECKOUT 
83      CREATE_PAYMENT
84      RENEW_CIRC 
85      VIEW_CIRCULATIONS 
86      VIEW_COPY_CHECKOUT_HISTORY 
87      VIEW_PERMIT_CHECKOUT 
88      VIEW_USER 
89      VIEW_USER_FINES_SUMMARY 
90      VIEW_USER_TRANSACTIONS 
91 +
92 OR use SQL like: 
93 +
94    
95    INSERT INTO permission.grp_tree (name,parent,description,application_perm) 
96    VALUES ('SIP', 1, 'SIP2 Client Systems', 'group_application.user.sip_client'); 
97   
98    INSERT INTO 
99      permission.grp_perm_map (grp, perm, depth, grantable) 
100    SELECT 
101      g.id, p.id, 0, FALSE 
102    FROM 
103      permission.grp_tree g, 
104      permission.perm_list p 
105    WHERE 
106      g.name = 'SIP' AND 
107      p.code IN ( 
108        'COPY_CHECKIN', 
109        'COPY_CHECKOUT', 
110        'RENEW_CIRC', 
111        'VIEW_CIRCULATIONS', 
112        'VIEW_COPY_CHECKOUT_HISTORY', 
113        'VIEW_PERMIT_CHECKOUT', 
114        'VIEW_USER', 
115        'VIEW_USER_FINES_SUMMARY', 
116        'VIEW_USER_TRANSACTIONS' 
117     ); 
118 +
119 Verify:
120 +
121     
122     SELECT * 
123     FROM permission.grp_perm_map pgpm 
124         INNER JOIN permission.perm_list ppl ON pgpm.perm = ppl.id 
125         INNER JOIN permission.grp_tree pgt ON pgt.id = pgpm.grp 
126     WHERE pgt.name = 'SIP';
127     
128  
129     
130 . For each account created in the +<login>+ section of oils_sip.xml, create a user (via the staff client user 
131 editor) that has the same username and password and put that user into the +SIP+ group. 
132
133 [NOTE]
134 ===================
135 The expiration date will affect the +SIP+ users' connection so you might want to make a note of this 
136 somewhere. 
137 ===================
138
139 Running the server 
140 ^^^^^^^^^^^^^^^^^^
141
142 To start the +SIP+ server type the following commands from the command prompt: 
143
144
145    $ sudo su opensrf 
146
147    $ oils_ctl.sh -a [start|stop|restart]_sip 
148
149 indexterm:[SIP]
150
151
152 Logging-SIP 
153 ^^^^^^^^^^^
154
155 Syslog
156 ++++++
157
158 indexterm:[syslog]
159
160
161 It is useful to log +SIP+ requests to a separate file especially during initial setup by modifying your syslog config file. 
162
163 . Edit syslog.conf. 
164
165    $ sudo vi /etc/syslog.conf  # maybe /etc/rsyslog.conf
166
167
168 . Add this: 
169
170    local6.*                -/var/log/SIP_evergreen.log 
171  
172 . Syslog expects the logfile to exist so create the file. 
173
174    $ sudo touch /var/log/SIP_evergreen.log 
175
176 . Restart sysklogd. 
177
178    $ sudo /etc/init.d/sysklogd restart 
179
180
181 Syslog-NG
182 +++++++++
183
184 indexterm:[syslog-NG]
185
186 . Edit logging config. 
187
188    sudo vi /etc/syslog-ng/syslog-ng.conf 
189
190 . Add: 
191
192    # +SIP2+ for Evergreen 
193    filter    f_eg_sip { level(warn, err, crit) and facility(local6); }; 
194    destination eg_sip { file("var/log/SIP_evergreen.log"); }; 
195    log { source(s_all); filter(f_eg_sip); destination(eg_sip); }; 
196
197 . Syslog-ng expects the logfile to exist so create the file. 
198
199    $ sudo touch /var/log/SIP_evergreen.log
200
201 . Restart syslog-ng 
202
203    $ sudo /etc/init.d/syslog-ng restart 
204
205
206 indexterm:[SIP]
207
208
209 Testing Your SIP Connection 
210 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
211
212 * In the root directory of the SIPServer code: 
213
214    $ cd SIPServer/t 
215
216 * Edit SIPtest.pm, change the $instid, $server, $username, and $password variables. This will be 
217 enough to test connectivity. To run all tests, you'll need to change all the variables in the _Configuration_ section. 
218
219    $ PERL5LIB=../ perl 00sc_status.t 
220 +
221 This should produce something like:
222 +
223
224    1..4 
225    ok 1 - Invalid username 
226    ok 2 - Invalid username 
227    ok 3 - login 
228    ok 4 - SC status 
229
230 * Don't be dismayed at *Invalid Username*. That's just one of the many tests that are run. 
231
232 More Testing
233 ^^^^^^^^^^^^
234
235 Once you have opened up either the +SIP+ OR +SIP2+ ports to be accessible from outside you can do some testing 
236 via +telnet+. In the following tests:
237
238 * Replace +$server+ with your server hostname (or +localhost+ if you want to
239   skip testing external access for now);
240 * Replace +$username+, +$password+, and +$instid+ with the corresponding values
241   in the +<accounts>+ section of your SIP configuration file;
242 * Replace the +$user_barcode+ and +$user_password+ variables with the values
243   for a valid user.
244 * Replace the +$item_barcode+ variable with the values for a valid item.
245
246 ///////////////
247 Comments because we don't want to indent these numbered bullets!
248 ///////////////
249
250 . Start by testing your ability to log into the SIP server:
251 +
252 [NOTE]
253 ======================
254 We are using 6001 here which is associated with +SIP2+ as per our configuration. 
255 ======================
256 +
257    $ telnet $server 6001 
258    Connected to $server. 
259    Escape character is '^]'. 
260    9300CN$username|CO$password|CP$instid
261 +
262 If successful, the SIP server returns a +941+ result. A result of +940+,
263 however, indicates an unsuccessful login attempt. Check the +<accounts>+
264 section of your SIP configuration and try agin.
265
266 . Once you have logged in successfully, replace the variables in the following
267 line and paste it into the telnet session:
268 +
269     2300120080623    172148AO$instid|AA$user_barcode|AC$password|AD$user_password
270 +
271 If successful, the SIP server returns the patron information for $user_barcode,
272 similar to the following:
273 +
274    24  Y           00120100113    170738AEFirstName MiddleName LastName|AA$user_barcode|BLY|CQY
275    |BHUSD|BV0.00|AFOK|AO$instid| 
276 +
277 The response declares it is a valid patron BLY with a valid password CQY and shows the user's +$name+.
278
279 . To test the SIP server's item information response, issue the following request:
280 +
281     1700120080623    172148AO$instid|AB$item_barcode|AC$password
282 +
283 If successful, the SIP server returns the item information for $item_barcode,
284 similar to the following:
285 +
286     1803020120160923    190132AB30007003601852|AJRégion de Kamouraska|CK001|AQOSUL|APOSUL|BHCAD
287     |BV0.00|BGOSUL|CSCA2 PQ NR46 73R
288 +
289 The response declares it is a valid item, with the title, owning library,
290 permanent and current locations, and call number.
291
292 indexterm:[SIP]
293
294 SIP Communication
295 ~~~~~~~~~~~~~~~~~
296
297 indexterm:[SIP Server, SIP Communication]
298
299 +SIP+ generally communicates over a +TCP+ connection (either raw sockets or over +telnet+), but can also 
300 communicate via serial connections and other methods. In Evergreen, the most common deployment is a +RAW+ socket 
301 connection on port 6001.
302
303 +SIP+ communication consists of strings of messages, each message request and response begin with a 2-digit 
304 ``command'' - Requests usually being an odd number and responses usually increased by 1 to be an even number. The 
305 combination numbers for the request command and response is often referred to as a _Message Pair_ (for example, 
306 a 23 command is a request for patron status, a 24 response is a patron status, and the message pair 23/24 is patron 
307 status message pair). The table in the next section shows the message pairs and a description of them. 
308
309 For clarification, the ``Request'' is from the device (selfcheck or otherwise) to the ILS/ACS. The response is… the 
310 response to the request ;). 
311
312 Within each request and response, a number of fields (either a fixed width or separated with a | [pipe symbol] and 
313 preceded with a 2-character field identifier) are used. The fields vary between message pairs. 
314
315 |===========================================================================
316 | *Pair* | *Name*              | *Supported?*          |*Details* 
317 | 01     | Block Patron        | Yes                   |<<sip_01_block_patron, 01/Block_Patron>> - ACS responds with 24 Patron Status Response 
318 | 09-10  | Checkin             | Yes (with extensions) |<<sip_09-10_checkin, 09/10_Checkin>> 
319 | 11-12  | Checkout            | Yes (no renewals)     |<<sip_11-12_checkout, 11/12_Checkout>> 
320 | 15-16  | Hold                | Partially supported   |<<sip_15-16_hold, 15/16_Hold>>  
321 | 17-18  | Item Information    | Yes (no extensions)   |<<sip_17-18_item_information, 17/18_Item_Information>> 
322 | 19-20  | Item Status Update  | No                    |<<sip_19-20_item_status_update, 19/20_Item_Status_Update>> - Returns Patron Enable response, but doesn't make any changes in EG  
323 | 23-24  | Patron Status       | Yes                   |<<sip_23-24_patron_status, 23/24_Patron_Status>> - 63/64 ``Patron Information'' preferred 
324 | 25-26  | Patron Enable       | No                    |<<sip_25-26_patron_enable, 25/26_Patron_Enable>> - Used during system testing and validation 
325 | 29-30  | Renew               | Yes                   |<<sip_29-30_renew, 29/30_Renew>> 
326 | 35-36  | End Session         | Yes                   |<<sip_35-36_end_session, 35/36_End_Session>>
327 | 37-38  | Fee Paid            | Yes                   |<<sip_37-38_fee_paid, 37/38_Fee_Paid>> 
328 | 63-64  | Patron Information  | Yes (no extensions)   |<<sip_63-64_patron_information, 63/64_Patron_Information>> 
329 | 65-66  | Renew All           | Yes                   |<<sip_65-66_renew_all, 65/66_Renew_All>> 
330 | 93-94  | Login               | Yes                   |<<sip_93-94_login, 93/94_Login>> - Must be first command to Evergreen ACS (via socket) or +SIP+ will terminate 
331 | 97-96  | Resend last message | Yes                   |<<sip_97-96_resend, 97/96_Resend>> 
332 | 99-98  | SC-ACS Status       | Yes                   |<<sip_99-98_sc_and_acs_status, 99/98_SC_and_ACS_Status>> 
333 |===========================================================================
334
335 anchor:sip_01_block_patron[]
336
337 01 Block Patron
338 ^^^^^^^^^^^^^^^
339
340 indexterm:[SelfCheck]
341
342 A selfcheck will issue a *Block Patron* command if a patron leaves their card in a selfcheck machine or if the 
343 selfcheck detects tampering (such as attempts to disable multiple items during a single item checkout, multiple failed 
344 pin entries, etc). 
345
346 In Evergreen, this command does the following:
347
348 * User alert message: _CARD BLOCKED BY SELF-CHECK MACHINE_ (this is independent of the AL _Blocked 
349 Card Message_ field). 
350
351 * Card is marked inactive. 
352
353 The request looks like: 
354
355    01<card retained><date>[fields AO, AL, AA, AC] 
356
357 _Card Retained_: A single character field of Y or N - tells the ACS whether the SC has retained the card (ex: left in 
358 the machine) or not. 
359
360 _Date_: An 18 character field for the date/time when the block occurred. 
361
362 _Format_: YYYYMMDDZZZZHHMMSS (ZZZZ being zone - 4 blanks when local time, ``Z'' (3 blanks and a Z) 
363 represents UTC(GMT/Zulu) 
364
365 _Fields_: See <<fields, Fields>> for more details.
366
367 The response is a 24 ``Patron Status Response'' with the following: 
368
369 * Charge privileges denied 
370 * Renewal privileges denied 
371 * Recall privileges denied (hard-coded in every 24 or 64 response) 
372 * hold privileges denied 
373 * Screen Message 1 (AF): _blocked_ 
374 * Patron 
375
376 anchor:sip_09-10_checkin[]
377
378 09/10 Checkin
379 ^^^^^^^^^^^^^
380
381 ~The request looks like: 
382
383    09<No block (Offline)><xact date><return date>[Fields AP,AO,AB,AC,CH,BI] 
384
385 _No Block (Offline)_: A single character field of _Y_ or _N_ - Offline transactions are not currently supported so send _N_. 
386
387 _xact date_: an 18 character field for the date/time when the checkin occurred. Format: 
388 YYYYMMDDZZZZHHMMSS (ZZZZ being zone - 4 blanks when local time, ``Z'' (3 blanks and a Z) represents 
389 UTC(GMT/Zulu) 
390
391 _Fields_: See <<fields, Fields>> for more details. 
392
393 The response is a 10 ``Checkin Response'' with the following: 
394
395    10<resensitize><magnetic media><alert><xact date>[Fields AO,AB,AQ,AJ,CL,AA,CK,CH,CR,CS,CT,CV,CY,DA,AF,AG] 
396
397 Example (with a remote hold): 
398
399   09N20100507    16593720100507    165937APCheckin Bin 5|AOBR1|AB1565921879|ACsip_01| 
400
401   101YNY20100623    165731AOBR1|AB1565921879|AQBR1|AJPerl 5 desktop reference|CK001|CSQA76.73.P33V76 1996 
402   |CTBR3|CY373827|DANicholas Richard Woodard|CV02|
403
404 Here you can see a hold alert for patron CY _373827_, named DA _Nicholas Richard Woodard_, to be picked up at CT 
405 ``BR3''. Since the transaction is happening at AO ``BR1'', the alert type CV is 02 for _hold at remote library_. The 
406 possible values for CV are: 
407
408 * 00: unknown 
409
410 * 01: local hold 
411
412 * 02: remote hold 
413
414 * 03: ILL transfer (not used by EG) 
415
416 * 04: transfer 
417
418 * 99: other 
419
420 indexterm:[magnetic media]
421
422 [NOTE]
423 ===============
424 The logic for Evergreen to determine whether the content is magnetic_media comes from either legacy circ 
425 scripts or search_config_circ_modifier. The default is non-magnetic. The same is true for media_type (default 
426 001). Evergreen does not populate the collection_code because it does not really have any, but it will provide 
427 the call_number where available.
428
429 Unlike the +item_id+ (barcode), the +title_id+ is actually a title string, unless the configuration forces the 
430 return of the bib ID. 
431
432 Don't be confused by the different branches that can show up in the same response line. 
433
434 * AO is where the transaction took place, 
435
436 * AQ is the ``permanent location'', and 
437
438 * CT is the _destination location_ (i.e., pickup lib for a hold or target lib for a transfer). 
439 ================
440
441 anchor:sip_11-12_checkout[]
442
443 11/12 Checkout
444 ^^^^^^^^^^^^^^
445
446
447 anchor:sip_15-16_hold[]
448
449 15/16 Hold
450 ^^^^^^^^^^
451
452 Evergreen supports the Hold message for the purpose of canceling
453 holds.  It does not currently support creating hold requests via SIP2.
454
455
456 anchor:sip_17-18_item_information[]
457
458 17/18 Item Information 
459 ^^^^^^^^^^^^^^^^^^^^^^
460
461 The request looks like: 
462
463     17<xact_date>[fields: AO,AB,AC] 
464
465 The request is very terse. AC is optional. 
466
467 The following response structure is for +SIP2+. (Version 1 of the protocol had only 6 total fields.) 
468
469     18<circulation_status><security_marker><fee_type><xact_date> 
470     [fields: CF,AH,CJ,CM,AB,AJ,BG,BH,BV,CK,AQ,AP,CH,AF,AG,+CT,+CS] 
471
472 Example:
473
474    1720060110    215612AOBR1|ABno_such_barcode| 
475
476    1801010120100609    162510ABno_such_barcode|AJ| 
477
478    1720060110    215612AOBR1|AB1565921879| 
479
480    1810020120100623    171415AB1565921879|AJPerl 5 desktop reference|CK001|AQBR1|APBR1|BGBR1 
481    |CTBR3|CSQA76.73.P33V76 1996| 
482
483 The first case is with a bogus barcode. The latter shows an item with a circulation_status of _10_ for _in transit between 
484 libraries_. The known values of +circulation_status+ are enumerated in the spec. 
485
486 indexterm:[Automated Material Handling (AMH)]
487
488 EXTENSIONS: The CT field for _destination location_ and CS _call number_ are used by Automated Material Handling 
489 systems. 
490
491
492 anchor:sip_19-20_item_status_update[]
493
494 19/20 Item Status Update
495 ^^^^^^^^^^^^^^^^^^^^^^^^
496
497
498 anchor:sip_23-24_patron_status[]
499
500 23/24 Patron Status 
501 ^^^^^^^^^^^^^^^^^^^
502
503 Example: 
504
505    2300120060101    084235AOUWOLS|AAbad_barcode|ACsip_01|ADbad_password| 
506
507    24YYYY          00120100507    013934AE|AAbad_barcode|BLN|AOUWOLS|
508
509    2300120060101    084235AOCONS|AA999999|ACsip_01|ADbad_password| 
510
511    24  Y           00120100507    022318AEDoug Fiander|AA999999|BLY|CQN|BHUSD|BV0.00|AFOK|AOCONS| 
512
513    2300120060101    084235AOCONS|AA999999|ACsip_01|ADuserpassword|LY|CQN|BHUSD|BV0.00|AFOK|AOCONS| 
514
515    24  Y           00120100507    022803AEDoug Fiander|AA999999|BLY|CQY|BHUSD|BV0.00|AFOK|AOCONS| 
516
517 . The BL field (+SIP2+, optional) is _valid patron_, so the _N_ value means _bad_barcode_ doesn't match a patron, the 
518 _Y_ value means 999999 does. 
519
520 . The CQ field (+SIP2+, optional) is _valid password_, so the _N_ value means _bad_password_ doesn't match 999999's 
521 password, the _Y_ means _userpassword_ does. 
522
523 So if you were building the most basic +SIP2+ authentication client, you would check for _|CQY|_ in the response to 
524 know the user's barcode and password are correct (|CQY| implies |BLY|, since you cannot check the password 
525 unless the barcode exists). However, in practice, depending on the application, there are other factors to consider in 
526 authentication, like whether the user is blocked from checkout, owes excessive fines, reported their card lost, etc. 
527 These limitations are reflected in the 14-character _patron status_ string immediately following the _24_ code. See the 
528 field definitions in your copy of the spec. 
529
530
531 anchor:sip_25-26_patron_enable[]
532
533 25/26 Patron Enable 
534 ^^^^^^^^^^^^^^^^^^^
535
536 Not yet supported. 
537
538
539 anchor:sip_29-30_renew[]
540
541 29/30 Renew
542 ^^^^^^^^^^^
543
544 Evergreen supports the Renew message.
545
546
547 anchor:sip_35-36_end_session[]
548
549 35/36 End Session
550 ^^^^^^^^^^^^^^^^^
551
552    3520100505    115901AOBR1|AA999999|
553
554    36Y20100507    161213AOCONS|AA999999|AFThank you!| 
555    
556 The _Y/N_ code immediately after the 36 indicates _success/failure_. Failure is not particularly meaningful or important 
557 in this context, and for evergreen it is hardcoded _Y_. 
558
559
560
561 anchor:sip_37-38_fee_paid[]
562
563 37/38 Fee Paid 
564 ^^^^^^^^^^^^^^
565
566 Evergreen supports the Fee Paid message.
567
568
569 anchor:sip_63-64_patron_information[]
570
571 63/64 Patron Information 
572 ^^^^^^^^^^^^^^^^^^^^^^^^
573
574 Attempting to retrieve patron info with a bad barcode:
575
576    6300020060329    201700          AOBR1|AAbad_barcode| 
577    
578    64YYYY          00020100623    141130000000000000000000000000AE|AAbad_barcode|BLN|AOBR1| 
579
580 Attempting to retrieve patron info with a good barcode (but bad patron password): 
581
582    6300020060329    201700          AOBR1|AA999999|ADbadpwd| 
583
584    64  Y           00020100623    141130000000000000000000000000AA999999|AEDavid J. Fiander|BHUSD|BV0.00 
585    |BD2 Meadowvale Dr. St Thomas, ON Canada 
586
587    90210|BEdjfiander@somemail.com|BF(519) 555 1234|AQBR1|BLY|CQN|PB19640925|PCPatrons 
588    |PIUnfiltered|AFOK|AOBR1| 
589
590 See <<sip_23-24_patron_status, 23/24 Patron Status>> for info on +BL+ and +CQ+ fields. 
591
592
593
594 anchor:sip_65-66_renew_all[]
595
596 65/66 Renew All
597 ^^^^^^^^^^^^^^^
598
599 Evergreen supports the Renew All message.
600
601
602 anchor:sip_93-94_login[]
603
604 93/94 Login 
605 ^^^^^^^^^^^
606
607 Example: 
608
609    9300CNsip_01|CObad_value|CPBR1| 
610   
611    [Connection closed by foreign host.] 
612    ... 
613
614    9300CNsip_01|COsip_01|CPBR1|
615
616    941 
617
618 _941_ means successful terminal login. _940_ or getting dropped means failure.
619
620
621 anchor:sip_97-96_resend[]
622
623 97/96 Resend
624 ^^^^^^^^^^^^
625
626
627 anchor:sip_99-98_sc_and_acs_status[]
628
629 99/98 SC and ACS Status
630 ^^^^^^^^^^^^^^^^^^^^^^^
631
632    99<status code><max print width><protocol version> 
633  
634 All 3 fields are required:
635
636 * 0: SC is OK
637
638 * 1: SC is out of paper 
639
640 * 2: SC shutting down
641
642 * status code - 1 character 
643
644 * max print width - 3 characters - the integer number of characters the client can print 
645
646 * protocol version - 4 characters - x.xx 
647
648   98<on-line status><checkin ok><checkout ok><ACS renewal policy>
649   <status update ok><offline ok><timeout period> 
650
651   <retries allowed><date/time sync><protocol version><institution id> 
652   <library name><supported messages><terminal 
653
654   location><screen message><print line> 
655
656 Example: 
657
658   9910302.00 
659
660   98YYYYNN60000320100510    1717202.00AOCONS|BXYYYYYYYYYNYNNNYN|
661
662 The Supported Messages field +BX+ appears only in +SIP2+, and specifies whether 16 different +SIP+ commands are 
663 supported by the +ACS+ or not. 
664
665
666 anchor:fields[]
667
668 Fields
669 ^^^^^^
670
671 All fixed-length fields in a communication will appear before the first variable-length field. This allows for simple 
672 parsing. Variable-length fields are by definition delimited, though there will not necessarily be an initial delimiter 
673 between the last fixed-length field and the first variable-length one. It would be unnecessary, since you should know 
674 the exact position where that field begins already.