Section 7.2 - Creating a Custom Device

In many (but not all) cases, you will need to define both a file manager and a device for the manager to communicate with/through. For example, the FTP file manager requires a device, and so would supporting a DDR such as an Accom.

As usual, the device is defined through a structure, the definition of which is contained in CPI_DeviceProvider.h. Here is an example of the structure, as defined for the FTP device used in the supplied sample (required entries are shown in bold; optional entries can be filled in with NULL):

static RPI_DeviceInfo dinfo = {
    {
        "ftp",                  // Internal name
        "FTP File System",      // Not used
        "Silicon Grail",        // Author - not used
        "1.0",                  // Version string - not used
         NULL, NULL             // Help strings - not used
    },

    FTPOpen,                    // Open device
    FTPClose,                   // Close device
    FTPIsOpen,                  // Device is open
    FTPSync,                    // Sync device
    FTPGetPos,                  // Get position
    FTPSetPos,                  // Set position
    FTPGetFileLength,           // Get file length
    FTPRead,                    // Read device
    FTPWrite                    // Write device
};
The function signatures and the uses of each function are given below. Theys pass around a CPI_PrivateData structure which is user-defined, and which should contain any pertinent information about the file or device with is being handled.

For example, the FTP device uses the following private data structure:

typedef struct _deviceState
{
    netbuf              *nControl;    //Our control handle
    netbuf              *fileHandle;
    CPI_Bool             isConnected;
    CPI_Int64            myFileOffset;
    CPI_Uint64           myFileSize;
    char                 userName[256];
    char                 userPass[256];
    char                 servername[CPI_PATH_LENGTH];
    int                  openFlags;
    char                *filePath;
    char                *localPath;
    CPI_DeviceHandle     localDevice;
    CPI_Bool             isWrite;
    CPI_Bool             isRead;
} deviceState;
The complete source for this example is supplied in the file_manager directory of the plugin examples.

Internal Name - This is the name used to reference the device from the File Manager. It should be identical to the string returned by the function GetDeviceName in the File Manager structure.

Label - Any text string.

Author - Any text string.

Version - This is not used by RAYZ, but is available to the programmer.

Help Strings - These are not used, and should be set to NULL.

Open Device - This opens the device. The signature of the function is

CPI_PrivateData  DeviceOpen( CPI_Metadata data );
The passed in metadata will have been set up via the File Manager plugin, and will contain all of the necessary information about the file to open. The returned data structure is user-created, and should contain any information necessary to use this file (device) in the future, such as a file handle. This structure should be allocated here in the open function.

For example, here is a code fragment from the FTPdevice example

CPI_PrivateData
FTPOpen( CPI_Metadata data )
{
    deviceState *dev = (deviceState *)cpiAlloc( sizeof( deviceState ) );

    dev->filePath = (char *)cpiAlloc( CPI_PATH_LENGTH );

    // Get the neccessary information from the metadata
    cpiGetFilename( data, dev->filePath, CPI_PATH_LENGTH );
    cpiGetMetaString( data, "SERVERNAME", dev->servername, CPI_PATH_LENGTH );
    cpiGetMetaString( data, "USERNAME", dev->userName, 256 );
    cpiGetMetaString( data, "PASSWORD", dev->userPass, 256 );

    cpiGetRead( data, &dev->isRead );
    cpiGetWrite( data, &dev->isWrite );

    if ( dev->isRead )
    {
...
The calls to cpiGetRead() and cpiGetWrite() are calls to retrieve metadata boolean values to indicate whether the file is to be opened for reading and/or writing. The other metadata strings (SERVERNAME, etc) are user-created. The filename also comes from a metadata call, cpiGetFilename().

Close Device - Closes the device described in the private data structure. This structure should probably be freed in this routine.

void  DeviceClose( CPI_PrivateData device );

Device is Open - Returns CPI_TRUE if the specified file is open, CPI_FALSE if not.

CPI_Bool  DeviceIsOpen( CPI_PrivateData device );

Sync Device - Sync the specified file.

void  DeviceSync( CPI_PrivateData device );

Get Position - Returns the position (in bytes) that we are from the start of the file.

CPI_Uint64  DeviceGetPos( CPI_PrivateData device );

Set Position - Sets the file to the specified position.

CPI_Uint64  DeviceSetPos( CPI_PrivateData  device,
                          CPI_Int64        pos,
                          CPI_Uint8        whence );
The position is an offset given in bytes. The 'whence' value is the where the offset is relative to:
CPI_SEEK_START - the start of the file
CPI_SEEK_CUR - the current position in the file
CPI_SEEK_END - the end of the file
The function should return the position (in bytes) where we are from the start of the file after being moved to the new position. You should return -1 for failure.

Get File Length - Sets the length of the current file. Returns CPI_TRUE for success, else CPI_FALSE.

CPI_Bool DeviceLength( CPI_PrivateData  device,
                       CPI_Uint64      *length );

Read Device - Read 'count' bytes into the supplied buffer, from the given device. Should return the number of bytes actually read (-1 for failure).

CPI_Uint64 DeviceRead( CPI_PrivateData  device,
                       void            *buffer,
                       CPI_Uint64       count );

Write Device - Write 'count' bytes of buffer to the device. Return the number of bytes actually written, or -1 for failure.

CPI_Uint64  DeviceWrite( CPI_PrivateData  device,
                         const void      *buffer,
                         CPI_Uint64       count );


[Previous Page] [Next Page]
[Table of Contents] [Index]

Copyright © 2002 Silicon Grail Inc.
736 Seward Street, Hollywood, CA 90038