Table of Contents NMS Glossary Previous Page Next Page Version


Chapter 3

Writing a Natural Access Service - Overview


3.1 Introduction
3.2 Service Components
3.3 Service Name
3.4 Service ID
3.5 Software Structure
3.5.1 Binary Files
Source Files
3.6 Natural Access Coding Conventions
3.6.1 Function Names
3.6.2 Function Arguments
3.6.3 Return Values
3.6.4 Event and Reason Names
3.6.5 Error, Reason, Event, Command, and Trace Tag Codes
3.6.6 Manifest Constants and Enums
3.6.7 Structures
3.6.8 Parameter Structure Naming Convention
3.7 Writing a Service
3.7.1 Defining a Service
3.7.2 Implementing a Service
3.8 Sample Natural Access Service
3.8.1 Template Source Files

3.1 IntroductionTop of Page

This chapter describes the software structure and conventions for creating a Natural Access service. It also provides an overview of the steps necessary for developing a Natural Access service.

3.2 Service ComponentsTop of Page

Figure 17 shows the Natural Access architectural model. The following components (shown in gray boxes) comprise a Natural Access service:

The service interface component of a service includes the service API and the service SPI. The service implementation component includes the service manager and the service implementation.

3.3 Service NameTop of Page

Each Natural Access service is assigned a unique three letter acronym. This acronym is an integral part of the naming conventions for the components of a service. For example, the AG Board Driver Interface is referred to as the ADI service.

In this manual, the letters xxx are used to represent the three letter acronym assigned to a service.

3.4 Service IDTop of Page

Since Natural Access supports multiple services, any of which can be accessible to a client application, an internal mechanism is required to uniquely identify each service. This mechanism is the service ID.

The service ID is a 16 bit numeric value that is embedded in all command, error, and event messages. This allows the dispatcher to route messages between the service interface and the service implementation components.

3.5 Software StructureTop of Page

The following tables specify the contents and naming conventions for binary files and source files of a Natural Access service.

3.5.1 Binary FilesTop of Page

There are two DLLs or libraries created for a service: one for the service interface and one for the service implementation. Developers link with the implementation library when compiling an application. The corresponding interface library will be dynamically loaded at runtime. The CTA_SERVICE_NAME structure passed to ctaInitialize controls which service interface the application will use and which implementation of that interface should be dynamically linked in. For example, using ADI, ADIMGR states that the application will be making calls to the ADI service API and that the implementation of those calls will be performed by ADIMGR (for the hardware). Similarly, using ADI, QDIMGR, directs the application to make calls to the ADI service API, and directs QDIMGR to perform the implementation of those calls. Note that in both cases, the application links with adiapi.lib.

Having two libraries allows a service developer to leverage an existing service API by simply re-implementing the service implementation. For example, the ADI interface can be used for another vendor's telephony board by creating a new service implementation component which communicates with the board. The service interface remains the same.

The naming conventions for service binary files are:

Windows NT DLL

UNIX Library

Service Interface

xxxapi.dll

libxxxapi.so

Service Implementation

xxxmgr.dll

libxxxmgr.so

The appropriate implementation library is dynamically loaded at run time. This is controlled by the CTA_SERVICE_NAME structure passed to ctaInitialize.

For example:
This service and service manager...

links with...

and loads...

ADI, ADIMGR

adiapi.lib

adimgr.dll

ADI, QDIMGR

adiapi.lib

qdimgr.dll

Source FilesTop of Page

The service interface typically consists of the following source files:
File

Description

xxxapi.c

Implements the service API by calling the corresponding SPI function and handling API errors.

xxxspi.c

Implements the service SPI functions.

xxxdef.h

Header file containing API data structures, function prototypes, and definitions.

xxxspi.h

Header file containing SPI function prototypes.

xxxparm.pf

ASCII file containing definition of service parameters.

The service implementation typically consists of the following source files:
File

Description

xxxbnd.c

Implements the service manager (binding) functions.

xxxcmd.c

Implements the service functions which interact with the managed resource.

xxxparm.c

Parameter source file automatically generated from xxxparm.pf.

xxxparm.h

Parameter header file automatically generated from xxxparm.pf.

xxxsys.h

Header file containing internal data structures, function prototypes, and definitions.

Additional source files for a service can also exist as required. These files should also follow the Natural Access naming conventions (e.g., xxxsomething.c). File names should be restricted to 8.3 format.

The following diagram shows the relationship between service source files and binaries as well as the dispatcher functions available to service writers:


chap31.gif

Figure 18. Natural Access Software Structure

3.6 Natural Access Coding ConventionsTop of Page

The conventions in this section must be followed when writing the service interface for a Natural Access service. Natural Access includes conventions for:

3.6.1 Function NamesTop of Page

All API functions for the service begin with the service's three letter acronym (e.g., adiStartCallProgress).

For each API function, the corresponding SPI function and implementation function must use the following naming convention:


chap32.gif

Figure 19. API and SPI Function Names


The naming convention for the managed resource event handler is xxxFetchAndProcess. All other functions should follow the convention xxxFunctionDescription.

3.6.2 Function ArgumentsTop of Page

Arguments to functions may be one of the following types:
Argument Type

Description

in

Argument provides an input value for the function.

out

Argument is a buffer to place output from the function.

inout

Argument is both and input value and an output buffer for the function.

Use of inout arguments is not recommended.

In arguments should precede inout and out arguments whenever possible.

Argument names should be lower case without underscores. Underscores may be used if the argument name is long and would be unreadable or misread without them. Arguments should be weakly typed (int, unsigned, etc.) instead of strongly typed (INT32, DWORD, etc.).

3.6.3 Return ValuesTop of Page

All Natural Access functions return a status code that can be either SUCCESS, CTAERR_something, or XXXERR_something. Any other information returned from a function should be handled via out arguments.

A return value of SUCCESS for an asynchronous function means that the function request was initiated. The function subsequently may fail and return an error in an event. For a synchronous (short term blocking) function, there are no events returned and SUCCESS means that the command completed with no errors.

When defining return codes, reuse existing Natural Access return and error codes as much as possible (i.e., CTAERR_something).

3.6.4 Event and Reason NamesTop of Page

Events for a service must be named XXXEVN_something.

The event structure contains a value field which can further classify an event by providing additional information (e.g., an error code).

To further classify a DONE event, the value field may contain a reason code. Reasons for a service must be named XXX_REASON_something. Reasons are typically used to indicate an application error (e.g., the network is down). Error codes typically indicate a programming problem.

When defining the service events and reasons, one should attempt to reuse existing Natural Access event and reason codes as much as possible.

3.6.5 Error, Reason, Event, Command, and Trace Tag CodesTop of Page

Error, reason, event, command, and trace tag codes are constructed using the service ID, a type code (to distinguish between errors, events, commands, or reasons), and a sequence number.

The following table lists the valid range of types as defined in ctadef.h:

Description

Sequence Range

Type Code

Error codes

0x0000-0x0FFF

CTA_CODE_ERROR (0x0000)

Reason codes

0x1000-0x1FFF

CTA_CODE_REASON (0x1000)

Event codes

0x2000-0x2FFF

CTA_CODE_EVENT (0x2000)

Command codes

0x3000-0x3FFF

CTA_CODE_COMMAND (0x3000)

Trace tag codes

0x4000-0x4FFF

CTA_CODE_TRACETAG (0x4000)

Natural Access macros are used to assign an error/reason/event/command/tracetag code. A code is constructed by using the service ID, the type code, and a sequence number as shown below:

  (( service_id << 16 ) | type_code | sequence )
For example, assigning an ADI service error code:

 #define ADIERR_PLAYREC_ACCESS         (( ADI_SVCID << 16 ) | CTA_CODE_ERROR | 1 )

To facilitate browsing, the defines are typically assigned to the resultant hexadecimal number rather than constructed .

Note: DONE events range from 0x2100-0x2FFF.

3.6.6 Manifest Constants and EnumsTop of Page

The naming convention for enumerations is the same as for manifest constants. Names are in all capital letters. The service acronym is separated from the manifest by an underscore. Underscores should be used freely to separate words to make the manifests and enumeration names more readable. For example:

#define CTA_UNITS_INTERNAL  0
#define CTA_UNITS_INTEGER 1

typedef enum { CTA_TRACE_SEVERITY_INFO=0,
CTA_TRACE_SEVERITY_WARNING,
CTA_TRACE_SEVERITY_ERROR} CTA_TRACE_SEVERITY;

#define VCE_FILETYPE_AUTO 0
#define VCE_FILETYPE_VOX 1
#define VCE_FILETYPE_WAVE 2
#define VCE_FILETYPE_FLAT 3

3.6.7 StructuresTop of Page

Structures should include a size field as the first field. The size of the structure should be passed as an extra argument if the structure is an out argument and the size field of the structure will be filled with the output size. Structure fields must be strongly typed (i.e., INT32, DWORD, etc.) for compatibility between libraries and applications.

For backward compatibility, structure fields should never be removed, only added.

Each field within a structure must use 4 byte packing (i.e., must begin on a four byte boundary). The total size of the structure must be a multiple of 4 bytes, in case an application uses 1 or 2 byte packing.

Structure names (typedefs) should be all upper case with underscores to improve readability.

Structure field names should be all lower case with no underscores unless needed for readability.

Parameter structures must have fields that can be classified into one of the valid parameter field types (see ctaGetParmInfo for a list of valid field descriptors).

3.6.8 Parameter Structure Naming ConventionTop of Page

Parameter structures that are arguments to a service API function call must follow the xxx_PARMS naming convention. For example, the ADI function to start playing requires the ADI_PLAY_PARMS data structure.

If the value of the parameter passed via the API function call is NULL, the service implementation uses the context default values.

3.7 Writing a ServiceTop of Page

There are two phases in writing a service: the definition phase and the implementation phase. During the definition phase the requirements of the managed resource are defined. During the implementation phase, the actual software components for the service are developed and tested.

3.7.1 Defining a ServiceTop of Page

To define a service:

Step

To...

See...

1.

Understand the managed resource and how to best interact with it

Section 4.2, Understanding the Managed Resource

2.

Design an interface (a set of API function calls and their associated errors, events, and reasons)

Section 4.4, Defining the API

Section 4.5, Defining Events and Reasons

Section 4.6, Defining Errors

Section 4.7, Defining Parameters

3.

Determine the tracing capability for debugging purposes

Section 4.8, Defining Tracing

3.7.2 Implementing a ServiceTop of Page

To implement a service:

Step

To...

See...

1.

Write the service API

Chapter 5 - Implementing the API

2.

Write the service SPI

Chapter 6 - Implementing the SPI

3.

Implement the service manager functions for initialization and shut down

Section 7.4, Service Registration

Section 7.5, Initializing Managed Resource Event Handling

Section 7.6, Service Startup

Section 7.7, Event Handling Shutdown

Section 7.8, Service Shutdown

4.

Implement the service manager functions for command and event processing

Section 7.9.1, Command Processing

Section 7.9.4, Event Processing

5.

Implement the service manager functions for tracing and error handling

Section 7.9.2, Error Handling

Section 7.9.3, Trace Handling

6.

Implement the service functions which interact with the managed resource

Section 8.2, Implementing Service Functions

3.8 Sample Natural Access ServiceTop of Page

The Natural Access Service Writer's Manual is accompanied by source code to the TIK sample service. The goal of the TIK service is to embed software timer functionality (i.e., "ticker") into Natural Access by:

The implementation of the software timer is meant to model a physical device. It sends a command to the device and get asynchronous messages back. From an application's perspective, the software timer is simply another managed resource available under Natural Access as shown in Figure 20.


chap34.gif

Figure 20. Software Timer Service Architecture


In subsequent chapters of this manual, each phase of writing a Natural Access service will be illustrated using code fragments from the TIK service. All TIK-specific information is displayed in a "TIK service" section similar to the following:


chap33.gif
tik service

tik example information

All source code for the TIK service is provided as part of the Natural Access Developer's Kit and can be found in the nms\ctaccess\demos\tiksvc directory. Refer to this source code as you read the information about creating a Natural Access service.

The TIK service includes the following files:
File

Description

tikapi.c

Implements the service API by calling the corresponding SPI function and handling API errors.

tikspi.c

Implements the service SPI functions.

tikdef.h

Contains API data structures, function prototypes, and definitions.

tikspi.h

Contains SPI function prototypes.

tikbnd.c

Implements the service manager binding functions.

tikcmd.c

Implements the service functions which interface to the managed resource.

tikcomms.c

Contains communication logic to TICK server (i.e., "driver interface").

tikutils.c

Contains miscellaneous functions.

tikparm.pf

ASCII parameter definition file (used to generate tikparm.c and tikparm.h).

tiksys.h

Contains internal data structures, function prototypes, and definitions.

tikapi.def

Windows NT export definition file for TIK API.

tikmgr.def

Windows NT export definition file for TIK service manager.

makefile

Makefile to build the TIK service.

3.8.1 Template Source FilesTop of Page

To facilitate writing a service, a set of template source files (based on the TIK service) is provided in nms\ctaccess\template\ctatmplt.

Template files exist for each of the files listed in the previous table. Use these skeleton template files to start constructing a new service.



Table of Contents NMS Glossary Previous Page Next Page Version


Want to send us feedback on our documentation? Email: Tech_Pubs@nmss.com
Copyright © 2001, Natural MicroSystems, Inc. All rights reserved.