Migration guide from 0.4 to 0.5

Between libfreespace 0.4 and libfreespace 0.5, Hillcrest introduced the FSP200 family of Freespace processors.  This family uses a slightly different set of HID messages than the previous FSP160 series, and libfreespace 0.5 now supports both message formats.  Migrating to the new libfreespace version is straightfoward with only a few minor changes to the application code. 

The libfreespace 0.5 release changes the message representation from raw character arrays to well-defined structures.  The libfreespace 0.4 release contained these same structures, but their use was optional.  With 0.5, the API enforces the use of these structures which will allow future message format changes to be hidden from thh API.  The change impacts the send and receive message functions that now handle the parsing and packing of data as appropriate for the target device. For most applications, the code is now simpler.  Below are examples of how to port libfreespace 0.4 code to libfreespace 0.5:

Synchronous Send - libfreespace 0.4

struct freespace_DataMotionControl d;
uint8_t buffer[FREESPACE_MAX_OUTPUT_MESSAGE_SIZE];
...
memset(&d, 0, sizeof(d));
d.enableBodyMotion = 1;
rc = freespace_encodeDataMotionControl(&d, buffer, sizeof(buffer));
if (rc > 0) {
    rc = freespace_send(device, buffer, rc);
    if (rc != FREESPACE_SUCCESS) {
        printf("Could not send message: %d.\n", rc);
    }
} else {
    printf("Could not encode message.\n");
}

Synchronous Send - libfreespace 0.5

struct freespace_message message;
...
memset(&message, 0, sizeof(message));
message.messageType = FREESPACE_MESSAGE_DATAMODEREQUEST;
message.dataModeRequest.enableBodyMotion = 1;
rc = freespace_sendMessage(device, &message);
if (rc != FREESPACE_SUCCESS) {
    printf("Could not send message: %d.\n", rc);
}

Synchronous Receive - libfreespace 0.4

struct freespace_UserFrame user;
uint8_t buffer[FREESPACE_MAX_INPUT_MESSAGE_SIZE];
...
rc = freespace_read(device, buffer, sizeof(buffer), 1000 /* 1 second timeout */, &length);
if (rc == FREESPACE_ERROR_TIMEOUT ||
    rc == FREESPACE_ERROR_INTERRUPTED) {
    continue;
}
if (rc != FREESPACE_SUCCESS) {
    printf("Error reading: %d. Trying again after a second...\n", rc);
    sleep(1);
    continue;
}
// Check if this is a user frame message.
if (freespace_decodeUserFrame(buffer, length, &user) == FREESPACE_SUCCESS) {
    if (user.button1) {
        // Processing here
    }
}

Synchronous Receive - libfreespace 0.5

struct freespace_message m;
...
rc = freespace_readMessage(device, &m, 1000 /* 1 second timeout */);
if (rc == FREESPACE_ERROR_TIMEOUT ||
    rc == FREESPACE_ERROR_INTERRUPTED) {
    continue;
}
if (rc != FREESPACE_SUCCESS) {
    printf("Error reading: %d. Trying again after a second...\n", rc);
    sleep(1);
    continue;
}

// Check if this is a user frame message.
if (m.messageType == FREESPACE_MESSAGE_USERFRAME) {
    if (m.userFrame.button1) {
        // Processing here
    }
}

Why the change?

Due to the message changes, sending and receiving encoded byte streams required that the HID version of the device be queried to choose the proper encoding.

Rather than forcing the programmer to query the HID version, libfreespace now supports sending and receiving message structures instead of byte streams.  The encoding and decoding are done internally by libfreespace automatically.  The programmer no longer has to call a message-specific encode function.  Instead, the programmer fills in the structure, as had been done in libfreespace 0.4, and fills the message type into the structure, and this structure is sent directly.  Each byte stream-based send and receive function has a corresponding message-based send and receive function.