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