CHAILink SDK  Version 1.3
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
CHAI vs CHAILink Client

Almost all CHAI functionalities are available when using the CHAILink Client SDK, but its architecture implies differences in programming models.


In the CHAILink Client, CHAI objects are manipulated through their handle and not via their interface pointer. There are two types of handle:

  • CPHOBJECT for standard CHAI objects like Devices, Inputs, ...
  • CPHOOKEDOBJECT for hooked objects like Messages, Remote Devices, ...

An exception exists for performance messages (Event, Modifier, Selector, ...). These are handled directly and their message data are transferred in data structures (see CPEVENTMSG, CPMODIFIERMSG, ...).


In the CHAILink, instead of calling a method from an interface pointer, a function is called with the object handle as its first parameter. Each CHAILink function return a standard code (CLC_ErrorCode), CopperLan return codes (CPNS::Enums::Errors in CHAI Errors in CHAILink) and Boolean return codes are included in this CHAILink return code:

  • For Boolean return code, the CHAILink return code is ERR_None or CLC_ErrorCode_Success for TRUE and ERR_Failed for FALSE.
  • For CopperLan return code, the CHAILink return codes from 0x01 to 0xFF are reserved and mapped to Errors enumeration.



CPNS::IOutput * pOutput;
CPNS::CEndPoint destination;
CPNS::Enums::Errors CPError = pOutput->RemoveDestination(destination);


CPENDPINT destination
err = Output_RemoveDestination(hOutput, FALSE, &destination);

For object numeric properties, the CHAILink typically uses a function called xxx_GetInfo to retrieve all these parameters in one call to the CHAI.



CPNS::IOutput * pOutput;


CLC_OutputInfo outputInfo;
err = Output_GetInfo(hOutput, &outputInfo);

Notifications and Asynchronous Returns


In the standard CHAI SDK, usually, to register a notification on an object, a method is called with an interface pointer as parameter. This interface pointer contains a set of handler called when the object wants to notify the application. In CHAILink Client, notifications are global. Each notification has a unique callback function associated to it, and all instances use it. To identify the source of the notification, the object handle is passed as the first parameter of the callback function. The second parameter of the notification is a 32 bit data associated by the application to the handle during the object creation. All the notifications (callback function pointer) are stored in a CLC_NH_CallbackList structure and are passed to the CHAILink Client during initialization (see CLC_Init and CLC_Callbacks for more information). Except for the CHAI which is unique, the notifications are enabled independently per object even if the same Callback function pointer is used for all instances.

Example: Registration of the Notification Handler for an ILocalDevice


virtual void RegisterNotificationHandler(IN CPNS::IBaseLocalDevice_NotificationHandler * const pHandler) = 0;


Asynchronous Return

Asynchronous Returns for Asynchronous Calls also differ from standard CHAI development in some points:

  • As for Notifications, Asynchronous Returns have only one handler per Asynchronous Call. These handlers (or callback functions) are stored in a CLC_ARH_CallbackList structure and are passed to the CJHAILink Client during initilization (see CLC_Init and CLC_Callbacks for more informations).
  • More than one Asynchronous Call can be performed simultaneously and Asynchronous Returns may come back in different order. In order to differentiate calls, a Custom parameter is passed during the Asynchronous Call and is passed back during the corresponding Asynchronous Return. This parameter is named dwClientContextData.
  • The Asynchronous Handle retrieved during an asynchronous call is no more valid during the Asynchronous Return. It only serves to cancel the operation before it returns by using Async_CancelTask.

Example: The GetNamAsync call on a IRemoteDevice


virtual CPNS::IAsync* GetName_Async(
IN CPNS::IRemoteDevice_GetName_AsyncReturnHandler * const pHandler,
IN void* const pUserPointer
) = 0;


CPHOOKEDOBJECT const hRemoteDevice,
DeviceProperties const propertyID,
CPUINT32 const dwClientContextData,
CPHASYNC * const phAsync);


Contrarily to the CHAI, the CHAILink Client is designed to work in a cooperative single threaded environment, with or without OS.