SIP Server as SIP client library user/berick/parse-client-responses
authorBill Erickson <berick@esilibrary.com>
Fri, 5 Apr 2013 18:14:27 +0000 (14:14 -0400)
committerBill Erickson <berick@esilibrary.com>
Fri, 5 Apr 2013 18:14:27 +0000 (14:14 -0400)
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 <berick@esilibrary.com>
Sip/Constants.pm
Sip/MsgType.pm

index 9360039..245ac00 100644 (file)
@@ -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',
 
index abdeec2..ddfaae0 100644 (file)
@@ -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);
        }