Guidance for the DAISY Online Delivery Protocol V2
Authors:
Dave Gunn, DAISY Consortium Consultant (Chair)
Jelle Martijn Kok, Solutions Radio
Claudio Montalban, Vision Australia (Editor)
Fredrik Schill, Textalk (Editor)
Per Sennels, Norwegian Library of Talking Books and Braille
Takuro Shiroki, Shinano Kenshi
Copyright Notice:
All content of the DAISY Structure Guidelines is licensed for others to copy, distribute, and display only verbatim copies. No changes may be made and no derivative works based upon it.
Copyright © by the DAISY Consortium, Creative Commons License: No Derivative Works
Table of Contents
- 1 Service Discovery
- 2 Reading System Configuration
- 3 Session management overview
- 4 Content Retrieval Sequence and Downloading and Streaming of Content
- 5 Service Announcements
- 6 Bookmarks
- 6.1 Introduction
- 6.2 Enabling Support for Bookmark Operations
- 6.3 The bookmarkObject
- 6.4 The bookmarkSet
- 6.5 Bookmark Set Elements
- 6.6 Reading System calling on getBookmarks
- 6.7 Service Response to getBookmarks
- 6.8 Reading System Setting a Bookmark Object
- 6.9 Service Response to Setting a Bookmark Object
- 7 Dynamic Menus
- 7.1 Introduction
- 7.2 Overview of dynamic menus
- 7.3 Log on
- 7.4 Example menu structure
- 7.4.1 Visual menu structure example
- 7.4.2 Text menu structure example
- 7.4.2.1 Root menu
- 7.4.2.2 Root menu response C-01 leads to sub menu Q-01
- 7.4.2.3 Sub menu response C-01-01 leads to end point
- 7.4.2.4 Sub menu response C-01-02 leads to sub menu Q-01-02-01
- 7.4.2.5 Sub menu response to Q-01-02-01 leads to end point
- 7.4.2.6 Sub menu response C-01-03 leads to sub menu Q-01-03-01
- 7.4.2.7 Sub menu response to Q-01-03-01 leads to end point
- 7.4.2.8 Root menu response C-02 leads to sub menu with questions Q-02-1, Q-02-2 and Q-02-3
- 7.4.2.9 Sub menu responses to Q-02-1, Q-02-2 and Q-02-3 lead to end point
- 7.5 getQuestions
- 7.6 Input questions
- 7.7 Content list
- 7.8 Add content to the bookshelf
- 7.9 Advanced Dynamic menu
- 7.10 Other Examples
1 Service Discovery
1.1 Introduction
Any DODP capable Service can register itself on the service discovery list. This list is maintained by the DAISY Consortium and is freely available. Every Service defines its name, url, country and other parameters.
A Reading System can use this list to give the end-user a list of Services to connect to. It is up to the Reading System to present this in a nice manner. It could first request a country or language to narrow the list.
The file is located at:
https://www.daisy.org/DODP/dodp-service-list.xml
1.2 Amending the Service Discovery System
To add or change your Service details on the Discovery file use the DAISY Contact form to request assistance, using the message category DAISY Online Delivery:
A member of the DAISY team will then make contact directly to request your correctly formatted Service details to add to the discovery file.
2 Reading System Configuration
2.1 Introduction
The operation getUserCredentials()
gives a Reading System the ability to fetch its username and password which it needs to login. For this to work the Service needs to assign a specific device (manufacturer and serial number) to a User. If that device requests the User credentials, the Service would return the username and password.
2.2 Security
Security is critical as the User credentials should not be handed out to any Reading System, only to one of the Reading Systems which are assigned by the User. For that reason the credentials will be encrypted before sending to the Reading System. Only Reading Systems which are assigned to the User will be able to decrypt the credentials. Other devices will not be able to decrypt the credentials. The method used is asymmetric encryption, where the Reading System has the private key and the Service has the public key.
2.2.1 Public keys
The public keys are distributed by the manufacturers. They are linked to the private keys which are stored inside the Reading Systems. Services can request this key via the publicKey
URL as specified in the readingSystemList
. This URL takes one GET/POST
parameter which is the serial number for the device. If no serial number is given, the public corporate key is returned.
For example, URLs may look like this:
https://keys.domain.com/api/public-keys.php?serial=12345-67890
https://keys.domain.com/api/public-keys.php
2.2.2 Private keys
The private keys are created and owned by the manufacturer. They are not shared with anyone and should be kept secret under all circumstances.
2.2.3 Encryption
Currently the only encryption used is “PCKS#1” with “RSAES-OAEP” padding. This is an asymmetric encryption which can encrypt a fixed amount of data. The maximum amount of text depends on the size of the used key. A key of 1024 bits can encrypt up to 86 bytes, 2048 can encrypt up to 214 bytes.
2.3 Step by step
2.3.1 Step 1
The Reading System performs a getUserCredentials()
request to the Service. This request holds the readingSystemAttributes
, which include the manufacturer and serial number.
2.3.2 Step 2
The Service extracts the manufacturer name and serial number from the getUserCredentials()
request. It looks up the manufacturer record from the centrally stored dodp-reading-system-list.xml
(hint: cache these daily). The Service then requests the public key from the URL specified in this manufacturer record.
2.3.3 Step 3
The Service encrypts the username and the password with the public key. As a result the username and password are in a binary format. Both encrypted username and encrypted password should be base64 encoded so they are suitable for placement inside the XML response.
2.3.4 Step 4
The Service creates the credentials response and stores the encrypted username and password as encoding in the correct place. The response is then sent to the Reading System.
2.3.5 Step 5
The Reading System reads the username and password from the response. They are encrypted and base64 encoded. The Reading System will base64 decode the username and password. It reads the encryptionScheme
to determine the encryption used. It will then try to decrypt the username and password with one of its private keys. It should first try its serial key, then its corporate key and lastly the example key.
2.3.6 Step 6
If successful, the Reading System uses this username and password to perform a logOn()
.
2.4 Amending the Reading System File
To add or amend your Reading System details on the Reading System List use the DAISY Contact form to request assistance, using the message category DAISY Online Delivery:
A member of the DAISY team will then make contact directly to request your correctly formatted Reading System details to add to the file.
2.5 Examples
In these examples we use the following public/private key pair. We call this key “DAISY-example”.
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXmtTTvovu9keHY//4RFoCuBmh
1UdEnDGsOef3543eABZz4lqr5QNO0ktfRg5kwheqVwZJHshYZuZzfgFOxVD8YlG4
F7kvhkNaC2M0XGM2BuQBgqrkOMB0EmhqBROP6tAQ4DLfTAm8FAo/rryrRoAejwxq
A8ZHdCZuINXTJluGcQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCXmtTTvovu9keHY//4RFoCuBmh1UdEnDGsOef3543eABZz4lqr
5QNO0ktfRg5kwheqVwZJHshYZuZzfgFOxVD8YlG4F7kvhkNaC2M0XGM2BuQBgqrk
OMB0EmhqBROP6tAQ4DLfTAm8FAo/rryrRoAejwxqA8ZHdCZuINXTJluGcQIDAQAB
AoGADGbE/CE9LyoEReX/PV7SAiDvL9bTgqBIS+9cs2HEsCFPtOESS7drItp/Aeco
LEPYTb3arMaQ2vJn7ZCkKL5pVmuzEvFXjO3vY0283U1xUdoevL/2yyHAM3l2dYbp
bvsPrWZhoa06mqcmN1d4XPKnLLrJzYOWDvlW7IXop6Y4EvECQQDJwHpY+bao5lE+
S7I3FnAzu6jUYA2VCTWDJVilX8sc/3OhONFlfAuv4gC2Yh+M4n8JhDZaKJ5q4Dbd
50jzSPJ9AkEAwF5/YneLUldjYZfpj/8dDBkSZ1qwB5kBpM0q/8UPassBVP00A3pa
4PCvxqhcsDPhnM9KX8N0D1f8fIM2vAoSBQJADW5l9sRxF591qysI60fwIlGM9M6M
OO7LBDcZRrEw6XZMMWCB+Dqg4I2wNHQl25A8mtqVb70ihsT0giNipOenVQJBALyp
cOEPQPJGhk8mf4gbuU8uH6CBjnZFFxmbpfomN9KSugGyOhrXGt3U728zm4Orvi7e
FaEJvX922Ub8IOgWMEkCQDAUHoY4SEZQPI9PpQrcJP87J4x3+8CfWni6SAWkuKUU
BsDoI6qtrBbVvkxx/wzv/i28scwKCj4enQkFbDWjPxg=
-----END RSA PRIVATE KEY-----
We will now describe the scenario where the device for a User requests the username and password. The username is “john.doe” and the password is “super-secret”
2.5.1 Example: The unencrypted response
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.daisy.org/ns/daisy-online/">
<soapenv:Body>
<credentials xmlns="http://www.daisy.org/ns/daisy-online/" >
<username>john.doe</username>
<password>super-secret</password>
</credentials>
</soapenv:Body>
</soapenv:Envelope>
2.5.2 Example: The encrypted response
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<credentials xmlns="http://www.daisy.org/ns/daisy-online/" encryptionScheme="RSAES-OAEP">
<username>kxUCZwu/1o2pzuiK2VQfQG46+Rd7uwbP2+BD7nuvps7TcFk1H3JkIo3/wjINaABEK/r9lqY8uozh44PuyRvI0LcqxI2BvYKtWsI2CsU2pojOZJJmq5yYP4xoOq8Y6SdMTSAtNCWIlLhKJwaMUyi9KlnnG3nl8cDTK8uQrbPI078=</username>
<password>C9vtkOagK3hS82W95bzvjKLSmvsV3N2vafqKp6mayPKqG+fCXRuT9d6qiAVv0LIuQN9k9idFc/nFAjYW3orEeTT7hU+iQmH1Az8UpqMHN54r0LjRaIVl8RyUKZcQpbMY4MTYGmSigZWrGe2RT4+puJDs2XCKx7AiVYJDkk3AS3Y=</password>
</credentials>
</soapenv:Body>
</soapenv:Envelope>
2.6 Command line encryption (Linux + openssl)
2.6.1 Private key generation
You can generate a 2048 bit RSA key with:
openssl genrsa -out private.pem 2048
WARNING: keep this key in a safe place and do not lose it.
2.6.2 Public key generation
You can extract the public key from the private key with:
openssl rsa -in private.pem -pubout > public.pem
The “public.pem” file now holds the public key. This file may be freely distributed.
2.6.3 Encrypt a password
echo -n "super-secret" | openssl rsautl -encrypt -oaep -pubin -inkey public.pem | base64 > encrypted.txt
2.6.4 Decrypt an encrypted password
cat encrypted.txt | base64 -d | openssl rsautl -decrypt -oaep -inkey private.pem
2.7 Example PHP code
The samples below should add more checks to determine if the encryption succeeds or fails. It is very important that the encryption function does this to prevent any leakage of unencrypted content. It should also be noted that the code should try to generate usable soap faults. (like “manufacturer not found”, “serial not located”, “encryption failed”, etc). And not just throw a “500” HTTP error.
2.7.1 Example: Service (library) code
<?
/* --- LIBRARY CODE --- */
/* In this example we use the default username and password */
$username = "default";
$password = "default";
/* Get the example public key
* NOTE: in production the Service should check the "manufacturer" field to use the correct key */
$key = openssl_pkey_get_public("file:///etc/ssl/DAISY-example.public.key");
if ($key) {
openssl_public_encrypt($username, $username_crypted, $key, OPENSSL_PKCS1_OAEP_PADDING);
$username_crypted = base64_encode($username_crypted);
openssl_public_encrypt($password, $password_crypted, $key, OPENSSL_PKCS1_OAEP_PADDING);
$password_crypted = base64_encode($password_crypted);
}
?>
2.7.2 Example: Reading System code
<?
/* --- READING SYSTEM CODE --- */
/* Perform the getUserCredentials() API call and read the encrypted and base64 encoded username and password */
$credentials = $daisy->getUserCredentials();
if ($credentials && $credentials['username'] && $credentials['password']) {
/* We use the example key for now */
$key = openssl_pkey_get_private("file:///etc/ssl/DAISY-example.private.key");
if ($key) {
$credentials['username'] = base64_decode($credentials['username']);
openssl_private_decrypt($credentials['username'], $username, $key, OPENSSL_PKCS1_OAEP_PADDING);
$credentials['password'] = base64_decode($credentials['password']);
openssl_private_decrypt($credentials['password'], $password, $key, OPENSSL_PKCS1_OAEP_PADDING);
}
}
?>
2.8 Some notes
- The key exchanges should be performed over https. This prevents a man in the middle attack which allows a malignant party to inject a fake key.
- It is likely and not less safe to use the public corporate key, as only devices of that manufacturer have that key.
- The Service may choose to use the example key to encrypt the credentials. This should be handled by all Reading Systems. It should be noted that this is not secure, but it can help during implementation and other circumstances.
- The “PCKS#1” with “RSAES-OAEP” padding can only encrypt a limited amount of text. It depends on the amount of bits in the public/private key. For this reason a minimum key length of 1024 is required. This allows for usernames and passwords of up to 86 characters.
3 Session management overview
3.1 Log on
A session starts with a successful logOn()
operation. What the Reading System wants to do after that depends on the capabilities of the Reading System, however all Reading Systems should be able to present content to the User.
3.2 Content
So, the common thing to do after the logOn()
operation is to perform the getContentList()
operation with the parameter for content list identifier set to “bookshelf”. This operation transfers information about the on-line bookshelf for the User from the Service to the Reading System as a contentList
. If the Reading System has a display, it will normally present the bookshelf to the User as a list of books. If the Reading System does not offer this, it will typically have a mechanism for presenting the book titles aurally.
What the Reading System will do after the getContentList()
operation depends on the type of Reading System as well as on the configuration of the Reading System.
The most likely actions are to:
- wait for a response from the User on which book to play or download; or to
- automatically start downloading books that are not already on the device.
In the first case, the Reading System will get the identifier of the required book from the contentList
and will perform the getContentResources()
operation for that identifier. At this point, the Reading System will offer information to the Service about what it wants to do with the content by use of the accessType
parameter to the getContentResources()
operation and the Service can then optimize the resources for the signaled activity.
In the second case, the Reading System will loop through the contentList
and for each item check if it is already downloaded. If not, the Reading System will perform a getContentResources()
operation with the proper content identifier and access type and start to download the resources offered from the Service.
When the Reading System receives the contentList
from the Service, the Reading System must also check if there are locally stored books that previously have been on the contentList
, but are not presented from the Service through the most updated contentList
. This means the loans have expired and the Reading System must delete the resources for any such books from the device.
3.3 Bookmarks
Reading Systems may offer bookmark handling as part of the reading experience. In addition, Reading Systems can also support storage of bookmarks on to the Service if this optional feature is available at the Service.
In this case, before the Reading System actually presents a specific content to the User, it can perform the getBookmarks()
operation to retrieve the set of bookmarks from the Service. This way the user experience will be that bookmarks and the last reading position for the books are maintained between reading sessions and cross devices.
For this to work properly, it is necessary that the Reading System updates the bookmarks on the Service at the end of reading sessions. This is managed with the updateBookmarks()
operation.
3.4 Announcements
A Service may also offer announcements to Reading Systems through the getServiceAnnouncements()
operation.
Reading Systems that supports announcements should check for new announcements at the very beginning of a Session and then present the announcements to the User through a suitable interface. After this, the Reading System should contact the Service for new announcements at regular intervals, as defined in the announcementsPullFrequency
element of the serviceAttributes
.
The Reading System should use the announcement’s priority to decide on the appropriate timing for presenting its information to the User.
3.5 Log off
When the Reading System has finished all synchronization with the Service, the session should always be gracefully ended by the Reading System performing the logOff()
operation.
4 Content Retrieval Sequence and Downloading and Streaming of Content
4.1 Introduction
When a valid session has been established, Content can be Downloaded or Streamed from the Service to the Reading System. This guidance serves to assist developers when setting up this communication.
In order to Download or Stream Content from a Service, a Reading System should perform the following:
- Get an updated list of the available Content items from the Service.
- Let the User select a Content item and an access type.
- Get the list of resources for the selected Content item.
- Perform the actual Download or begin Streaming and playback.
4.2 Content lists and the Bookshelf
The most common way for Reading Systems to synchronize the list of available Content items for the User is through the special Content list with the reserved id
"bookshelf"
. For simplicity, we refer to this Content list as the Bookshelf during this guidance.
Understanding Content lists in general and the Bookshelf in particular is vital to be able to perform correct Content synchronization. Before explaining the steps outlined above, we therefore here first highlight the most important aspects of Content lists.
4.2.1 Content lists
A Content list is a collection of Content items which is either the result to a direct call to the operation getContentList()
or the endpoint in a dynamic menu. Dynamic menues are explained in detail in other parts of the Guidance. The structure of Content lists are however the same for both cases.
The type for Content lists is contentList
and it has the following attributes:
id
totalItems
firstItem
lastItem
A contentList
may also have a label to be presented to the User by the Reading System.
There exists one reserved id
, the "bookshelf"
. Besides this, the Service can name identifiers for Content lists in the way it finds most appropriate.
The Service may return just a subset of the entire Content list to the Reading System, either for performance reasons on the Service or because the Reading System requested it to do so in the getContentList()
call. The attributes totalItems
, firstItem
and lastItem
communicates which subset of the total Content list a specific contentList
represents.
4.2.2 Content items
Each Content item in a contentList
is a contentItem
element. For a complete description on all properties and attributes for contentItem
, please see 7.14 in the DODP v2 specification. Here we will just highlight the most fundamental and important parts.
The following attributes are specified for a contentItem
:
id
firstAccessedDate
lastAccessedDate
lastModifiedDate
category
subCategory
returnBy
hasBookmarks
The id
attribute holds the Content Identifier of the Content item. There are no reserved values for it.
firstAccessedDate
and lastModifiedDate
is an indication to the Reading System whether this is a new Content item or if it has been consumed before.
lastModifiedDate
should be used by the Reading System to check if its stored resources for this Content item needs to be refreshed.
category
and subCategory
is a way to group Content items into an hierarchy of two levels.
If existing, the returnBy
attribute informs when this Content item must be returned and removed from the Reading System and a finally hasBookmarks
is a shortcut for Reading Systems that are interested in knowing if Content list items have bookmarks.
The following properties are specified for a contentItem
:
label
sample
metadata
categoryLabel
subCategoryLabel
accessPermission
lastmark
multipleChoiceQuestion
The label
is expected to be presented to the User by the Reading System and the sample
may contain a short appetizer for it to the User.
An important and significant update in DODP v2 as compared with DODP v1 is that the metadata
is available directly as a property on the contentItem
. This means that no extra call is required from the Reading System to the Service just to retrieve the metadata
. This is actually one of the most significant optimization improvements in DODP v2. The complete list of properties for metadata
can be found in 7.31 in the DODP v2 specification.
The categoryLabel
and subCategoryLabel
are User friendly labels for the corresponding attributes category
and subCategory
.
A contentItem
has one or more allowed access permissions which is set in its accessPermission
property. Possible permissions are streaming, download, restricted download and automatic download. The definition of all values for accessPermission
(the allowed combinations) and their descriptions can be found in 7.2 in the DODP v2 specification.
If available, lastmark
holds the last known reading position.
Finally, multipleChoiceQuestion
can be used in Content lists returned in dynamic menues and the multipleChoiceQuestion
of the contentItem
then represents the context menu for that Content item.
4.2.3 Example of a Content list
Taken from 6.4.1 in the DODP v2 specification, here is an example of a rather full Content list:
<contentList xmlns="http://www.daisy.org/ns/daisy-online/" id="cl123" totalItems="2">
<label xml:lang="en">
<text>Please select from these publications.</text>
<audio uri="http://example.com/static/PleaseChooseFrom.mp3" size="12342"/>
</label>
<contentItem id="com-example-001" category="BOOK" lastModifiedDate="2015-02-25T09:20:10Z">
<label xml:lang="en">
<text>Harry Potter and the Chamber of Secrets</text>
<audio uri="http://example.com/content/titles/hp_cs.mp3" size="130821"/>
</label>
<sample id="hp_cos-sample"/>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>Harry Potter and the Chamber of Secrets</dc:title>
<dc:identifier>com-example-hp_cos</dc:identifier>
<dc:format>Daisy 2.02</dc:format>
<dc:language>en-GB</dc:language>
<dc:description>Harry ignores warnings not to return to Hogwarts, only to find the school plagued by a series of mysterious attacks and a strange voice haunting him.</dc:description>
<narrator>Mary Svensson</narrator>
<size>8119213</size>
</metadata>
<accessPermission>STREAM_ONLY</accessPermission >
</contentItem>
<contentItem id="com-example-002" category="BOOK" lastModifiedDate="2015-02-26T13:20:10+06:00">
<label xml:lang="en">
<text>Harry Potter and the Goblet of Fire</text>
<audio uri="http://example.com/content/titles/hp_gf.mp3" size="130821"/>
</label>
<sample id="hp_cos-sample"/>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>Harry Potter and the Goblet of Fire</dc:title>
<dc:identifier>com-example-hp_cos</dc:identifier>
<dc:format>Daisy 2.02</dc:format>
<dc:language>en-GB</dc:language>
<dc:description>Harry ignores warnings not to return to Hogwarts, only to find the school plagued by a series of mysterious attacks and a strange voice haunting him.</dc:description>
<narrator>Mary Svensson</narrator>
<size>8119213</size>
<meta name="pdtb2:specVersion" content="2005-1" />
<meta name="cover" content="http://example.com/image.png" />
</metadata>
<accessPermission>STREAM_ONLY</accessPermission >
<multipleChoiceQuestion id="contentId_cl123">
<label>
<text>What would you like to do now?</text>
</label>
<choices>
<choice id="loanItem">
<label>
<text>Loan Book</text>
</label>
</choice>
<choice id="addToWishList">
<label>
<text>Add to Wish List</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</contentItem>
</contentList>
4.3 Get an updated list of the available Content items from the Service
Reading Systems are expected to keep a local cache of the Bookshelf in order to be able to present it to the User when the Reading System is off-line.
The latest version of the complete Bookshelf is requested by the Reading System by making the call getContentList("bookshelf", 0, -1)
.
Once received, the Reading System should inspect and compare the new Bookshelf with the previous, cached, version. There are a few key aspects for the Reading System to pay extra attention to:
- Content items that have an updated
returnBy
. Content items having the newreturnBy
in the past need to be returned by callingreturnContent()
for it. - Content items where
lastModifiedDate
has been updated. For those Content items the resources need to be retrieved again prior to playback. - Items that have disappeared in the new Bookshelf should no longer be presented to the User by the Reading System in the Bookshelf. All streamed or restricted downloaded resources for the Content item must be removed. Downloaded content that has been manually transferred to external media may continue to exist in that location.
- New Content items (where
firstAccessedDate
is omitted) should be indicated in a clear way in the Reading System, so that the User easily can find them.
4.4 Let the User select Content item and access type
The next step is for the Reading System to present the Bookshelf in a way so the User can get a good overview of the available Content items. The access permissions for each Content item should reflect which access types are available to the user for that Content item.
For example, when a Content item is available for both streaming and download, the User should have the possibility to choose which method to use.
4.5 Get the list of resources for a Content item
Once the user has made its selection, the Reading System needs to request information on the resources for the Content item from the Service unless the resources are already known to the Reading System due to an earlier access to that Content item.
To request the resources, the Reading System calls the operation getContentResources()
with the Content Identifier and the access type as the parameters.
Valid values for the access type are:
STREAM
DOWNLOAD
AUTOMATIC_DOWNLOAD
An important note to make here is that if the access type changes (for example from DOWNLOAD
to STREAM
) the Reading System must issue a new call to getContentResources()
since the resources may differ based on access type.
4.5.1 Resources
The result from the call to getContentResources()
has the type resources
, which has a single attribute lastModifiedDate
, which should reflect the last modified resource and should match the corresponding value in the contentItem
.
The resources
has one or more resource
sub elements.
The following attributes are specified for a resource
:
uri
mimeType
size
localURI
lastModifiedDate
serverSideHash
The resource
type has both a uri
and a localURI
attribute. localURI
is a local name for the Reading System to use to reference the resource, while uri
is the location of the resource’s data. This system lets a Service provide resources with arbitrary URIs (such as those served by a script), while allowing Reading Systems to follow internal links in a Content item, such as in a DAISY DTB. The localURI
path is relative to the root path of the Content item.
A Reading System should not use the uri
attribute to name resources locally, as the URIs may resolve to scripts or other content delivery mechanisms.
Reading Systems may use the MIME type information in the mimeType
attribute of a resource to order the transfer of resources. For example, a Streaming Reading System may retrieve the OPF, NCX and SMIL files of a DAISY Digital Talking Book to provide the User full navigation before downloading any audio data.
The size
attribute contains the size of the resource in bytes and the lastModifiedDate
indicates when this specific resource was last updated at the Service.
Finally, serverSideHash
is an optional server side hash of the resource.
The Service may freely choose which algorithm to use for calculating the serverSideHash
. It is required for the serverSideHash
to remain constant while the resource is unchanged and the same algorithm must be used for calculating the serverSideHash
for all resources.
By examining the localURI
, the lastModifiedDate
and the serverSideHash
attributes of resources combined, Reading Systems can identify duplicate resources for a Content item, provided by multiple calls to getContentResources()
, with various methodHint
parameters provided.
4.5.2 Packages
The resources
may also have zero or more package
sub elements.
The package
element contains 1 or more resourceRef
sub elements. For the resourceRef
sub elements, the localURI
should match the localURI
of a resource
, indicating that the matched resource can be found in the package.
The following attributes are specified for a package
:
uri
mimeType
size
lastModifiedDate
The uri
attribute contains the URI of a package in which the resource can be found.
The value of this attribute refers to a URI, which the Reading System may choose to download instead of the uri
attribute of the individual resources.
The Service thus has the possibility to group one or more resources into one package, such as all text resources of an audio book.
The mimeType
attribute indicates to the Reading System how to unpack the package.
The size
attribute contains the size of the package in bytes and the lastModifiedDate
indicates when this package was last updated at the Service.
4.5.3 Example of resources
Taken from 6.12.1 in the DODP v2 specification, here is an example of a resources instance where a few resources can also be downloaded as part of a package.
<resources xmlns="http://www.daisy.org/ns/daisy-online/" lastModifiedDate="2015-02-26T13:20:10+06:00" >
<resource mimeType="text/xml" size="123456" uri="https://example.com/content/get.php?a123891" localURI="package.opf" lastModifiedDate="2015-02-26T13:20:10+06:00" />
<resource mimeType="application/x-dtbncx+xml" size="123456" uri="https://example.com/content/get.php?a123892" localURI="nav.ncx" lastModifiedDate="2015-02-25T09:20:10Z" />
<resource mimeType="application/smil" size="567890" uri="https://example.com/content/get.php?a123893" localURI="chapter_1.smil" lastModifiedDate="2015-02-25T09:20:10Z" />
<resource mimeType="audio/mpeg" size="123456789" uri="https://example.com/content/get.php?a123894" localURI="chapter_1.mp3" lastModifiedDate="2015-02-25T09:20:10Z" />
<package mimeType="application/zip" size="987" uri="https://example.com/content/get.php?123" lastModifiedDate="2015-02-26T13:20:10+06:00">
<resourceRef localURI="package.opf" />
<resourceRef localURI="nav.ncx" />
<resourceRef localURI="chapter_1.smil" />
</package>
</resources>
4.6 Perform Download or begin Streaming and playback
When a Reading System attempts to Stream DAISY content, it should ensure files are retrieved in a logical order to prevent excessive calls and load on Services for retrieving non required files. For example the Reading System will access the NCC or NCX files, and by interrogating their contents determine the files that are needed to begin Streaming. This ensures that retrieving all resources is not required to begin Streaming.
A Reading System may wish to perform Automatic Download. It may do so by providing either DOWNLOAD_ONLY
, STREAM_AND_DOWNLOAD
, STREAM_AND_RESTRICTED_DOWNLOAD
or RESTRICTED_DOWNLOAD_ONLY
as the value for the accessConfig
in the readingSystemAttributes
.
Then any contentItem
returned from the Service having its accessPermission
set to either DOWNLOAD_ONLY_AUTOMATIC_ALLOWED
, STREAM_AND_DOWNLOAD_AUTOMATIC_ALLOWED
, STREAM_AND_RESTRICTED_DOWNLOAD_AUTOMATIC_ALLOWED
or RESTRICTED_DOWNLOAD_ONLY_AUTOMATIC_ALLOWED
is available for Automatic Download.
If the property progressStateOperationAllowed
in the serviceAttributes
is set to true
, the Reading System may call the operation setProgressState()
to indicate the state in which a current Streaming or Download operation for a Content item is in. The parameters to setProgressState()
are contentID
and state
.
Allowed values for the state
parameter are:
START
: A Download or Streaming is beginning which would result in resources returned bygetContentResources()
being accessed.PAUSE
: A Download or Streaming is being paused. This is valid from aSTART
state.RESUME
: A Download or Streaming is being resumed. This is valid from aPAUSE
state.FINISH
: A Download or Streaming is finished. This is valid from either aSTART
,PAUSE
orRESUME
state.
5 Service Announcements
5.1 Introduction
DODP2 provides support for sending short messages in text and/or audio form to inform Users of events. These could include informing the User about new titles available, overdue notices, or important messages such as server maintenance announcements.
DODP2 is a “Pull” protocol. Therefore it is not recommended for sending time critical messages (such as emergency announcements) as it is dependent on the Reading System to poll the Service and Pull the announcement based on a set “Pull Frequency”.
The Service Announcements Operation is optional. A server may choose not to implement the Operation, however its implementation is recommended as it allows efficient communication to Users via Reading Systems that support the Operation. It is a requirement that Reading Systems support this Operation.
5.2 Enabling Support for Service Announcements
A Service supporting Announcements must inform the Reading System by including in serviceAttributes
, an Operation element with the value of SERVICE_ANNOUNCEMENTS
.
Equally, a Service can indicate it does not support Announcements by not including the SERVICE_ANNOUNCEMENTS
value.
If a Service does not support Service Announcements, the Service must return an operationNotSupported
Fault when a Reading System calls getServiceAnnouncements()
.
5.2.1 Example: Service Attributes for a Service supporting Service Announcements
<serviceAttributes xmlns="http://www.daisy.org/ns/daisy-online/">
<serviceProvider id="gy-zenith" />
<service id="gy-zenith-libraryServiceDeluxe" />
<supportsServerSideBack>true</supportsServerSideBack>
<supportsSearch>true</supportsSearch>
<supportedUplinkAudioCodecs>
<codec>audio/mpeg</codec>
</supportedUplinkAudioCodecs>
<supportsAudioLabels>true</supportsAudioLabels>
<supportedOptionalOperations>
<operation>DYNAMIC_MENUS</operation>
<operation>SET_BOOKMARKS</operation>
<operation>GET_BOOKMARKS</operation>
<operation>SERVICE_ANNOUNCEMENTS</operation>
<operation>PDTB2_KEY_PROVISION</operation>
</supportedOptionalOperations>
<accessConfig>STREAM_AND_RESTRICTED_DOWNLOAD</accessConfig>
<announcementsPullFrequency>120</announcementsPullFrequency>
<progressStateOperationAllowed>true</progressStateOperationAllowed>
</serviceAttributes>
5.3 Announcements Pull Frequency
The announcementPullFrequency
value found in the serviceAttributes
informs the Reading System how often to pull Announcements from the Service. A Service may choose to enter a value of “0”, in which case the Reading System should only pull Announcements after logOn()
. The value is specified in minutes.
Services should consider the value of the announcementPullFrequency
. It is recommended not to make this value too frequent unless delivery of urgent messages is of paramount importance as this could lead to performance issues due to constant polling of the server as well as increased data traffic for the User. This is especially relevant for Reading Systems in mobile networks.
5.3.1 Example: serviceAttributes for a Service with announcementPullFrequency of 2 hours (120 minutes)
<serviceAttributes xmlns="http://www.daisy.org/ns/daisy-online/">
<serviceProvider id="gy-zenith" />
<service id="gy-zenith-libraryServiceDeluxe" />
<supportsServerSideBack>true</supportsServerSideBack>
<supportsSearch>true</supportsSearch>
<supportedUplinkAudioCodecs>
<codec>audio/mpeg</codec>
</supportedUplinkAudioCodecs>
<supportsAudioLabels>true</supportsAudioLabels>
<supportedOptionalOperations>
<operation>DYNAMIC_MENUS</operation>
<operation>SET_BOOKMARKS</operation>
<operation>GET_BOOKMARKS</operation>
<operation>SERVICE_ANNOUNCEMENTS</operation>
<operation>PDTB2_KEY_PROVISION</operation>
</supportedOptionalOperations>
<accessConfig>STREAM_AND_RESTRICTED_DOWNLOAD</accessConfig>
<announcementsPullFrequency>120</announcementsPullFrequency>
<progressStateOperationAllowed>true</progressStateOperationAllowed>
</serviceAttributes>
5.4 Reading System checking Announcements
A Reading System checks for new Announcements when connected to a Service by calling the getServiceAnnouncements()
Operation.
It is recommended that Reading Systems check for Announcements immediately after completing the initialization of a new Session and re-checks every X minutes according to the announcmentPullFrequency
.
A Reading System should not call the getServiceAnnouncements()
Operation if the Service does not have the SERVICE_ANNOUNCEMENTS
value in its serviceAttributes
.
5.4.1 Example: getServiceAnnouncements SOAP call
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.daisy.org/ns/daisy-online/IDAISYOnlineService/getServiceAnnouncements</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getServiceAnnouncements xmlns="http://www.daisy.org/ns/daisy-online/" />
</s:Body>
</s:Envelope>
5.5 Service Response
If there are no Announcements, the Service must respond with an empty Announcement list.
5.5.1 Example: Announcement
<announcements xmlns="http://www.daisy.org/ns/daisy-online/">
<announcement id="downtime" priority="HIGH" type="SYSTEM">
<label xml:lang="en">
<text>The Service will not be available for 30 minutes from 1:30pm today, Friday the 10th of September due to maintenance.</text>
<audio uri="http://example.com/content/messages/current.mp3" rangeBegin="0" rangeEnd="65856" size="65856"/>
</label>
</announcement>
<announcement id="survey" priority="MEDIUM" type="INFORMATION">
<label xml:lang="en">
<text>A new survey is available, fill it in online at our home page, or use your Daisy Online Reading System if it has the required capabilities. Chance to win a Phantom Pocket Reader!</text>
<audio uri="http://example.com/content/messages/current.mp3" rangeBegin="65857" size="92112"/>
</label>
</announcement>
</announcements>
5.5.2 Example: Empty Service Announcement SOAP response
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="683a3f7c-6787-4fe3-97b6-72d563635c7a" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">922f0811-e889-4422-8a83-83090d7ebe0e</ActivityId>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getServiceAnnouncementsResponse xmlns="http://www.daisy.org/ns/daisy-online/">
<announcements />
</getServiceAnnouncementsResponse>
</s:Body>
</s:Envelope>
5.6 Announcement Attributes
Announcements may contain the following attributes. This document will refer to the example in the previous section to describe the different attributes available.
5.6.1 Announcement id
The id
attribute is required and valid only for the current session. This is the identifier of the Announcement.
A Service may remove unread Announcements from the Service at any time and for any reason. To avoid potential retrieval conflicts, a Reading System must treat the Announcement ids as valid only for the duration of the active Session.
5.6.2 Announcement Type
The Announcement type indicates the kind of Announcement being sent to the Reading System. Announcement types are optional and have a default value of INFORMATION
.
The possible Announcement types are:
INFORMATION
Service news, general “non actionable” information. This will be the most common type of Announcement for general information, more often this type would have priority values ofLOW
orMEDIUM
.SYSTEM
Actionable information for the User, for example account, Service outages or imminent book expiry or overdue, more often this type would have a priority value ofHIGH
orMEDIUM
.
5.6.3 Announcement Priority
The Announcement priority informs the Reading System of the immediacy with which the Announcement should be rendered. It is a required attribute with a default value of LOW
.
Following are the possible Announcement priority types as well as examples of how Reading Systems may interpret the Announcement priority to render them to the User:
HIGH
Immediately interrupt all current activities (including audio playback) and automatically render the Announcement to the User.MEDIUM
Wait until the current activity (e.g. streaming a file) is finished and then automatically render the Announcement to the User.LOW
Next time the Reading System is idle (e.g. pause mode) it will render the Announcement to the User.
In all cases a Reading System must present the Announcement in a way that enables the User to re-read the Announcement.
5.6.4 Example: XML Fragment containing Announcement id, type and priority
<announcement id="downtime" priority="HIGH" type="SYSTEM">
5.7 Announcements with Audio files
Announcements may contain audio files. Services in countries where TTS doesn’t correctly render their native language are advised to attach such a file.
The use of audio files is optional. When attaching audio Announcements Services should also be mindful of the load on the Service, Reading Systems, as well as bandwidth that particularly affects Users of mobile networks.
The Audio element is used to contain the URI to the audio file as well as the attributes.
5.7.1 Example: XML Fragment containing Audio Element
<announcement id="downtime" priority="HIGH" type="SYSTEM">
<label xml:lang="en">
<text>The Service will not be available for 30 minutes from 1:30pm today, Friday the 10th of September due to maintenance.</text>
<audio uri="http://example.com/content/messages/current.mp3" rangeBegin="0" rangeEnd="65856" size="65856"/>
</label>
</announcement>
5.8 Attributes of the Audio element
The Audio element may contain the following attributes. This document will refer to the example in the previous section to describe the different attributes available.
5.8.1 Audio uri
This is the URI of the audio file containing the Announcement the Reading System should render to the User. This attribute is required..
5.8.2 Audio rangeBegin
The Audio rangeBegin
attribute is the byte offset of the start of the audio resource named in the uri
attribute. If the rangeBegin
attribute is not present, the start offset is 0. This attribute is optional.
5.8.3 Audio rangeEnd
The Audio rangeEnd
attribute is the byte offset of the end of the audio resource named in the uri
attribute. If the rangeEnd
attribute is not present, the end is the last byte of the resource. This attribute is optional.
5.8.4 Audio size
The Audio size
attribute is the size in bytes of the audio resource named in the uri
attribute.
5.9 Mark Announcement as read
After rendering Announcements to a User, a Reading System may call the markAnnouncementsAsRead()
Operation to inform the Service the Announcement has been read and should not be sent again on the next getServiceAnnouncements()
call.
A Reading System could choose to present the option to the User to mark an Announcement as read via the UI and immediately delete the Announcement from the Reading System. In this case the Reading System should make it clear to the User the Announcement is being deleted.
Equally a Reading System could choose to mark the Announcement as read after it’s rendered and present the User the option to delete it via the UI, if choosing this option the Reading System should be responsible for caching the Announcement.
To prevent conflicts arising from Announcements that have been removed from the Service, a Reading System must only pass identifier values obtained from the last call to getServiceAnnouncements()
during the active Session to markAnnouncementsAsRead()
.
A Reading System may mark more than one Announcement as read in the same call to markAnnouncementsAsRead()
. If an invalidParameter
Fault is returned, the Reading System must call markAnnouncementsAsRead()
sequentially for each Announcement to determine which identifier caused the Fault.
The markAnnouncementsAsRead Operation contains the read
parameter and the item
element.
The Service response will be a boolean where true
means the Announcement was successfully marked as read, otherwise the Service must return a Fault. The Service must not return false
.
The Service must return true
if the Announcement was previously returned in the current session.
5.9.1 Example: Announcement list showing 2 Announcements
<announcements>
<announcement id="891" priority="HIGH">
<label xml:lang="en">
<text>Test Announcement 1</text>
</label>
</announcement>
<announcement id="892" priority="HIGH">
<label xml:lang="en">
<text>Test Announcement 2</text>
</label>
</announcement>
</announcements>
5.9.2 Example: SOAP call to markAnnouncementsAsRead
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.daisy.org/ns/daisy-online/IDAISYOnlineService/markAnnouncementsAsRead</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<markAnnouncementsAsRead xmlns="http://www.daisy.org/ns/daisy-online/">
<read>
<item>891</item>
</read>
</markAnnouncementsAsRead>
</s:Body>
</s:Envelope>
5.9.3 Example: Service SOAP Response
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="330549e6-c2a3-4347-b21a-5aa02ab34c7b" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">2ed3db37-06c3-4b08-85f5-148991ca160c</ActivityId>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<markAnnouncementsAsReadResponse xmlns="http://www.daisy.org/ns/daisy-online/">
<markAnnouncementsAsReadResult>true</markAnnouncementsAsReadResult>
</markAnnouncementsAsReadResponse>
</s:Body>
</s:Envelope>
5.9.4 Example: Announcement xml fragment response to getServiceAnnouncements after markAnnouncementsAsRead
<announcements>
<announcement id="892" priority="HIGH">
<label xml:lang="en">
<text>Test Announcement 2</text>
</label>
</announcement>
</announcements>
6 Bookmarks
6.1 Introduction
DODP2 provides Operations to support the storage of bookmarks, highlights and last marks (last reading position on the title) on the Service, which allows Users to synchronize these across multiple devices.
Bookmarks, highlights and last marks are contained in an xml fragment referred to as bookmarkSet
. The bookmarks grammar used in the protocol is defined by the Portable Bookmarks and Highlights section of the DAISY 3, Release 2005 ANSI/NISO Z39.86-2005 specification.
Reading Systems may store bookmark sets in a Service that supports them by the updateBookmarks()
operation; Reading Systems can retrieve stored bookmarks with the getBookmarks()
Operation. Services can also predefine bookmarks for the User to access.
The bookmarks Operations are optional. A Service may wish not to implement the Operations, however their implementation is recommended as it allows Users with multiple devices to preserve their bookmark set, enabling them to for example continue reading a book on a different device from the last reading position. It is a requirement that Reading Systems support this Operation.
6.2 Enabling Support for Bookmark Operations
A Service may support the retrieval of bookmark sets or both the setting and retrieval of bookmark sets.
A Service supporting setting of bookmark sets must inform the Reading System by including an Operation element with the value of SET_BOOKMARKS
in its serviceAttributes
as a response to logOn()
, a Service supporting the retrieval of bookmark sets must include the GET_BOOKMARKS
value in its response.
Equally, a Service can indicate it does not support one or both Operations by not including the SET_BOOKMARKS
and or GET_BOOKMARKS
values.
If a Service does not support bookmark Operations, the Service must return an operationNotSupported
Fault when a Reading System calls getBookmarks()
or updateBookmarks()
.
6.2.1 Example: Service Attributes for a Service supporting both bookmark Operations.
<serviceAttributes xmlns="http://www.daisy.org/ns/daisy-online/">
<serviceProvider id="gy-zenith" />
<service id="gy-zenith-libraryServiceDeluxe" />
<supportsServerSideBack>true</supportsServerSideBack>
<supportsSearch>true</supportsSearch>
<supportedUplinkAudioCodecs>
<codec>audio/mpeg</codec>
</supportedUplinkAudioCodecs>
<supportsAudioLabels>true</supportsAudioLabels>
<supportedOptionalOperations>
<operation>DYNAMIC_MENUS</operation>
<operation>SET_BOOKMARKS</operation>
<operation>GET_BOOKMARKS</operation>
<operation>SERVICE_ANNOUNCEMENTS</operation>
<operation>PDTB2_KEY_PROVISION</operation>
</supportedOptionalOperations>
<accessConfig>STREAM_AND_RESTRICTED_DOWNLOAD</accessConfig>
<announcementsPullFrequency>120</announcementsPullFrequency>
<progressStateOperationAllowed>true</progressStateOperationAllowed>
</serviceAttributes>
6.3 The bookmarkObject
The bookmarkObject
contains the bookmarkSet
, in addition is has an optional attribute with the last modified date and time zone, these attribute enables support for multiple devices setting bookmarks.
When a Reading System receives a bookmark set that is older than its internal bookmark set, it should update the Service bookmark set with its internal copy, where a Reading System receiving a newer bookmark set should update its internal bookmark set with the one received from the Service.
The additional information is also important for supporting setting bookmarks in offline mode, for this reason a Reading System should always update and not entirely replace its internal bookmark set with the bookmark set received from the Service.
6.4 The bookmarkSet
The bookmarkSet
is described in the Portable Bookmarks and Highlights section of the DAISY 3, Release 2005 ANSI/NISO Z39.86-2005 specification.
A bookmarkSet
may contain one or more bookmarks, highlights and a last mark.
Bookmark sets contain different elements depending on the type of Content Item they refer to, for instance Audio only Items will express a bookmark based on the time offset for the point referenced to a SMIL, while a Text only Item will express it in a character offset. Text and Audio Items will contain both.
6.4.1 Example: Bookmark Set containing examples of all types of Bookmarks on an Audio Only Item
<bookmarkSet xmlns="http://www.daisy.org/z3986/2005/bookmark/">
<title>
<text>Gone with the Wind</text>
<audio src="gwtw_title.mp3" />
</title>
<uid>us-rfbd-JT065</uid>
<lastmark>
<ncxRef>gwtw.ncx#lvl1_5</ncxRef>
<URI>gwtw_ch5.smil#para023</URI>
<timeOffset>03:52.00</timeOffset>
</lastmark>
<bookmark>
<ncxRef>gwtw.ncx#lvl1_1</ncxRef>
<URI>gwtw_ch1.smil#para008</URI>
<timeOffset>00:22.00</timeOffset>
</bookmark>
<bookmark>
<ncxRef>gwtw.ncx#lvl1_3</ncxRef>
<URI>gwtw_ch3.smil#para012</URI>
<timeOffset>01:28.00</timeOffset>
<note>
<text>Atlanta burns.</text>
</note>
</bookmark>
<hilite>
<hiliteStart>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para001</URI>
<timeOffset>00:00.00</timeOffset>
</hiliteStart>
<hiliteEnd>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para006</URI>
<timeOffset>04:06.00</timeOffset>
</hiliteEnd>
</hilite>
</bookmarkSet>
6.4.2 Example: Bookmark Set containing a lastmark on a Text Only Item
<bookmarkSet xmlns="http://www.daisy.org/z3986/2005/bookmark/">
<title>
<text>Chemistry Today</text>
</title>
<uid>uk-rnib-MM499</uid>
<lastmark>
<ncxRef>chemtd.ncx#lvl1_3</ncxRef>
<URI>chemtd.smil#para297</URI>
<charOffset>130</charOffset>
</lastmark>
</bookmarkSet>
6.4.3 Example: Bookmark Set containing a lastmark on a Text and Audio Item
<bookmarkSet xmlns="http://www.daisy.org/z3986/2005/bookmark/">
<title>
<text>Physics Yesterday</text>
</title>
<uid>uk-rnib-MM498</uid>
<lastmark>
<ncxRef>physyd.ncx#lvl1_5</ncxRef>
<URI>physyd.smil#para_573</URI>
<timeOffset>02:01.00</timeOffset>
<charOffset>250</charOffset>
</lastmark>
</bookmarkSet>
6.5 Bookmark Set Elements
A bookmarkSet
may contain the following elements. This document will refer to the example in the previous section to describe the different elements available.
6.5.1 title
Contains the title, in text and in an optional audio clip, of the Content Item for which the bookmark set was created.
6.5.1.1 Example: XML Fragment containing title
<title>
<text>Gone with the Wind</text>
<audio src="gwtw_title.mp3" />
</title>
6.5.2 text
Text of the Title
6.5.2.1 Example: XML Fragment containing title text
<title>
<text>Gone with the Wind</text>
<audio src="gwtw_title.mp3" />
</title>
6.5.3 audio
The audio clip for title of the Content Item, specified in any format supported.
6.5.3.1 Attributes
src
(%URI, #REQUIRED): The src attribute holds the URI of the audio file that contains the referenced clip.
clipBegin
(%SMILtimeVal, IMPLIED): The clipBegin attribute specifies the beginning of a segment of a continuous media object as a time offset from the start of the media object. The value syntax is defined by the SMIL 2.0 Timing and Synchronization Module [SMIL].
clipEnd
(%SMILtimeVal, IMPLIED): The clipEnd attribute specifies the end of a segment of a continuous media object as a time offset from the start of the media object. It uses the same attribute value syntax as clipBegin.
6.5.3.2 Example: XML Fragment containing audio text
<title>
<text>Gone with the Wind</text>
<audio src="gwtw_title.mp3" />
</title>
6.5.4 uid
The globally unique identifier for the book, drawn from the package file. Matches the dc:Identifier
referenced by the unique-identifier
attribute on the package file’s package element.
6.5.4.1 Example: XML Fragment containing title uid
<uid>us-rfbd-JT065</uid>
6.5.5 lastmark
Location where User most recently ceased reading and where player will resume play when restarted. Location consists of a URI pointing to the id attribute of the par
or seq
element in the SMIL file that contains the lastmark, plus a time offset and/or character offset to the exact point.
6.5.5.1 Example: XML Fragment containing title lastmark
<lastmark>
<ncxRef>gwtw.ncx#lvl1_5</ncxRef>
<URI>gwtw_ch5.smil#para023</URI>
<timeOffset>03:52.00</timeOffset>
</lastmark>
6.5.6 ncxRef
Captures current location in NCX (the id of the current navPoint) at time lastmark, bookmark, or highlight is set. Ensures that current location in NCX and SMIL are synchronized after moving to a lastmark, bookmark, or highlight so that any global navigation commands issued by the User will start from the current location.
6.5.6.1 Example: XML Fragment containing the ncxRef
<lastmark>
<ncxRef>gwtw.ncx#lvl1_5</ncxRef>
<URI>gwtw_ch5.smil#para023</URI>
<timeOffset>03:52.00</timeOffset>
</lastmark>
6.5.7 URI
Pointer to id of par
or seq
in SMIL that contains the lastmark
, bookmark
, hiliteStart
, or hiliteEnd
.
6.5.7.1 Example: XML Fragment containing the URI
<lastmark>
<ncxRef>gwtw.ncx#lvl1_5</ncxRef>
<URI>gwtw_ch5.smil#para023</URI>
<timeOffset>03:52.00</timeOffset>
</lastmark>
6.5.8 timeOffset
Exact position of lastmark
, bookmark
, hiliteStart
, or hiliteEnd
in the sequential audio presentation; a non-negative clock value, relative to the start of the SMIL time container referenced in the URI.
6.5.8.1 Example: XML Fragment containing the time offset
<lastmark>
<ncxRef>gwtw.ncx#lvl1_5</ncxRef>
<URI>gwtw_ch5.smil#para023</URI>
<timeOffset>03:52.00</timeOffset>
</lastmark>
6.5.9 charOffset
Exact position of bookmark
, lastmark
, hiliteStart
, or hiliteEnd
in textual content file referenced (via SMIL) by the URI.
6.5.9.1 Example: XML Fragment containing the char offset
<lastmark>
<ncxRef>chemtd.ncx#lvl1_3</ncxRef>
<URI>chemtd.smil#para297</URI>
<charOffset>130</charOffset>
</lastmark>
6.5.10 bookmark
Point in document marked by User for direct access in future. Bookmark consists of location and optional note. Location consists of a URI pointing to the id attribute of the par
or seq
element in the SMIL file that contains the bookmark, plus a time offset and/or character offset to the exact point.
6.5.10.1 Attributes
label
(CDATA, #IMPLIED): optional attribute for use in storing identifying label to assist User in choosing among a set of bookmarks.
xml:lang
(%languagecode, #IMPLIED): optional attribute for use in identifying the language of label and note for this bookmark, using an [RFC 3066] language code.
6.5.10.2 Example: XML Fragment containing a Bookmark
<bookmark>
<ncxRef>gwtw.ncx#lvl1_1</ncxRef>
<URI>gwtw_ch1.smil#para008</URI>
<timeOffset>00:22.00</timeOffset>
</bookmark>
6.5.11 hilite
A block of text marked by the User with an optional note attached.
6.5.11.1 Attributes
label
(CDATA, #IMPLIED): optional attribute for use in storing identifying label to assist User in choosing among a set of highlights.
6.5.11.2 Example: XML Fragment containing a Highlight
<hilite>
<hiliteStart>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para001</URI>
<timeOffset>00:00.00</timeOffset>
</hiliteStart>
<hiliteEnd>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para006</URI>
<timeOffset>04:06.00</timeOffset>
</hiliteEnd>
</hilite>
6.5.12 hiliteStart
The starting point of highlighted block. Location consists of a URI pointing to the id attribute of the par
or seq
element in the SMIL file that contains the beginning of the highlighted section, plus a time offset and/or character offset to the exact point.
6.5.12.1 Example: XML Fragment containing a Highlight Start
<hilite>
<hiliteStart>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para001</URI>
<timeOffset>00:00.00</timeOffset>
</hiliteStart>
<hiliteEnd>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para006</URI>
<timeOffset>04:06.00</timeOffset>
</hiliteEnd>
</hilite>
6.5.13 hiliteEnd
End of highlighted block. Location consists of a URI pointing to the id attribute of the par
or seq
element in the SMIL file that contains the end of the highlighted section, plus a time offset and/or character offset to the exact point.
6.5.13.1 Example: XML Fragment containing a Highlight End
<hilite>
<hiliteStart>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para001</URI>
<timeOffset>00:00.00</timeOffset>
</hiliteStart>
<hiliteEnd>
<ncxRef>gwtw.ncx#lvl1_4</ncxRef>
<URI>gwtw_ch4.smil#para006</URI>
<timeOffset>04:06.00</timeOffset>
</hiliteEnd>
</hilite>
6.6 Reading System calling on getBookmarks
A Reading System can retrieve a bookmark set using the getBookmarks()
Operation.
The actions that can be performed by getBookmarks()
are:
LASTMARK
Retrieves the lastmark only.HILITE
Retrieves all hilites only.BOOKMARK
Retrieves all bookmarks only.ALL
Retrieves all bookmarks including those of type lastmark, hilite and bookmark.
6.6.1 Example: SOAP call getBookmarks
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.daisy.org/ns/daisy-online/IDAISYOnlineService/getBookmarks</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getBookmarks xmlns="http://www.daisy.org/ns/daisy-online/">
<contentID>49219</contentID>
<action>ALL</action>
</getBookmarks>
</s:Body>
</s:Envelope>
6.7 Service Response to getBookmarks
The Service will return a bookmarkSet
.
6.7.1 Example: SOAP Response to getBookmarks call
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="4920da1a-07ee-4d8b-a5c1-1a6c71bc6935" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">a77bc6a6-b095-4e98-8a06-3722f060c989</ActivityId>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getBookmarksResponse xmlns="http://www.daisy.org/ns/daisy-online/">
<bookmarkObject>
<bookmarkSet xmlns="http://www.daisy.org/z3986/2005/bookmark/">
<title>
<text>Bookmark List</text>
</title>
<hilite>
<hiliteStart>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
<timeOffset>1.x.10</timeOffset>
</hiliteStart>
<hiliteEnd>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
<timeOffset>1.x.20</timeOffset>
</hiliteEnd>
<note />
</hilite>
<bookmark>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
<timeOffset>1.x.10</timeOffset>
<note />
</bookmark>
</bookmarkSet>
</bookmarkObject>
</getBookmarksResponse>
</s:Body>
</s:Envelope>
6.8 Reading System Setting a Bookmark Object
A Reading System can set, update or delete elements of a bookmark set using the updateBookmarks()
Operation.
The actions that can be performed by updateBookmarks()
are:
REPLACE_ALL
Service entirely replaces the User’s bookmarks for this Content item with this new bookmarkObject.ADD
The Service adds the elements in this bookmarkObject to the User’s bookmarks for this Content item. Any duplicate bookmarks are updated.REMOVE
The Service removes the elements in this bookmarkObject from the User’s bookmarks for this Content item.
A Reading System should only use REPLACE_ALL
when the internal Bookmark Set has recently been updated to ensure it does not miss potential updates to the bookmark set made by other Reading Systems on the same Content Item.
The REMOVE
function can be used to remove individual marks without having to pass the entire bookmark set; typically this would be used when the User manually removes a bookmark from the active Content Item.
6.8.1 Example: updateBookmarks SOAP call REPLACE_ALL
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.daisy.org/ns/daisy-online/IDAISYOnlineService/updateBookmarks</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<updateBookmarks xmlns="http://www.daisy.org/ns/daisy-online/">
<contentID>49219</contentID>
<action>REPLACE_ALL</action>
<bookmarkObject>
<bookmarkSet xmlns="http://www.daisy.org/z3986/2005/bookmark/">
<title>
<text>Sample Bookmark Set</text>
</title>
<lastmark>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
</lastmark>
<bookmark>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
<timeOffset>1.x.10</timeOffset>
</bookmark>
<hilite>
<hiliteStart>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
<timeOffset>1.x.10</timeOffset>
</hiliteStart>
<hiliteEnd>
<ncxRef>TestNCX</ncxRef>
<URI>TestURI</URI>
<timeOffset>1.x.20</timeOffset>
</hiliteEnd>
</hilite>
</bookmarkSet>
</bookmarkObject>
</updateBookmarks>
</s:Body>
</s:Envelope>
6.9 Service Response to Setting a Bookmark Object
The Service will return a boolean response to indicate if it has successfully updated the bookmark set.
6.9.1 Example: SOAP Response to updateBookmarks call
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="61811e1f-28fc-421e-90c5-ae6ad3297348" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">cd82c796-427a-4f37-98f1-87c860580761</ActivityId>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<updateBookmarksResponse xmlns="http://www.daisy.org/ns/daisy-online/">
<updateBookmarksResult>true</updateBookmarksResult>
</updateBookmarksResponse>
</s:Body>
</s:Envelope>
7 Dynamic Menus
7.1 Introduction
Dynamic menus provide support for custom menus defined by the Service that can be rendered by the Reading System for such purposes as search, configuration and any other menu structure required by a library service.
This document provides guidance on how to use the DAISY online dynamic menu system. By working through the included examples you will gain an understanding of how to define dynamic menus including the associated interaction between the Reading System and Service.
This document covers not only the internals of the dynamic menu system, but also session initialization and the content item acquisition steps resulting from a book search menu.
7.2 Overview of dynamic menus
Usage of dynamic menu is separated into three typical stages.
- Log on
During thelogOn
operation, the Service and the Reading System exchange information about the capabilities of each. The Reading System informs the Service what kind of dynamic menus are supported by the Reading System and the Service informs the Reading System if the Service supports dynamic menus or not. getQuestions
ThegetQuestions
operation is used by a Reading System to retrieve the choices or questions from the Service to be rendered to the User. Note that dynamc menus support both input fields and choice fields, i.e. a dynamic menu can capture data from the User (such as a data entry form) or simply act like a menu using the choice type. A response to a given dynamic menu can then be passed togetQuestions
again where the Service, based on this response, may respond with another dynamic menu to be rendered resulting in support for hierarchic menus.- Actions as the result of menu choices
The menus may support many levels but eventually this will lead to either acontentList
orlabel
end point. This represents the result of the menu selection. For example, thelabel
may contain a message such as “the book has been added to the bookshelf” or “user configuration updated successfully”.
7.3 Log on
7.3.1 readingSystemAttributes
Reading Systems must inform the DAISY Online Service about its user interface capabilities using the following switches.
supportsMultipleSelections
informs the Service the Reading System is able to select multiple choices for a singlemultipleChoiceQuestion
. In this example, this option is set tofalse
.supportsAdvancedDynamicMenus
informs the Service the Reading System supports questions attached to the contentItem.supportedInputTypes
informs the Service about which input types are supported by the Reading System.
7.3.1.1 Example: readingSystemAttributes
<readingSystemAttributes xmlns="http://www.daisy.org/ns/daisy-online/">
<manufacturer>ACME Corporation</manufacturer>
<model>Pro Phantom III</model>
<serialNumber>64321</serialNumber>
<version>1.23</version>
<config>
<accessConfig>STREAM_ONLY</accessConfig >
<supportsMultipleSelections>false</supportsMultipleSelections>
<supportsAdvancedDynamicMenus>false</supportsAdvancedDynamicMenus>
<preferredUILanguage>en</preferredUILanguage>
<supportedContentFormats>
<contentFormat>ANSI/NISO Z39.86-2005</contentFormat>
<contentFormat>Daisy 2.02</contentFormat>
</supportedContentFormats>
<supportedContentProtectionFormats />
<supportedMimeTypes>
<mimeType type="text/plain" xml:lang="en"/>
<mimeType type="audio/mpeg"/>
</supportedMimeTypes>
<supportedInputTypes>
<input type="TEXT_ALPHANUMERIC"/>
<input type="AUDIO"/>
</supportedInputTypes>
<requiresAudioLabels>false</requiresAudioLabels>
</config>
</readingSystemAttributes>
7.3.2 serviceAttributes
If the DAISY Online Service supports dynamic menus, the DYNAMIC_MENUS
operation element must be included in the supportedOptionalOperations
type in serviceAttributes
. Optional functionality such as “search” and “back” support for the getQuestions
operation may be specified using elements such as supportsSearch
and supportsServerSideBack
.
7.3.2.1 Example: serviceAttributes
<serviceAttributes xmlns="http://www.daisy.org/ns/daisy-online/">
<serviceProvider id="gy-zenith" />
<service id="gy-zenith-libraryServiceDeluxe" />
<supportsServerSideBack>true</supportsServerSideBack>
<supportsSearch>true</supportsSearch>
<supportedUplinkAudioCodecs>
<codec>audio/mpeg</codec>
</supportedUplinkAudioCodecs>
<supportsAudioLabels>true</supportsAudioLabels>
<supportedOptionalOperations>
<operation>DYNAMIC_MENUS</operation>
<operation>SET_BOOKMARKS</operation>
<operation>GET_BOOKMARKS</operation>
<operation>SERVICE_ANNOUNCEMENTS</operation>
<operation>PDTB2_KEY_PROVISION</operation>
</supportedOptionalOperations>
<accessConfig>STREAM_AND_RESTRICTED_DOWNLOAD</accessConfig>
<announcementsPullFrequency>120</announcementsPullFrequency>
<progressStateOperationAllowed>true</progressStateOperationAllowed>
</serviceAttributes>
7.4 Example menu structure
7.4.1 Visual menu structure example
ID: Q-00 (multipleChoiceQuestion )label : “Main menu. Please select menu option.” |
|||
ID: C-01label : “Search the library” |
ID: C-02label : “Updating the User Profile” |
||
ID: Q-01 (multipleChoiceQuestion )label : “Search menu.” |
ID: Q-02-1 (inputQuestion )inputTypes : “TEXT_ALPHANUMERIC”label : “Your name:”ID: Q-02-2 (inputQuestion )inputTypes : “TEXT_ALPHANUMERIC”label : “Your address:”
ID: Q-02-3 (
|
||
ID: C-01-01label : “This week newly coming books” |
ID: C-01-02label : “Book Search By keyword” |
ID: C-01-03label : “Voice search” |
|
contentListRef : “weeklynew”
(end point) |
ID: Q-01-02-01 (inputQuestion )inputTypes : “TEXT_ALPHANUMERIC”label : “Input keyword.” |
ID: Q-01-03-01 (inputQuestion )inputTypes : “AUDIO”label : “Please talk search keyword.” |
|
contentListRef : “searchresult”
(end point) |
contentListRef : “voicesearch”
(end point) |
||
label : “User Profile configured”
(end point) |
7.4.2 Text menu structure example
7.4.2.1 Root menu
- ID: Q-00 (
multipleChoiceQuestion
)
label
: “Main menu. Please select menu option.” - ID: C-01
label
: “Search the library” - ID: C-02
label
: “Update User Profile”
7.4.2.2 Root menu response C-01 leads to sub menu Q-01
- ID: Q-01 (
multipleChoiceQuestion
)
label
: “Search menu.” - ID: C-01-01
label
: “This weeks new books” - ID: C-01-02
label
: “Book Search By keyword” - ID: C-01-03
label
: “Voice search”
7.4.2.3 Sub menu response C-01-01 leads to end point
contentListRef
: “weeklynew”
7.4.2.4 Sub menu response C-01-02 leads to sub menu Q-01-02-01
- ID: Q-01-02-01 (
inputQuestion
)
inputTypes
: “TEXT_ALPHANUMERIC”
label
: “Input keyword.”
7.4.2.5 Sub menu response to Q-01-02-01 leads to end point
contentListRef
: “searchresult”
7.4.2.6 Sub menu response C-01-03 leads to sub menu Q-01-03-01
- ID: Q-01-03-01 (inputQuestion)
inputTypes
: “AUDIO”
label
: “Please talk search keyword.”
7.4.2.7 Sub menu response to Q-01-03-01 leads to end point
contentListRef
: “voicesearch”
7.4.2.8 Root menu response C-02 leads to sub menu with questions Q-02-1, Q-02-2 and Q-02-3
label
: “Updating the User Profile”- ID: Q-02-1 (
inputQuestion
)
inputTypes
: “TEXT_ALPHANUMERIC”
label
: “Your name:” - ID: Q-02-2 (
inputQuestion
)
inputTypes
: “TEXT_ALPHANUMERIC”
label
: “Your address:” - ID: Q-02-3 (
multipleChoiceQuestion
)
label
: “Your gender:”- Choice ID: C-02-3-01
label
: “Male” - Choice ID: C-02-3-02
label
: “Female”
- Choice ID: C-02-3-01
7.4.2.9 Sub menu responses to Q-02-1, Q-02-2 and Q-02-3 lead to end point
label
: “User Profile configured”
7.5 getQuestions
7.5.1 Opening a root menu
getQuestions
is the operation used to implement dynamic menus functionality. The Reading System calls getQuestions
with a parameter containing the userResponse
. The userResponse
contains the id of the menu and the response value, which is used by the Service to determine the next dynamic menu to return to the Reading System.
A Reading System will require the ability to open the root/main menu. That is, the menu that the Service makes available prior to the User making any specific selections. To achieve this, the Reading System sends the reserved id “default” as the questionId
informing the Service to return the default menu. If the Service supports dynamic menus then the “default” keyword must be supported.
The service may also optionally support reserved ids “search” and “back” as indicated by serviceAttribute
elements supportsSearch
and supportsServerSideBack
. The “search” keyword is designed to return the default search menu and “back” is designed to support a server side back (menu navigation) feature.
If the Service supports “search”, the Reading System may for example allow a choice of using the “default” or “search” menu as its initial menu.
7.5.1.1 Example: getQuestions with userResponse “default”
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="default" />
</userResponses>
</getQuestions>
7.5.1.2 Example: Response
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<multipleChoiceQuestion id="Q-00">
<label xml:lang="en">
<text> Main menu. Please select menu option.</text>
</label>
<choices>
<choice id="C-01">
<label xml:lang="en">
<text>Search the library</text>
</label>
</choice>
<choice id="C-02">
<label xml:lang="en">
<text>Update your profile</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</questions>
7.5.2 Selecting from multipleChoiceQuestion
When getQuestions
returns a multipleChoiceQuestion
, the Reading System renders the question
to enable the User to make a selection. The Reading System may render the question
label
as text to speech (TTS) or visually using text.
For example with the question “Q-00”, the Reading System will show “Main menu. Please select menu option”.
The Reading System will then render each choice label
providing the options from which the User chooses. In the example of question “Q-00”, “Search the library” and “Update your profile ” are choices on the “default” menu.
Once the User makes a selection, the Reading System then calls getQuestions
with the userResponse
id of the menu and selected choice. This informs the Service of the choice made and on what question
it was made.
7.5.2.1 Example: getQuestions with userResponse “Q-00” and “C-01”
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="Q-00" value="C-01" />
</userResponses>
</getQuestions>
7.5.2.2 Example: Response
By continuing this process, dynamic menus are able to represent hierarchical menu structures. In the example, the response of ID “Q-00”, value “C-01” represents the option “Search menu.”. The Reading System will render the label
“Search menu.” and will then present the associated choices to the User.
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<multipleChoiceQuestion id="Q-01">
<label xml:lang="en">
<text>Search menu.</text>
</label>
<choices>
<choice id="C-01-01">
<label xml:lang="en">
<text>This week newly coming books</text>
</label>
</choice>
<choice id="C-01-02">
<label xml:lang="en">
<text>Book Search By keyword</text>
</label>
</choice>
<choice id="C-01-03">
<label xml:lang="en">
<text>Voice search</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</questions>
7.5.3 Going “back” to previous menu
Where server side back is supported, a Reading System is able to call getQuestions
with the reserved id “back”, which allows the User to return to the previous menu.
Support for “back” is optional and is determined by the supportsServerSideBack
element in serviceAttributes
. If the Service does support server side back, the Reading System has the option of rendering support for it, but this is not mandatory.
To implement the “back” option, the Service must maintain the session to enable it to keep the chain of selected menu items, i.e. executing the “back” function returns the User to the last visited menu.
7.5.3.1 Example: getQuestions with userResponse “back” at the menu position of ID “Q-01”:
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="back"/>
</userResponses>
</getQuestions>
7.5.3.2 Example: Response:
Back from ID “Q-01” returning to the previous menu, the “default” menu.
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<multipleChoiceQuestion id="Q-00">
<label xml:lang="en">
<text> Main menu. Please select menu option.</text>
</label>
<choices>
<choice id="C-01">
<label xml:lang="en">
<text>Search the library</text>
</label>
</choice>
<choice id="C-02">
<label xml:lang="en">
<text>Update your profile</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</questions>
7.6 Input questions
7.6.1 Input question menu
When a User selects the choice of searching for contents by keyword, an inputQuestion
is returned by the Service.
An Input question supports the following three input type. “TEXT_NUMERIC”, “TEXT_ALPHANUMERIC” or “AUDIO”.
The input types supported by the Reading System have already been supplied to the Service as part of the readingSystemAttributes
. This ensures the Service only returns input types that are supported by the Reading System.
7.6.1.1 Example: getQuestions with userResponse “Q-01” and “C-01-02”
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="Q-01" value="C-01-02" />
</userResponses>
</getQuestions>
7.6.1.2 Example: Response
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<inputQuestion id="Q-01-02-01">
<inputTypes>
<input type="TEXT_ALPHANUMERIC" />
</inputTypes>
<label xml:lang="en">
<text>Input keyword.</text>
</label>
</inputQuestion>
</questions>
7.6.2 User interface of input
When an inputQuestion
is received from the Service, the Reading System renders the question’s label
– in this case, for inputQuestion
“Q-01-02-01”, “Input keyword”. The Reading System will then provide a user interface to capture User input based on the supplied input type.
For example a Reading System may render a spin control for capturing numeric data (“TEXT_NUMERIC”) or may simply render a standard text control as it would for text input (“TEXT_ALPHANUMERIC”). For an “AUDIO” input type, a Reading System would use a microphone and recording key.
Once the input has been captured by the Reading System, it calls getQuestions
with the data captured to return it to the Service.
7.6.2.1 Example: getQuestions with userResponse “Q-01-02-01″ and ” three little pigs”:
The Following example shows “three little pigs” as a book search query.
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="Q-01-02-01" value="three little pigs" />
</userResponses>
</getQuestions>
7.6.2.2 Example: Response
The getQuestions
response will then contain a reference to a content list containing the search results.
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<contentListRef>L200</contentListRef>
</questions>
7.6.3 Combination of questions
To support an advanced search, it is possible to combine two or more questions in the search query stage.
As the result of the initial inputQuestion
, the Service may return another inputQuestion
. For example, as the result of the inputQuestion
for author name, another question for issued date can be asked. When using this technique, it is possible to narrow down the search results by chaining together many questions.
Dynamic menus support another way to combine questions. The questions
type supports the ability to supply many multipleChoiceQuestion
and/or inputQuestion
in a single userResponse
.
The following example of “Updating the User Profile” shows how several questions may be combined into a single getQuestions
call.
7.6.3.1 Example: getQuestions with userResponse “C-02” at “Q-00”:
This example shows the userResponse for question Q-00, with selection C-02 “Updating the User Profile”.
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="Q-00" value="C-02" />
</userResponses>
</getQuestions>
7.6.3.2 Example: contentList
This example shows a sample questions
element containing two inputQuestion
s and one multipleChoiceQuestion
.
label
: “Input your new user profile.”
inputQuestion
: “Your name:”
inputQuestion
: “Your address:”
multipleChoiceQuestion
: “Your gender:” Male / Female
The questions
element may optionally have a label
. This example shows “Input your new user profile”.
When two or more inputQuestion
s, or multipleQuestion
s exist, each inputQuestion
has a label
to explain what the inputQuestion
is.
The label
associated with the parent questions
element may be used to explain the purpose of the set of questions.
Note that a default value may be provided by the Service for an inputQuestion
using the attribute defaultValue
. For example, if the question
was being used to edit their address, then the existing address could be passed as the defaultValue
and would be rendered to the User for them to edit or leave unchanged.
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<label xml:lang="en">
<text>Input your new user profile.</text>
</label>
<inputQuestion id="Q-02-1">
<inputTypes>
<input type="TEXT_ALPHANUMERIC" />
</inputTypes>
<label xml:lang="en">
<text>Your name:</text>
</label>
</inputQuestion>
<inputQuestion id="Q-02-2">
<inputTypes>
<input type="TEXT_ALPHANUMERIC" />
</inputTypes>
<label xml:lang="en">
<text>Your address:</text>
</label>
</inputQuestion>
<multipleChoiceQuestion id="Q-02-3">
<label xml:lang="en">
<text>Your gender:</text>
</label>
<choices>
<choice id="C-02-3-01">
<label xml:lang="en">
<text>Male</text>
</label>
</choice>
<choice id="C-02-3-02">
<label xml:lang="en">
<text>Female</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</questions>
7.6.3.3 Example: getQuestions for a set of questions:
The following example shows a response to the set of questions containing a label
end point.
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="Q-02-1" value="Margaret Asterales" />
<userResponse questionID="Q-02-2"
value="Grubenstrasse 12, 8045 Zurich, Switzerland" />
<userResponse questionID="Q-02-3" value="C-02-3-02" />
</userResponses>
</getQuestions>
7.6.4 Label as an end point of a dynamic menu
Dynamic menus can be terminated by using a label
end point. In the example of “Updating the User Profile” a label
end point is returned containing the test message “Your profile has been updated successfully”.
When the menu reaches the end point, the Service returns a label
to inform the Reading System of the result. For example when using a search menu, if no search results were found, the Service can return the label
“No title available for this search keyword”. This label
is normally returned to inform the Reading System of the success or failure of an action or why a contentList
was not returned.
Note that a Service could alternatively return a contentListRef
pointing to an empty contentList
as a contentListRef
may also contain a label
but this operation requires the Reading System to retrieve the contentList
before it can tell it is empty.
7.6.4.1 Example: Response for question of user profile configuration menu
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<label xml:lang="en">
<text>Your profile has been updated successfully!</text>
</label>
</questions>
7.7 Content list
7.7.1 Content list
The result of a dynamic menu may be a list of content items which is provided using the contentListRef
type which is a valid dynamic menu end point.
A contentListRef
cannot contain questions
as it is an end point.
A dynamic menu must end with 1 of 2 end points, being a contentListRef
” or label
.
A contentListRef
may contain an optional label
which is used to hold a description of the content list, for example “List of this weeks new books”.
7.7.1.1 Example: Response against getQuestions with userResponse “Q-01” and “C-01-01”
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<label xml:lang="en">
<text> List of this weeks new books</text>
</label>
<contentListRef>L100</contentListRef>
</questions>
7.7.2 Rendering a content list
A Reading System will then need to render the content list contained in the contentListRef
. The Reading System calls getContentList
using the contentlistRef
id to obtain the content list items.
The Reading System will then render the list to the User using the label
if available to describe the list returned. The User may then select an item from the list.
A Reading System may allow the User to request more details about a content list item and could then render information about this item using data made available as part of the content item’s metadata
.
If the content list contain a large number of items, the results may be returned in pages using the firstItem
and lastItem
parameters in getContentList
.
7.7.2.1 Example: Content list
<contentList xmlns="http://www.daisy.org/ns/daisy-online/" id=" L100" totalItems="2">
<label xml:lang="en">
<text>Please select from this weeks new titles.</text>
<audio uri="http://example.com/static/PleaseChooseFrom.mp3" size="12342"/>
</label>
<contentItem id="com-example-001" category="BOOK" lastModifiedDate="2015-02-25T09:20:10Z">
<label xml:lang="en">
<text>Fun of cooking</text>
<audio uri="http://example.com/content/titles/FunOf_1.mp3" size="130821"/>
</label>
<sample id="FunOf_1-sample"/>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>Fun of homemade cupcake</dc:title>
<dc:identifier>com-example-hp_cos</dc:identifier>
<dc:format>Daisy 2.02</dc:format>
<dc:language>en-GB</dc:language>
<dc:description>Homemade cupcake reflects tradition of family. You can find family history in the way of cooking.</dc:description>
<narrator>James Green</narrator>
<size>8119213</size>
</metadata>
<accessPermission>STREAM_ONLY</accessPermission >
</contentItem>
<contentItem id="com-example-002" category="BOOK" lastModifiedDate="2015-02-26T13:20:10+06:00">
<label xml:lang="en">
<text>True story of three little pigs</text>
<audio uri="http://example.com/content/titles/hp_gf.mp3" size="130821"/>
</label>
<sample id="hp_cos-sample"/>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>True story of three little pigs</dc:title>
<dc:identifier>com-example-hp_cos</dc:identifier>
<dc:format>Daisy 2.02</dc:format>
<dc:language>en-GB</dc:language>
<dc:description>Everyone knows about three little pigs. Yes, it is very traditional fairy tale. But, nobody know about another true story, hidden by mysterious witch.</dc:description>
<narrator>James Bule</narrator>
<size>8119213</size>
<meta name="pdtb2:specVersion" content="2005-1" />
<meta name="cover" content="http://example.com/image.png" />
</metadata>
<accessPermission>STREAM_ONLY</accessPermission >
</contentItem>
</contentList>
7.7.3 Sample book
When sample content is available, the Service can supply an id of the sample contents in the content’s metadata
. This enables a Reading System to support a user interface to open sample content.
To access the sample, a Reading System calls getContentResources
, which returns the URI to the content enabling playback to the User. (Details related to opening and playback of content are not described in this document.)
Reading Systems may optionally support terminating playback of the sample book. After termination, the Reading System may return to the content list selection.
7.7.4 Going “back” to previous question from a content list
To return to the previous question
from a content list, the Reading System calls getQuestions
using the reserved id “back”. In the example of viewing the contentListRef
“weeklynew”, the call to “back” would return the User to the question
“Q-01”
7.8 Add content to the bookshelf
7.8.1 Adding content
Provided that the contentItem
does not have a child element multipleChoiceQuestion
, the default action is always addContentToBookshelf
. The Reading System may request confirmation from the User prior to adding the content to the bookshelf.
To add the content to the bookshelf, the Reading System calls addContentToBookshelf
. The Reading System is able to call two or more addContentToBookshelf
operations when the User has selected multiple content items.
When a book is successfully added to the bookshelf, the Reading System may choose to start playback or show the bookshelf or may return to the content list. This depends on the Reading System’s design.
7.8.2 Bookshelf
After a Reading System has called addContentToBookshelf
, the content will be available on the bookshelf.
To retrieve the bookshelf, the Reading System calls getContentList
with the reserved id “bookshelf”. The Reading System may then allow the User to select and play content from bookshelf. (Details related to listing the bookshelf are not described in this document.)
7.8.3 Playback of bookshelf content item
Instead of returning to either the bookshelf or content list, the Reading System is able to start playback of the content. A Reading System calls getContentResources
to get the relevant URIs and uses them to begin playback. (Details related to listing the bookshelf are not described in this document.)
The particular Reading System behavior once the content list endpoint has been reached is dependent on the Reading System’s design.
7.9 Advanced Dynamic menu
7.9.1 Support of advanced dynamic menus
Advanced dynamic menus provide support for a content item to have its own menu. This is used when the default action of addContentToBookshelf
is not adequate, i.e. a Service wishes to provide multiple actions for a given content item. For example, a Service may wish to support actions such as “Loan to Internet bookshelf”, “Loan by CD”, or “Mark as favorites” for a given content item.
Advanced dynamic menu allows the Service to attach a multipleChoiceQuestion
to a contentItem
containing the required actions. Note that each content item may contain a different action list. For example, if an item cannot be loaned by CD, then the “Loan to CD” option may not be included for that content item.
To use advanced dynamic menus, a Reading System must set supportsAdvancedDynamicMenus
to true
. When this value is false, the Service must not add a multipleChoiceQuestion
to content items.
7.9.1.1 Example: readingSystemAttributes
<readingSystemAttributes xmlns="http://www.daisy.org/ns/daisy-online/">
<manufacturer>ACME Corporation</manufacturer>
<model>Pro Phantom III</model>
<serialNumber>64321</serialNumber>
<version>1.23</version>
<config>
<accessConfig>STREAM_ONLY</accessConfig >
<supportsMultipleSelections>false</supportsMultipleSelections>
<supportsAdvancedDynamicMenus>false</supportsAdvancedDynamicMenus>
<preferredUILanguage>en</preferredUILanguage>
<supportedContentFormats>
<contentFormat>ANSI/NISO Z39.86-2005</contentFormat>
<contentFormat>Daisy 2.02</contentFormat>
</supportedContentFormats>
<supportedContentProtectionFormats />
<supportedMimeTypes>
<mimeType type="text/plain" xml:lang="en"/>
<mimeType type="audio/mpeg"/>
</supportedMimeTypes>
<supportedInputTypes>
<input type="TEXT_ALPHANUMERIC"/>
<input type="AUDIO"/>
</supportedInputTypes>
<requiresAudioLabels>false</requiresAudioLabels>
</config>
</readingSystemAttributes>
7.9.2 Questions in the contentItem
The Following example shows three actions “Loan to Internet bookshelf”, “Loan by CD”, or “Mark as favorites” as available for each content item.
The multipleChoiceQuestion
“L100_com-example-001” is assigned as options for the contentItem
with id “com-example-001”. This example shows how a Service can include the content id in the question id to ensure the Service knows which content item is being referred to once the action has been selected and returned.
7.9.2.1 Example: Content list
<contentList xmlns="http://www.daisy.org/ns/daisy-online/" id=" L100" totalItems="2">
<label xml:lang="en">
<text>Please select from this weeks new titles.</text>
<audio uri="http://example.com/static/PleaseChooseFrom.mp3" size="12342"/>
</label>
<contentItem id="com-example-001" category="BOOK" lastModifiedDate="2015-02-25T09:20:10Z">
<label xml:lang="en">
<text>Fun of cooking</text>
<audio uri="http://example.com/content/titles/FunOf_1.mp3" size="130821"/>
</label>
<sample id="FunOf_1-sample"/>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>Fun of homemade cupcake</dc:title>
<dc:identifier>com-example-hp_cos</dc:identifier>
<dc:format>Daisy 2.02</dc:format>
<dc:language>en-GB</dc:language>
<dc:description>Homemade cupcake reflects tradition of family. You can find family history in the way of cooking.</dc:description>
<narrator>James Green</narrator>
<size>8119213</size>
</metadata>
<accessPermission>STREAM_ONLY</accessPermission >
<multipleChoiceQuestion id="L100_ com-example-001">
<label>
<text>What would you like to do now?</text>
</label>
<choices>
<choice id="LoanByNet">
<label>
<text>"Loan to Internet bookshelf</text>
</label>
</choice>
<choice id="LoanByCD">
<label>
<text>Loan by CD</text>
</label>
</choice>
<choice id="Mark">
<label>
<text>Mark as favorites</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</contentItem>
<contentItem id="com-example-002" category="BOOK" lastModifiedDate="2015-02-26T13:20:10+06:00">
<label xml:lang="en">
<text>True story of three little pigs</text>
<audio uri="http://example.com/content/titles/hp_gf.mp3" size="130821"/>
</label>
<sample id="hp_cos-sample"/>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>True story of three little pigs</dc:title>
<dc:identifier>com-example-hp_cos</dc:identifier>
<dc:format>Daisy 2.02</dc:format>
<dc:language>en-GB</dc:language>
<dc:description>Everyone knows about three little pigs. Yes, it is very traditional fairy tale. But, nobody know about another true story, hidden by mysterious witch.</dc:description>
<narrator>James Bule</narrator>
<size>8119213</size>
<meta name="pdtb2:specVersion" content="2005-1" />
<meta name="cover" content="http://example.com/image.png" />
</metadata>
<accessPermission>STREAM_ONLY</accessPermission >
<multipleChoiceQuestion id=" L100_ com-example-002">
<label>
<text>What would you like to do now?</text>
</label>
<choices>
<choice id="LoanByNet">
<label>
<text>"Loan to Internet bookshelf</text>
</label>
</choice>
<choice id="LoanByCD">
<label>
<text>Loan by CD</text>
</label>
</choice>
<choice id="Mark">
<label>
<text>Mark as favorites</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</contentItem>
</contentList>
7.9.3 Selecting from multipleChoiceQuestion of contentItem
When a multipleChoiceQuestion
is provided for a contentItem
, the Reading System renders this as a menu for the User to select from.
The Reading System may render the label
of a question
by text to speech (TTS) or by showing text in the screen. For example, in relation to the question “L100_com-example-001”, the Reading System will show “What would you like to do now?” The Reading System will then render the label
of each choice and allow for the User to select from these options.
In this example, the “Loan to Internet bookshelf”, “Loan by CD”, or “Mark as favorites” options are attached to the “Fun of cooking” contentItem
. Once a choice is selected, the Reading System calls getQuestions
with a userResponse
containing both the menu id and selected choice.
The following example shows a sample userResponse
and subsequent getQuestions
response containing a label
end point informing the User the title was added successfully to their bookshelf.
7.9.3.1 Example: getQuestions with userResponse “L100_com-example-001″ and ” LoanByNet”:
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="L100_com-example-001" value="LoanByNet" />
</userResponses>
</getQuestions>
7.9.3.2 Example: Response
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<label xml:lang="en">
<text>The title was successfully added to your bookshelf!</text>
</label>
</questions>
7.9.4 Actions to take as a result of an advanced dynamic menu
When getQuestion
is called from a Reading System, the Service executes the corresponding actions based on the User’s choice. For the Service to execute this action it will need to know both the action to perform based on the choice the User has made and the content item on which to perform the action. The Service can determine the choice from the value while the content item can be extracted from the question id.
For example, if the response contained the question id “L100_com-example-001” and the value “LoanByNet”, then the choice made was “LoanByNet”. The content item id is “com-example-001” which is part of the value used for the question id.
If advanced dynamic menus are not used, the Reading System can assume the action being executed is addToBookshelf
. With advanced dynamic menus, the Reading System cannot make assumptions about the action selected as this is controlled by the Service, i.e. it would not make sense for a Reading System to auto start playback of a content item when using advanced dynamic menus.
The Service returns a questions
type as a result of getQuestions
. This means the Service can return a label
or contentListRef
as an end point of a dynamic menu or a further menu containing a combination of multipleChoiceQuestion
or inputQuestion
elements.
Since Reading Systems have no way of knowing what actions are being performed as the result of a choice, Reading Systems simply continue to render provided questions until end points are reached.
7.10 Other Examples
7.10.1 Example of supportsMultipleSelections
The allowMultipleSelections
switch can be used to inform a Reading System that the Service can accept multiple selections from a given multipleChoiceQuestion
but only when the Reading System has stated it can support them. The Reading System declares it can support accepting more than one selection for a multiple choice questions using the supportsMultipleSelections
element in the readingSystemAttributes
.
This results in a userResponse
containing multiple rows, each containing the same question id yet a different choice value.
When a Reading System supports multiple selections, it must look at the allowMultipleSelections
attribute on the question
to determine if multiple choices are allowed by the Service for this question
.
If the Reading System does not support multiple selections, the Service cannot provide menu items with the allowMultipleSelections
attribute set to “true”.
The following example shows multiple choice questions requesting the User to select their favorite search categories. The User is able to choose from “Comedy “, “Thriller”, “Biography”, “History”, and/or “Fairy tale”. The User can select one of the choices, or if they wish, two or more choices can be selected at once.
7.10.1.1 Example: multipleChoiceQuestion with allowMultipleSelections true
<questions xmlns="http://www.daisy.org/ns/daisy-online/">
<multipleChoiceQuestion id="q5" allowMultipleSelections="true">
<label xml:lang="en">
<text>Which of the following category(s) would you like to search?</text>
</label>
<choices>
<choice id="c1">
<label xml:lang="en">
<text>Comedy</text>
</label>
</choice>
<choice id="c2">
<label xml:lang="en">
<text>Thriller</text>
</label>
</choice>
<choice id="c3">
<label xml:lang="en">
<text>Biography</text>
</label>
</choice>
<choice id="c4">
<label xml:lang="en">
<text>History</text>
</label>
</choice>
<choice id="c5">
<label xml:lang="en">
<text>Fairy tale</text>
</label>
</choice>
</choices>
</multipleChoiceQuestion>
</questions>
7.10.1.2 Example: Choice result with “Comedy” and “Thriller”, two choices selected
<getQuestions xmlns="http://www.daisy.org/ns/daisy-online/">
<userResponses>
<userResponse questionID="q5" value="c1" />
<userResponse questionID="q5" value="c2" />
</userResponses>
</getQuestions>
7.10.2 Error handling case: Reading System does not support required input type
It is possible that a Reading System does not support an input type required by the Service to perform a particular action. For example, the Service may require support for “TEXT_ALPHA_NUMERIC” input for a book search, but the Reading System does not support alphabetic input.
When this occurs, the Service can return a label
to inform the User that this function is not supported on this device. As the Service knows which input types are supported by the given Reading System, it may choose simply to exclude such options that cannot be supported from the menu to simplify the User experience.
The Service could return a Fault message to the Reading System but it is often better to use a label
end point. The label
end point allows a reason to be returned to the Reading System and allows normal processing to continue such as processing the “back” command. For this reason it is often better to use the label
end point avoiding the need to raise a Fault condition.
7.10.3 Error handling case: Fault error
The DAISY Online protocol defines Fault error cases to handle error situations. Once a Fault occurs, the Service will have difficulty tracking the current selections of dynamic menu items. It will be difficult for Reading Systems to respond to getQuestions
to resume suitable dynamic menu conditions.
This results in both Service and Reading System not being able to continue dynamic menu selections once a Fault condition has occured.
The Error handing / Fault management design depends on the individual Reading System design, however it is normal behavior when a Fault occurs for a Reading System to render the error message to the User and exit from the dynamic menu.