From c8ad0c3e7eb9156f6927ef706355d70c3384b05e Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 5 Apr 2013 14:14:27 -0400 Subject: [PATCH] SIP Server as SIP client library Adds support for parsing message responses directly to the SIP server message handling code. This allows for the creation of Perl SIP client code using the existing SIP server code infrastructure. Code originally developed my Michael Smith. Support for allowing duplicate fields (in client mode) added by me (berick). Signed-off-by: Bill Erickson --- Sip/Constants.pm | 3 +- Sip/MsgType.pm | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/Sip/Constants.pm b/Sip/Constants.pm index 9360039..245ac00 100644 --- a/Sip/Constants.pm +++ b/Sip/Constants.pm @@ -95,7 +95,7 @@ BEGIN { FID_RECALL_DATE FID_SECURITY_INHIBIT FID_MEDIA_TYPE FID_SORT_BIN FID_HOLD_PICKUP_DATE - FID_LOGIN_UID FID_LOGIN_PWD + FID_LOGIN_UID FID_LOGIN_PWD FID_OK FID_LOCATION_CODE FID_VALID_PATRON_PWD FID_PATRON_EXPIRE @@ -245,6 +245,7 @@ use constant { FID_HOLD_PICKUP_DATE => 'CM', FID_LOGIN_UID => 'CN', FID_LOGIN_PWD => 'CO', + FID_OK => '', FID_LOCATION_CODE => 'CP', FID_VALID_PATRON_PWD => 'CQ', diff --git a/Sip/MsgType.pm b/Sip/MsgType.pm index abdeec2..ddfaae0 100644 --- a/Sip/MsgType.pm +++ b/Sip/MsgType.pm @@ -94,6 +94,25 @@ my %handlers = ( }, } }, + (CHECKOUT_RESP) => { + name => "Checkout Response", + protocol => { + 2 => { + template => "A1A1A1A1A18", + template_len => 22, + fields => [(FID_INST_ID),(FID_PATRON_ID), + (FID_ITEM_ID),(FID_TITLE_ID), + (FID_DUE_DATE),(FID_FEE_TYPE), + (FID_SECURITY_INHIBIT),(FID_CURRENCY), + (FID_FEE_AMT),(FID_MEDIA_TYPE), + (FID_ITEM_PROPS),(FID_SCREEN_MSG), + (FID_PRINT_LINE)], + }, + + } + }, + + (CHECKIN) => { name => "Checkin", handler => \&handle_checkin, @@ -113,6 +132,18 @@ my %handlers = ( } } }, + (CHECKIN_RESP) => { + name => "Checkin Response", + protocol => { + 2 => { + template => "A1A1A1A1A18", + template_len => 22, + fields => [(FID_INST_ID),(FID_ITEM_ID),(FID_PERM_LOCN),(FID_TITLE_ID), + (FID_SORT_BIN),(FID_PATRON_ID),(FID_MEDIA_TYPE),(FID_ITEM_PROPS), + (FID_SCREEN_MSG),(FID_PRINT_LINE)], + } + } + }, (BLOCK_PATRON) => { name => "Block Patron", handler => \&handle_block_patron, @@ -159,6 +190,19 @@ my %handlers = ( } } }, + + (LOGIN_RESP) => { + name => "Login Response", + protocol => { + 2 => { + template => "A", + template_len => 1, + fields => [], + } + } + + }, + (PATRON_INFO) => { name => "Patron Info", handler => \&handle_patron_info, @@ -172,6 +216,20 @@ my %handlers = ( } } }, + + (PATRON_INFO_RESP) => { + name => "patron_info_resp", + protocol => { + 2 => { + template => "A14A3A18A4A4A4A4A4A4", + template_len => 59, + fields => [(FID_INST_ID), (FID_PATRON_ID), (FID_PERSONAL_NAME), (FID_HOLD_ITEMS_LMT), (FID_OVERDUE_ITEMS_LMT), (FID_CHARGED_ITEMS_LMT), (FID_VALID_PATRON), (FID_VALID_PATRON_PWD), (FID_CURRENCY), (FID_FEE_AMT), (FID_FEE_LMT), (FID_HOLD_ITEMS), (FID_OVERDUE_ITEMS), (FID_CHARGED_ITEMS), (FID_FINE_ITEMS), (FID_RECALL_ITEMS), (FID_UNAVAILABLE_HOLD_ITEMS), (FID_EMAIL), (FID_HOME_PHONE), (FID_SCREEN_MSG), (FID_PRINT_LINE)], + } + } + + }, + + (END_PATRON_SESSION) => { name => "End Patron Session", handler => \&handle_end_patron_session, @@ -210,6 +268,18 @@ my %handlers = ( } } }, + (ITEM_INFO_RESP) =>{ + name => "Item Information Response", + protocol => { + 2 => { + template => "A2A2A2A18", + template_len => 24, + fields => [(FID_HOLD_QUEUE_LEN),(FID_DUE_DATE),(FID_RECALL_DATE),(FID_HOLD_PICKUP_DATE),(FID_ITEM_ID),(FID_TITLE_ID), + (FID_OWNER),(FID_CURRENCY),(FID_FEE_AMT),(FID_MEDIA_TYPE),(FID_PERM_LOCN),(FID_CURRENT_LOCN),(FID_ITEM_PROPS),(FID_SCREEN_MSG),(FID_PRINT_LINE)], + } + } + }, + (ITEM_STATUS_UPDATE) => { name => "Item Status Update", handler => \&handle_item_status_update, @@ -250,6 +320,18 @@ my %handlers = ( } } }, + (HOLD_RESP) => { + name => "Hold Response", + protocol => { + 2 => { + template => "AAA18", + template_len => 20, + fields => [(FID_EXPIRATION), (FID_QUEUE_POS),(FID_PICKUP_LOCN),(FID_INST_ID),(FID_PATRON_ID),(FID_ITEM_ID),(FID_TITLE_ID),(FID_SCREEN_MSG),(FID_PRINT_LINE)], + } + } + }, + + (RENEW) => { name => "Renew", handler => \&handle_renew, @@ -290,7 +372,7 @@ foreach my $i (keys(%handlers)) { } sub new { - my ($class, $msg, $seqno) = @_; + my ($class, $msg, $seqno, $is_client) = @_; my $self = {}; my $msgtag = substr($msg, 0, 2); @@ -318,6 +400,7 @@ sub new { bless $self, $class; $self->{seqno} = $seqno; + $self->{is_client} = $is_client; $self->_initialize(substr($msg,2), $handlers{$msgtag}); return($self); @@ -357,10 +440,25 @@ sub _initialize { syslog("LOG_WARNING", "Unsupported field '%s' in %s message '%s'", $fn, $self->{name}, $msg); + } elsif (defined($self->{fields}->{$fn})) { - syslog("LOG_WARNING", - "Duplicate field '%s' (previous value '%s') in %s message '%s'", - $fn, $self->{fields}->{$fn}, $self->{name}, $msg); + + if ($self->{is_client}) { + # in client mode, it's not uncommon to receive repeating + # fields of data. E.g. list of hold items + + $self->{fields}->{$fn} = [$self->{fields}->{$fn}] + unless ref $self->{fields}->{$fn} eq 'ARRAY'; + + push (@{$self->{fields}->{$fn}}, substr($field, 2)); + + } else { + + #syslog("LOG_WARNING", + #"Duplicate field '%s' (previous value '%s') in %s message '%s'", + #$fn, $self->{fields}->{$fn}, $self->{name}, $msg); + } + } else { $self->{fields}->{$fn} = substr($field, 2); } -- 2.11.0