Zero-Knowledge Command Protocol API

Freedom Services 2.0 Archive Validated

$Id: zkcp.html,v 1.4 2001/07/10 20:36:49 sam Exp $
Revision Comments
1.1 Author(s): Roger McFarlane (roger@zks.net), Francis L'Écuyer (francisl@zks.net); 

Initial draft. 

1.2 Incorporated API changes suggested by Igor Stolbikov (igor@zks.net) and Philippe Boucher (philippe@zks.net)

Contents

  1. Introduction
  2. User's Guide
  3. Function Reference
    1. zkcpContext_Create
    2. zkcpContext_Destroy
    3. zkcpContext_AddType
    4. zkcpContext_SetKey
    5. zkcpContext_NewConnection
    6. zkcpConnection_Destroy
    7. zkcpConnection_SetKey
    8. zkcpConnnection_ReadCommand
    9. zkcpConnection_WriteCommand
    10. zkcpCommand_Create
    11. zkcpCommand_Destroy
    12. zkcpCommand_AddParam
    13. zkcpCommand_GetId
    14. zkcpCommand_GetParamById
    15. zkcpCommand_GetParamByIndex
    16. zkcpCommand_GetParamCount
    17. zkcpValueConstructor_Destroy
    18. zkcpValue_Destroy
  4. Interfaces
    1. Creating your own types
    2. Making your types available
    3. Input and Output
  5. Examples
  6. References

1 - Introduction

Goto : [top]
This Application Programming Interface (API) is intended to facilitate the implementation of client/server software which communicates using the Zero-Knowledge Command Protocol (ZKCP).
See also:
Zero-Knowledge Command Protocol Specification
Zero-Knowledge Database Server Protocol Specification

2 - User's Guide

Goto : [top]

Overview

The data types exposed by the API are the following:
typedef uint16_t                        ZkcpCommandId;
typedef uint16_t                        ZkcpParameterId;
typedef uint16_t                        ZkcpTypeId;
typedef uint32_t                        ZkcpTimeStamp;

typedef struct T_ZkcpContext          * ZkcpContext;
typedef struct T_ZkcpConnection       * ZkcpConnection;
typedef struct T_ZkcpCommand          * ZkcpCommand;
typedef struct T_ZkcpValue            * ZkcpValue;
typedef struct T_ZkcpValueConstructor * ZkcpValueConstructor;
The first three data types are used to identify commands, parameters, and types to the system.

ZkcpCommandId

A numeric value which uniquely identifies a command in the application spefic context in which the protocol library is being used. These values correspond to function names.

ZkcpParameterId

A numeric value which uniquely identifies a parameter to a given command in the application spefic context in which the protocol library is being used. Note that these identifiers only need by unique within the context of a given command. These identifiers correspond to variable names.

ZkcpTypeId

A numeric value which uniquely identifies a data-type in the application specific context in which the protocol library is being used. These value correspond to data type names.
The ZkcpCommand and ZkcpValue data types define abstractions for the objects that form a ZKCP packet.

The ZkcpContext and ZkcpValueConstructor abstractions serve to construct commands from data received from an entity communication using the ZKCP. These objects implement the Builder pattern discussed in [GoF]. As described in the design pattern: ZkcpContext objects play the Director role; ZkcpValueConstructor defines the Builder interface; and, ZkcpValue define interface to the Product issued by the builder. For more information on adding your own types and making them available to the parser see the Interfaces section of this document.

Using the API

Coming soon.

4 - Function Reference

Goto : [top]

4.1 - zkcpContext_Create

Prototype:
int zkcpContext_Create(
    ZK_INOUT ZkError                                error,
    ZK_OUT   ZkcpContext *                          context );
Creates a new ZkcpContext object. The returned object must eventually be destroyed using the zkcpContext_Destroy function.

4.2 - zkcpContext_Destroy

Prototype:
int zkcpContext_Destroy(
    ZK_INOUT ZkError                                error,
    ZK_OUT   ZkcpContext                            context );
Destroys a ZkcpContext object. The object must have been previously allocated using the zkcpContext_Create function.

4.3 - zkcpContext_AddType

Prototype:
int zkcpContext_AddType(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpContext                            context,
    ZK_IN    ZkcpValueConstructor                   in_constructor )
Registers a new type for use by the command parsing system. The constructor object which is passed must conform to the ZkcpValueConstructor
interface. The constructor object must also exist for the entire lifetime of the context object.

4.4 - zkcpContext_SetKey

Prototype:
int zkcpContext_SetKey(
    ZK_INOUT ZkError                                error,
    Zk_IN    ZkcpContext                            context,
    ZK_IN    const void *                           key,
    ZK_IN    size_t                                 key_length );
Changes the initial link authentication key for all subsequent connections which are based on this context.

4.5 - zkcpContext_NewConnection

Prototype:
int zkcpContext_NewConnection(
    ZK_INOUT ZkError                                error,
    Zk_IN    ZkcpContext *                          context,
    ZK_IN    void *                                 io_context,
    ZK_IN    ZkcpCallback_Read                      read_func,
    ZK_IN    ZkcpCallback_Write                     write_func,
    ZK_OUT   ZkcpConnection *                       out_connection );
Creates a new ZkcpConnection object. The connection object will be initialized using the current context. It will used the supplied read and write functions to perform I/O. Upon destruction of the connection the free function will be called on the supplied io_context.
see also
ZkcpCallback_Read
ZkcpCallback_Write

4.6 - zkcpConnection_Destroy

Prototype:
int zkcpConnection_Destroy(
    ZK_INOUT ZkError                                error,
    Zk_IN    ZkcpConnection *                       connection );
Destroys a ZkcpConnection.

4,7 - zkcpConnection_SetKey

Prototype:
int zkcpConnection_SetKey(
    ZK_INOUT ZkError                                error,
    Zk_IN    ZkcpConnection                         connection,
    ZK_IN    const void *                           key,
    ZK_IN    size_t                                 key_length );
Rotates the link authentication key for the current connection.

4.8 - zkcpConnection_ReadCommand

Prototype:
int zkcpContext_ReadCommand (
    ZK_INOUT ZkError                                error,
    Zk_IN    ZkcpConnection                         connection,
    ZK_OUT   ZkcpCommand *                          out_new_command );
Reads and parses a command from the given connection stream.

4.9 - zkcpConnection_WriteCommand

Prototype:
int zkcpContext_WriteCommand (
    ZK_INOUT ZkError                                error,
    Zk_IN    ZkcpConnection                         connection,
    ZK_IN    ZkcpCommand                            command );
Writes a command to the given connection stream.

4.10 - zkcpCommand_Create

Prototype:
int zkcpCommand_Create(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpCommandId                          command_id,
    ZK_OUT   ZkcpCommand *                          command );
Creates a new command object.

4.11 - zkcpCommand_Destroy

Prototype:
int zkcpCommand_Destroy(
    ZK_INOUT ZkError                                error,
    ZK_OUT   ZkcpCommand *                          command );
Destroys a command object.

4.12 -zkcpCommand_AddParam

Prototype:
int zkcpCommand_AddParam(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpCommand                            command,
    ZK_IN    ZkcpParameterId                        param_id,
    ZK_IN    ZkcpValue                              value );
Adds the supplied id/value pair to the given command. The parameter ID for the new parameter must be unique from those of the previously added parameters. Ownership of the parameter object is transferred to the command object. Do not destroy the parameter after adding it to the command.

4.13 - zkcpCommand_GetId

Prototype:
int zkcpCommand_GetId(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpCommand                            command,
    ZK_OUT   ZkcpCommandId *                        command_id );
Retrieves the command identifier associated with the given command object.

4.14 - zkcpCommand_GetParamById

Prototype:
int zkcpCommand_GetParamById(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpCommand                            command,
    ZK_IN    ZkcpParameterId                        param_id,
    ZK_OUT   ZkcpValue *                            value );
Retrieves the parameter object associated with the given parameter id.
 
 

The pointer that is returned parameter object refers to memory that is owned by the command object. The parameter to which it refers should not be freed by the recipient. Note that this also means that the lifetime of the object referred to does not exceed that of the command from which it was retrieved.

4.15 - zkcpCommand_GetParamByIndex

Prototype:
int zkcpCommand_GetParamByIndex(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpCommand                            command,
    ZK_IN    uint32_t                               param_index,
    ZK_OUT   ZkcpParameterId *                      param_id,
    ZK_OUT   ZkcpValue *                            value );
Retrieves the param_index'th object associated with the given parameter id. The order in which the parameters will be returned in arbitrary.

The pointer that is returned parameter object refers to memory that is owned by the command object. The parameter to which it refers should not be freed by the recipient. Note that this also means that the lifetime of the object referred to does not exceed that of the command from which it was retrieved.

4.16 - zkcpCommand_GetParamCount

Prototype:
int zkcpCommand_GetParamCount(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpCommand                            command,
    ZK_IN    uint32_t *                             param_count );
Retrieves the number of parameters associated with the given command object.

4.17 - zkcpValueConstructor_Destroy

Prototype:
int zkcpValueConstructor_Destroy(
    ZK_INOUT ZkError                                error,
    ZK_IN    ZkcpValueConstructor *                 constructor );
A wrapper function to call the virtual destructor defined for this value constructor object.

4.18 - zkcpValue_Destroy

int zkcpValue_Destroy(
    ZK_INOUT ZkError                                error,
    ZK_OUT   ZkcpValue *                            value );
A wrapper function to call the virtual destructor defined for this value object.

5 - Interfaces

Goto : [top]
  1. Creating your own types
  2. Making your types available
  3. Input and Output
This chapter explains how to create new data types and how to make these data types available as parameters so that the command and parser system will make use of them.

5.1 - Creating your own types

Goto : [top] [interfaces]
To create new data types for use by the library you need to define two object classes: a value type and a "constructor" type for that value type.

The value type provides an abstraction layer between the applications logical objects and data and the ZKCP library. Concrete value types serve to bind application domain data objects to the appropriate functions and context by which they can be serialized. The structures which define the interface for value objects are the following:

typedef struct T_ZkcpValue *        ZkcpValue;
typedef struct T_ZkcpValue_vtbl *   ZkcpValue_vtbl;

struct T_ZkcpValue {
    const ZkcpValue_vtbl    vtbl;
};

struct T_ZkcpValue_vtbl {
    int (*Destroy)        ( ZkError                 error,
                            ZkcpValue *             io_value );

    int (*GetTypeId)      ( ZkError                 error,
                            ZkcpValue               in_value,
                            uint16_t *              out_type_id );

    int (*GetSize)        ( ZkError                 error,
                            ZkcpValue               in_value,
                            uint32_t *              out_size );

    int (*WriteToBuffer)  ( ZkError                 error,
                            ZkcpValue               in_value,
                            void *                  io_buffer,
                            uint32_t                in_max_size,
                            uint32_t *              out_bytes_written );
};
To create a new type you first define a data structure to represent that type. This data structure MUST have as its first element a pointer to a function table matching struct T_ZkcpValue_vtbl. That is, your new data structure must have the same initial layout as a struct T_ZkcpValue. You then implement functions for each of the function pointer prototypes as defined. Lastly, define a static instance of a struct T_ZkcpValue_vtbl containing pointers to your functions.

The library maps type identifiers to auxialliary value constructor objects that serve to deserialize data to return abstract value objects. The structures which define the interface for value object constructors are the following:

typedef struct T_ZkcpValueConstructor *             ZkcpValueConstructor;
typedef struct T_ZkcpValueConstructor_vtbl *        ZkcpValueConstructor_vtbl;

struct T_ZkcpValueConstructor {
    const ZkcpValueConstructor_vtbl                 vtbl;
};

struct T_ZkcpValueConstructor_vtbl {
    int (*Destroy)        ( ZkError                 error,
                            ZkcpValueConstructor *  constructor );

    int (*GetTypeId)      ( ZkError                 error,
                            ZkcpValueConstructor    constructor,
                            uint16_t *              out_type_id );

    int (*FromBuffer)     ( ZkError                 error,
                            ZkcpValueConstructor    constructor,
                            const void *            in_buffer_ptr,
                            uint32_t                in_buffer_size,
                            ZkcpValue *             out_new_value,
                            uint32_t *              out_bytes_consumed );
};
To create a new constructor type you first define a data structure to represent that type. This data structure MUST have as its first element a pointer to a function table matching struct T_ZkcpValueConstructor_vtbl. That is, your new data structure must have the same initial layout as a struct T_ZkcpValueConstructor. You then implement functions for each of the function pointer prototypes as defined. Lastly, define a static instance of a struct T_ZkcpValueConstructor_vtbl containing pointers to your functions.

5.2 - Making your types available

Goto : [top] [interfaces]
Given that you have defined a set of classes for your type and its constructor, you need to have a means for application developers to use them. To that end, you want to implement the following set of operations: Optionally, you may wish to expose an application level function which creates instances of your new value object (be sure to return a ZkcpValue pointer and not a pointer to the actual type of your new object) and a function which interprets a ZkcpValue object as an application level object (verifying that the type is correct). In any case, you have to implement this functionality in order to provide the required functions.

5.3 - Input and Output

Goto : [top] [interfaces]

5.3.1 - ZkcpCallback_Read

typedef int (*ZkcpCallback_Read)(
    ZK_INOUT ZkError                error,
    ZK_IN    void *                 io_context,
    ZK_INOUT void *                 raw_buffer,
    ZK_IN    uint32_t               size );
This application defined callback is used to by the protocol library to read data from a communication medium.

5.3.2 - ZkcpCallback_Write

typedef int (*ZkcpCallback_Write)(
    ZK_INOUT ZkError                error,
    ZK_IN    void *                 io_context,
    ZK_INOUT const void *           raw_buffer,
    ZK_IN    uint32_t               size );
This application defined callback is used to by the protocol library to write data from to communication medium.

6 - Examples

Goto : [top]
Coming soon.

7 - References

Goto : [top]
[GoF] Design Patterns: Elements of Reusable Object-Oriented Software Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.
Addison-Wesley Publishing Company (Massachusetts, 1995)
ISBN: 0-201-63361-2

Copyright © 2000 Zero-Knowledge Systems Inc.
All rights reserved.