-- The protocol data unit (PDU) is the
-- message that is transmitted between receptionists and
-- collectionservers (colservers?).
--
-- Comments in ASN.1 start with two dashes and continue to the end
-- of a line (or to the next two dashes, whichever is first).
-- 
-- Z39.50 has inspired much of this but I have tried to keep
-- it simple. Its hard to tell if I have succeeded ;-)


GSDL-APDU DEFINITIONS ::=
BEGIN


-- PDU is the basic message type. Note: in ASN.1 the
-- field name comes first and the field type second (opposite
-- to C). Ignore the numbers in the square brackets (e.g. [0]),
-- they're just tags to disambiguate certain circumstances and to
-- make the protocol easier to extend. The keyword 'IMPLICIT' just
-- makes the tags a little more efficient.
--
-- A SEQUENCE is a list of fields where the order is important

PDU ::= SEQUENCE {
  header  StandardHeader,
  message Message
}


-- ????? Is there anything else we want in the header ?????
--
-- Anonymous transactions should leave out the idAuthentication field

StandardHeader ::= SEQUENCE {
  protocolVersion       [0] IMPLICIT INTEGER,
  idAuthentication      [1] IMPLICIT IdAuthentication OPTIONAL
}

IdAuthentication ::= SEQUENCE {
  userId   GeneralString,
  groupId  GeneralString,
  password GeneralString
}


-- A CHOICE is like a union in C.
-- 
-- Short forms: Auth (Authority), Mir (Mirror), Col (Collection),
--   Doc (Document), Info (Information)

Message ::= CHOICE {
  -- General
  error                      [0]  IMPLICIT Error,
  pingRequest                [1]  IMPLICIT PingRequest,
  pingResponse               [2]  IMPLICIT PingResponse,

  -- Authority
--  authListRequest            [12] IMPLICIT AuthListRequest,
--  authListResponse           [13] IMPLICIT AuthListResponse,
--  editAuthListRequest        [14] IMPLICIT EditAuthListRequest,
--  editAuthListResponse       [15] IMPLICIT EditAuthListResponse,

  -- an authority mirror is a mirror of THIS authority
--  authMirListRequest         [16] IMPLICIT AuthMirListRequest,
--  authMirListResponse        [17] IMPLICIT AuthMirListResponse,
--  editAuthMirListRequest     [18] IMPLICIT EditAuthMirListRequest,
--  editAuthMirListResponse    [19] IMPLICIT EditAuthMirListResponse,

  colListRequest             [20] IMPLICIT ColListRequest,
  colListResponse            [21] IMPLICIT ColListResponse,
--  editColListRequest         [22] IMPLICIT EditColListRequest,
--  editColListResponse        [23] IMPLICIT EditColListResponse,

--  colMirListRequest          [24] IMPLICIT ColMirListRequest,
--  colMirListResponse         [25] IMPLICIT ColMirListResponse, 
--  editColMirListRequest      [26] IMPLICIT EditColMirListRequest, 
--  editColMirListResponse     [27] IMPLICIT EditColMirListResponse,

  -- Collection
  colInfoRequest             [40] IMPLICIT ColInfoRequest,
  colInfoResponse            [41] IMPLICIT ColInfoResponse,

  -- Document
  documentRequest            [52] IMPLICIT DocumentRequest,
  documentResponse           [53] IMPLICIT DocumentResponse,

  -- Access (searching, browsing, and metadata information)
  infoFiltersRequest         [60] IMPLICIT InfoFiltersRequest,
  infoFiltersResponse        [61] IMPLICIT InfoFiltersResponse,
  infoFilterOptionsRequest   [62] IMPLICIT InfoFilterOptionsRequest,
  infoFilterOptionsResponse  [63] IMPLICIT InfoFilterOptionsResponse,
  filterRequest              [64] IMPLICIT FilterRequest,
  filterResponse             [65] IMPLICIT FilterResponse
}



-- ------------------------------
-- GENERAL
-- ------------------------------


-- The error list is not complete yet ...

Error ::= ENUMERATED {
  authenticationFailure(0), protocolError(1), systemProblem(2)
}


PingRequest ::= SEQUENCE {
}

PingResponse ::= SEQUENCE {
}



-- ------------------------------
-- AUTHORITY
-- ------------------------------


-- Support for subscription is optional for both the clients and
-- the servers. It is recomended that it is not implemented yet
-- for simplicity.

-- AuthListRequest ::= SEQUENCE {
-- }

-- AuthListResponse ::= SEQUENCE {
--   authList  [1] IMPLICIT StringSet
-- }


-- EditAuthListRequest ::= SEQUENCE {
--   editAction EditAction,
--   authority  GeneralString
-- }

-- EditAuthListResponse ::= SEQUENCE {
-- }


-- AuthMirListRequest ::= SEQUENCE {
--   limitNumber [1] IMPLICIT INTEGER OPTIONAL,
--   limitDomain [2] IMPLICIT GeneralString OPTIONAL
-- }

-- AuthMirListResponse ::= SEQUENCE {
--   authMirList [1] IMPLICIT HostPortSet
-- }


-- EditAuthMirListRequest ::= SEQUENCE {
--   editAction EditAction,
--   authMir    HostPort
-- }

-- EditAuthMirListResponse ::= SEQUENCE {
-- }


ColListRequest ::= SEQUENCE {
}

ColListResponse ::= SEQUENCE {
  colList   [1] IMPLICIT ShortColInfoSet
}


-- EditColListRequest ::= SEQUENCE {
--   editAction EditAction,
--   colInfo    ShortColInfo
-- }

-- EditColListResponse ::= SEQUENCE {
-- }


-- ColMirListRequest ::= SEQUENCE {
--   limitNumber [1] IMPLICIT INTEGER OPTIONAL,
--   limitDomain [2] IMPLICIT GeneralString OPTIONAL
-- }

-- ColMirListResponse ::= SEQUENCE {
--   colMirList [1] IMPLICIT ShortColInfoSet
-- }


-- EditColMirListRequest ::= SEQUENCE {
--   editAction EditAction,
--   colMirInfo ShortColInfo
-- }

-- EditColMirListResponse ::= SEQUENCE {
-- }




-- ------------------------------
-- COLLECTION
-- ------------------------------


ColInfoRequest ::= SEQUENCE {
}

ColInfoResponse ::= SEQUENCE {
  shortInfo   [0] IMPLICIT ShortCollectionInfo,
  isPublic    [2] IMPLICIT BOOLEAN,    -- whether has anonymous access
  isBeta      [3] IMPLICIT BOOLEAN,    -- beta if still under development
  builddate   [4] IMPLICIT GeneralizedTime,
  languages   [5] IMPLICIT StringSet,  -- languages in the collection
  numDocs     [6] IMPLICIT INTEGER,
  numWords    [7] IMPLICIT INTEGER OPTIONAL,
  numBytes    [8] IMPLICIT INTEGER OPTIONAL,
  useBook     [9] IMPLICIT BOOLEAN     -- whether to use book mode
}



-- ------------------------------
-- DOCUMENT
-- ------------------------------



DocumentRequest ::= SEQUENCE {
  OID       GeneralString,
  docType   GeneralString,
  docFormat GeneralString
}

DocumentResponse ::= SEQUENCE {
  doc OCTET STRING
}


-- ------------------------------
-- ACCESS (SEARCH AND BROWSE)
-- ------------------------------


-- filter options which might be supported for the QueryFilter
--
-- onePerQuery StartResults   integer
-- onePerQuery EndResults     integer
-- onePerQuery QueryType      enumerated (boolean, ranked)
-- onePerTerm  Term           string ???
-- onePerTerm  Casefold       boolean
-- onePerTerm  Stem           boolean
-- onePerTerm  Index          enumerated
-- onePerTerm  Subcollection  enumerated
--
-- filter options which might be supported for the BrowseFilter
--
-- onePerQuery StartResults   integer
-- onePerQuery EndResults     integer
-- onePerQuery ParentNode     string ("" will return the browsing available)
--
-- The NullFilter always returns the set it was given, it doesn't have
-- any options

InfoFiltersRequest ::= SEQUENCE {
}

InfoFiltersResponse ::= SEQUENCE {
  filterNames StringSet
}

InfoFilterOptionsRequest ::= SEQUENCE {
  filterName GeneralString
}

InfoFilterOptionsResponse ::= SEQUENCE {
  filterOptions SET OF FilterOption
}

FilterOption ::= SEQUENCE {
  name         GeneralString,
  type         ENUMERATED {booleant(0), integert(1), enumeratedt(2), stringt(3)},
  repeatable   ENUMERATED {onePerQuery(0), onePerTerm(1), nPerTerm(2)},
  defaultValue GeneralString,
  -- the interpretation of the validValues depends on the type
  -- for boolean: the first value is the false value, the second is true value
  -- for integer: the first value is the minimum, the second the maximum
  -- for enumerated: all values a listed
  -- for string: this value is ignored
  validValues  StringSequence
}


-- Terms are presented in the same order that they are requested,
-- any information relating to the terms is in reference to the
-- index specified for that term.
-- Metadata is presented in the same order that it is requested.

FilterRequest ::= SEQUENCE {
  filterName          [0] GeneralString,
  filterOptions       [1] IMPLICIT SEQUENCE OF OptionValue,
  docSet              [2] IMPLICIT StringSequence, -- the OID "" represents everything
  filterResultOptions [3] IMPLICIT BIT STRING {termFreq(0), matchTerms(1), OID(2), 
                                               subCol(3), ranking(4), docFreq(5), 
                                               metadata(6)}

  -- the next set of options are for the metadata request, 
  -- they can be left blank if metadata is not wanted
  requestParams       [4] IMPLICIT GeneralString, -- used to negotiate the metadata content
  refParams           [5] IMPLICIT GeneralString, -- used to decide whether to return a 
                                                  -- reference to the data or the actual data
  fields              [6] IMPLICIT StringSequence
}

OptionValue ::= SEQUENCE {
  name  GeneralString,
  value GeneralString
}

FilterResponse ::= SEQUENCE {
  numDocs   [0] IMPLICIT INTEGER,
  isApprox  [1] IMPLICIT BOOLEAN,                  -- whether numDocs is approximate
  termInfo  [2] IMPLICIT SEQUENCE OF TermInfo,     -- empty if not required
  docInfo   [3] IMPLICIT SEQUENCE OF ResultDocInfo -- empty if not required
}

TermInfo ::= SEQUENCE {
  term       [0] GeneralString,
  freq       [1] IMPLICIT INTEGER,       -- 0 if not requested
  matchTerms [2] IMPLICIT StringSequence -- empty if not requested
}

ResultDocInfo ::= SEQUENCE {
  OID      [0] IMPLICIT GeneralString,
  ranking  [1] IMPLICIT INTEGER,             -- 0 if not requested, range 0-10000
  docFreq  [2] IMPLICIT SEQUENCE OF INTEGER, -- empty if not requested
  metadata [3] IMPLICIT SEQUENCE OF MetadataInfo
}


MetadataInfo ::= SEQUENCE {
  params  [0] IMPLICIT GeneralString,
  isRef   [1] IMPLICIT BOOLEAN,
  field   [3] IMPLICIT GeneralString,
  value   [4] IMPLICIT GeneralString
}


-- ------------------------------
-- Useful Types
-- ------------------------------

-- HostPortSet ::= SET OF HostPort

-- HostPort ::= SEQUENCE {
--   host [0] IMPLICIT GeneralString,
--   port [1] IMPLICIT INTEGER
-- }

ShortColInfoSet ::= SET OF ShortColInfo

ShortColInfo ::= SEQUENCE {
  name GeneralString,
  host GeneralString,
  port INTEGER
}

-- EditAction ::= ENUMERATED {
--   update(0), delete(1)
-- }

StringSequence ::= SEQUENCE OF GeneralString
StringSet ::= SET OF GeneralString


END
