C API Reference
ABI-stable C interface defined in Reader/Reader_C.h. Provides extern "C" linkage for FFI from C, C#, Python, Rust, and other languages.
The C API uses extern "C" linkage for ABI stability but is typically consumed from C++ source files. The examples and type signatures below use C++ syntax for namespace-qualified types (e.g. RikCommon::ReaderDefinition).
Header
#include "Reader/Reader_C.h"
Handle Types
Opaque pointer types used to reference reader instances.
typedef struct Reader_Handle* ReaderPtr;
The ReaderPtr handle is used for all common methods and reader-specific functions.
Error Handling
Every function takes RikResult& rikResult as its first parameter. Check rikResult.HasException after each call.
RikResult
typedef struct {
bool HasException;
char ExceptionType[256];
char Message[2048];
char FileName[2048];
int LineNumber;
char FunctionName[256];
bool HasProtocolException;
char ProtocolExceptionType[256];
char ProtocolMessage[2048];
char ProtocolFileName[2048];
int ProtocolLineNumber;
char ProtocolFunctionName[256];
} RikResult;
| Field | Description |
|---|---|
HasException | true if the call failed |
ExceptionType | Exception class name |
Message | Human-readable error description |
FileName | Source file where the error originated |
LineNumber | Line number of the error |
FunctionName | Function that raised the error |
HasProtocolException | true if a protocol-level error also occurred |
Protocol* | Matching fields for the inner protocol exception |
Usage pattern:
RikResult result = {0};
Rik_Init(result, handle);
if (result.HasException) {
fprintf(stderr, "Error: %s\n", result.Message);
fprintf(stderr, " at %s:%d in %s\n",
result.FileName, result.LineNumber, result.FunctionName);
if (result.HasProtocolException) {
fprintf(stderr, "Protocol error: %s\n", result.ProtocolMessage);
}
}
Factory Functions
RikReader_Open
Opens a connection to a reader.
ReaderPtr RikReader_Open(
RikResult& rikResult,
const RikCommon::ReaderDefinition& readerDefinition,
int retryCount);
| Parameter | Type | Description |
|---|---|---|
rikResult | RikResult& | Error output |
readerDefinition | const ReaderDefinition& | Reader connection parameters |
retryCount | int | Number of connection retry attempts |
Returns: Handle to the reader instance, or NULL on failure.
Common Methods
These functions accept any ReaderPtr.
Rik_Close
Closes the reader connection and destroys the handle.
void Rik_Close(RikResult& rikResult, ReaderPtr handle);
Always call Rik_Close when finished, even if earlier operations failed.
Rik_Init
Initializes the reader after opening. Must be called before any other operations.
void Rik_Init(RikResult& rikResult, ReaderPtr handle);
Rik_RefreshMetadata
Forces a refresh of cached reader metadata from the device.
void Rik_RefreshMetadata(RikResult& rikResult, ReaderPtr handle);
Rik_GetMetadataStruct
Retrieves reader metadata (part number, serial, firmware version, etc.).
void Rik_GetMetadataStruct(
RikResult& rikResult,
ReaderPtr handle,
ReaderMetadataStruct* outStruct,
bool forceRefresh = false);
| Parameter | Type | Description |
|---|---|---|
rikResult | RikResult& | Error output |
handle | ReaderPtr | Reader handle |
outStruct | ReaderMetadataStruct* | Output buffer for metadata |
forceRefresh | bool | Bypass cache and query device (default: false) |
Reader Methods
All reader methods require a ReaderPtr handle.
RikReader_Beep
Causes the reader to beep.
void RikReader_Beep(
RikResult& rikResult,
ReaderPtr handle,
uint8_t beepCount,
uint8_t duration);
| Parameter | Type | Description |
|---|---|---|
beepCount | uint8_t | Number of beeps |
duration | uint8_t | Beep duration enum value |
RikReader_GetCardData
Reads raw card data from the reader.
void RikReader_GetCardData(
RikResult& rikResult,
ReaderPtr handle,
uint8_t* cardDataOut,
size_t bufferLength,
uint32_t& bitCount,
RikProtocol::GetCardDataSizeParameters sizeParameter = RikProtocol::READ_32_BYTES);
| Parameter | Type | Description |
|---|---|---|
cardDataOut | uint8_t* | Output buffer for card bytes |
bufferLength | size_t | Size of the output buffer |
bitCount | uint32_t& | Output: number of valid bits read |
sizeParameter | RikProtocol::GetCardDataSizeParameters | Optional. Read size; defaults to RikProtocol::READ_32_BYTES. See GetCardDataSizeParameters. |
RikProtocol::READ_8_BYTES returns at most the first 8 bytes of the credential. The output buffer is still 32 bytes of card data: bytes 0–7 hold the returned data and bytes 8–31 are zero. bitCount always reports the full credential width, so a bit count greater than 64 means the card carries more data than was returned. Prefer RikProtocol::READ_32_BYTES. Reader_C.h is a C++ header with extern "C" linkage; C++ callers may omit sizeParameter because of the default argument.
RikReader_EnableKeystroking
Enables or disables keystroking.
void RikReader_EnableKeystroking(
RikResult& rikResult,
ReaderPtr handle,
bool enable);
RikReader_EnableTransparentMode
Enables or disables transparent mode. The writeToFlash parameter controls whether the setting persists across reader power cycles.
void RikReader_EnableTransparentMode(
RikResult& rikResult,
ReaderPtr handle,
uint8_t enable,
uint8_t writeToFlash);
RikReader_GetTransparentModeStatus
Returns the current transparent mode state and readiness status.
void RikReader_GetTransparentModeStatus(
RikResult& rikResult,
ReaderPtr handle,
RikProtocol::TransparentModeState& state,
RikProtocol::TransparentModeStatus& status);
RikReader_GetBeeperVolume / SetBeeperVolume
void RikReader_GetBeeperVolume(
RikResult& rikResult,
ReaderPtr handle,
uint8_t& volume);
void RikReader_SetBeeperVolume(
RikResult& rikResult,
ReaderPtr handle,
uint8_t volume);
RikReader_GetReaderConfiguration / SetReaderConfiguration
void RikReader_GetReaderConfiguration(
RikResult& rikResult,
ReaderPtr handle,
const uint8_t configNum,
ReaderConfigurationStruct& config,
ExtendedConfiguration& extConfig);
void RikReader_SetReaderConfiguration(
RikResult& rikResult,
ReaderPtr handle,
const uint8_t configNum,
const ReaderConfigurationStruct& config,
const ExtendedConfiguration& extConfig,
const HashData* hashData = nullptr);
| Parameter | Type | Description |
|---|---|---|
configNum | uint8_t | Configuration slot number |
config | ReaderConfigurationStruct& | Reader configuration data |
extConfig | ExtendedConfiguration& | Extended configuration data |
hashData | const HashData* | Optional hash data (Set only, default: nullptr) |
RikReader_GetModuleState / SetModuleState
void RikReader_GetModuleState(
RikResult& rikResult,
ReaderPtr handle,
uint8_t moduleId,
uint32_t& state);
void RikReader_SetModuleState(
RikResult& rikResult,
ReaderPtr handle,
uint8_t moduleId,
uint32_t state);
RikReader_GetLedConfiguration / SetLedConfiguration
void RikReader_GetLedConfiguration(
RikResult& rikResult,
ReaderPtr handle,
uint8_t configNum,
LedConfiguration& ledConfig);
void RikReader_SetLedConfiguration(
RikResult& rikResult,
ReaderPtr handle,
uint8_t configNum,
const LedConfiguration& ledConfig);
RikReader_GetLuid / SetLuid
void RikReader_GetLuid(
RikResult& rikResult,
ReaderPtr handle,
LuidResponseInformation& luidInfo);
void RikReader_SetLuid(
RikResult& rikResult,
ReaderPtr handle,
uint16_t luid);
RikReader_GetSupportedCardTypes
void RikReader_GetSupportedCardTypes(
RikResult& rikResult,
ReaderPtr handle,
SupportedCardTypesResult* outResult);
RikReader_OnCredentialPresented
Registers a callback that fires when a card is presented to the reader. The library polls on a background thread and invokes the callback on the leading edge of card presence.
typedef void (*CredentialCallback)(const uint8_t* cardData, uint32_t bitCount);
uint32_t RikReader_OnCredentialPresented(
RikResult& rikResult,
ReaderPtr handle,
CredentialCallback callback,
RikProtocol::GetCardDataSizeParameters sizeParameter = RikProtocol::READ_32_BYTES);
| Parameter | Type | Description |
|---|---|---|
rikResult | RikResult& | Error output |
handle | ReaderPtr | Reader handle |
callback | CredentialCallback | Function pointer called with card data and bit count |
sizeParameter | RikProtocol::GetCardDataSizeParameters | Optional. Read size used by the shared polling thread; defaults to RikProtocol::READ_32_BYTES. See GetCardDataSizeParameters. |
Returns: Subscription ID (0 on error).
There is one read size per reader instance. A later RikReader_OnCredentialPresented call with a different sizeParameter changes the payload delivered to all existing subscribers on that reader.
RikReader_UnsubscribeCredentialCallback
Removes a previously registered credential callback.
void RikReader_UnsubscribeCredentialCallback(
RikResult& rikResult,
ReaderPtr handle,
uint32_t subscriptionId);
| Parameter | Type | Description |
|---|---|---|
rikResult | RikResult& | Error output |
handle | ReaderPtr | Reader handle |
subscriptionId | uint32_t | ID returned by RikReader_OnCredentialPresented |
RikReader_ReadBleConfigurationFromReader / WriteBleConfigurationToReader
void RikReader_ReadBleConfigurationFromReader(
RikResult& rikResult,
ReaderPtr handle,
uint8_t dataType,
const char* fileName);
void RikReader_WriteBleConfigurationToReader(
RikResult& rikResult,
ReaderPtr handle,
uint8_t dataType,
const char* fileName);
| Parameter | Type | Description |
|---|---|---|
dataType | uint8_t | BLE data type identifier |
fileName | const char* | Path to the BLE configuration file |
RikReader_WriteUserDefaultsToReader
Copies the reader's active flash configuration to stored (user-default) flash.
void RikReader_WriteUserDefaultsToReader(
RikResult& rikResult,
ReaderPtr handle);
RikReader_ResetReaderConfiguration
Resets the reader configuration to a checkpoint.
void RikReader_ResetReaderConfiguration(
RikResult& rikResult,
ReaderPtr handle,
uint8_t checkpointType);
| Parameter | Type | Description |
|---|---|---|
checkpointType | uint8_t | Checkpoint to restore (1 = FactoryDefaults, 2 = UserSettings) |
RikReader_WriteHwgFileToReader / ReadHwgFileFromReader
Writes an HWG configuration file to the reader, or reads the current configuration from the reader into an HWG file.
void RikReader_WriteHwgFileToReader(
RikResult& rikResult,
ReaderPtr handle,
const char* fileName);
void RikReader_ReadHwgFileFromReader(
RikResult& rikResult,
ReaderPtr handle,
const char* fileName,
bool secureHwgFormat = true);
| Parameter | Type | Description |
|---|---|---|
fileName | const char* | Path to the HWG file |
secureHwgFormat | bool | Read only. If true (default), writes the AES-128 encrypted format |
RikReader_WriteSmartCardConfigurationToReader / ReadSmartCardConfigurationFromReader
Writes a smart card configuration file to the reader, or reads the reader's smart card configuration into the provided struct.
void RikReader_WriteSmartCardConfigurationToReader(
RikResult& rikResult,
ReaderPtr handle,
const char* fileName);
void RikReader_ReadSmartCardConfigurationFromReader(
RikResult& rikResult,
ReaderPtr handle,
RikCommon::SmartCardConfigurationStruct& configuration);
| Parameter | Type | Description |
|---|---|---|
fileName | const char* | Write only. Path to the smart card configuration file |
configuration | SmartCardConfigurationStruct& | Read only. Output: smart card configuration read from the reader |
Reader Discovery
Standalone function -- no handle required.
Rik_DiscoverUsbReaders
Discovers all connected rf IDEAS USB readers. Uses a two-call pattern: call first with readers set to nullptr to get the count, then allocate a buffer and call again to retrieve the results.
void Rik_DiscoverUsbReaders(
RikResult& rikResult,
RikCommon::ReaderDefinition* readers,
size_t* readerCount);
| Parameter | Type | Description |
|---|---|---|
rikResult | RikResult& | Error output |
readers | ReaderDefinition* | Output buffer, or nullptr to query count only |
readerCount | size_t* | In/out: buffer size on input, number of readers found on output |
Each returned ReaderDefinition has DeviceId.VendorId, DeviceId.ProductId, DeviceId.UsbPath, DeviceId.SerialNumber, and ProtocolType populated and can be passed directly to RikReader_Open.
RikResult result = {0};
size_t count = 0;
// First call: get count
Rik_DiscoverUsbReaders(result, nullptr, &count);
if (result.HasException || count == 0) return;
// Second call: retrieve readers
RikCommon::ReaderDefinition* readers =
(RikCommon::ReaderDefinition*)calloc(count, sizeof(RikCommon::ReaderDefinition));
Rik_DiscoverUsbReaders(result, readers, &count);
if (!result.HasException) {
for (size_t i = 0; i < count; i++) {
printf("Reader %zu: VID=%04X PID=%04X Path=%s\n",
i, readers[i].DeviceId.VendorId,
readers[i].DeviceId.ProductId,
readers[i].DeviceId.UsbPath);
}
}
free(readers);
See Discovering USB Readers for a full walkthrough.
Library Info
Standalone function -- no handle required.
LibraryInfo Rik_BuildLibraryInfo();
Returns: LibraryInfo struct containing version and build information.
LibraryInfo info = Rik_BuildLibraryInfo();
printf("RIK %s\n", info.VersionString);
Examples
Open, Init, Use, Close
#include <stdio.h>
#include "Reader/Reader_C.h"
int main() {
RikResult result = {0};
// 1. Open
RikCommon::ReaderDefinition readerDef = {0};
readerDef.DeviceId.VendorId = 0x0C27;
readerDef.DeviceId.ProductId = 0x3BFA;
readerDef.ProtocolType = PROTOCOL_TYPE_FEATURE_REPORT;
ReaderPtr handle = RikReader_Open(result, readerDef, 3);
if (result.HasException) {
fprintf(stderr, "Open failed: %s\n", result.Message);
return 1;
}
// 2. Init
Rik_Init(result, handle);
if (result.HasException) {
fprintf(stderr, "Init failed: %s\n", result.Message);
Rik_Close(result, handle);
return 1;
}
// 3. Use -- read metadata
ReaderMetadataStruct metadata = {0};
Rik_GetMetadataStruct(result, handle, &metadata, false);
if (!result.HasException) {
printf("Part Number: %s\n", metadata.PartNumber);
printf("Serial: %s\n", metadata.ESN);
}
// 3. Use -- beep
RikReader_Beep(result, handle, 2, BEEP_DURATION_SHORT);
// 4. Close
Rik_Close(result, handle);
return 0;
}
Error Handling with Goto Cleanup
int configure_reader(const RikCommon::ReaderDefinition* readerDef) {
RikResult result = {0};
int rc = 0;
ReaderPtr handle = RikReader_Open(result, *readerDef, 3);
if (result.HasException) { rc = 1; goto done; }
Rik_Init(result, handle);
if (result.HasException) { rc = 1; goto cleanup; }
// Disable keystroking
RikReader_EnableKeystroking(result, handle, false);
if (result.HasException) { rc = 1; goto cleanup; }
printf("Reader configured successfully\n");
cleanup:
{
RikResult closeResult = {0};
Rik_Close(closeResult, handle);
}
done:
if (rc != 0) {
fprintf(stderr, "Error: %s\n", result.Message);
}
return rc;
}
Reading Card Data
void poll_card(ReaderPtr handle) {
RikResult result = {0};
uint8_t cardBuffer[64] = {0};
uint32_t bitCount = 0;
RikReader_GetCardData(result, handle, cardBuffer, sizeof(cardBuffer), bitCount);
if (result.HasException) {
fprintf(stderr, "Card read error: %s\n", result.Message);
return;
}
if (bitCount == 0) {
printf("No card present\n");
return;
}
printf("Card data (%u bits):", bitCount);
size_t byteCount = (bitCount + 7) / 8;
for (size_t i = 0; i < byteCount; i++) {
printf(" %02X", cardBuffer[i]);
}
printf("\n");
}
uint8_t cardBuffer[32] = {0};
uint32_t bitCount = 0;
// 8-byte read
RikReader_GetCardData(result, handle, cardBuffer, sizeof(cardBuffer), bitCount,
RikProtocol::READ_8_BYTES);
if (bitCount > 64) {
// bytes 8-31 are zero; data was truncated
}
See Also
- AbstractReader (C++)
- Reader (C++)
- Exceptions -- C++ exception model that
RikResultmaps from - C API Usage Examples
- ReaderDefinition