LIBFREESPACE_API int freespace_sendMessage(FreespaceDeviceId id,
                                           struct freespace_message* message) {

    int retVal;
    uint8_t msgBuf[FREESPACE_MAX_OUTPUT_MESSAGE_SIZE];
    struct FreespaceDeviceInfo info;

    memset(msgBuf, 0, sizeof(msgBuf));
    
    // Address is reserved for now and must be set to 0 by the caller.
    if (message->dest == 0) {
        message->dest = FREESPACE_RESERVED_ADDRESS;
    }

    retVal = freespace_getDeviceInfo(id, &info);
    if (retVal != FREESPACE_SUCCESS) {
        return retVal;
    }
    
    message->ver = info.hVer;
    retVal = freespace_encode_message(message, msgBuf, FREESPACE_MAX_OUTPUT_MESSAGE_SIZE);
    if (retVal <= FREESPACE_SUCCESS) {
        return retVal;
    }
    
    return freespace_private_send(id, msgBuf, retVal);
}
Example #2
0
int freespace_private_sendAsync(FreespaceDeviceId id,
                                const uint8_t* message,
                                int length,
                                unsigned int timeoutMs,
                                freespace_sendCallback callback,
                                void* cookie) {
#ifdef __APPLE__
    // @TODO: Figure out why libusb on darwin doesn't seem to work with asynchronous messages
    int rc;

    rc = freespace_private_send(id, message, length);
    if (callback != NULL) {
        callback(id, cookie, rc);
    }

    return libusb_to_freespace_error(rc);
#else
    struct FreespaceDevice* device;
    device = findDeviceById(id);
    struct libusb_transfer* transfer;
    int rc;

    if (device == NULL || device->state_ != FREESPACE_OPENED) {
        return FREESPACE_ERROR_NOT_FOUND;
    }

    if (length > device->maxWriteSize_) {
        return FREESPACE_ERROR_SEND_TOO_LARGE;
    }

    transfer = libusb_alloc_transfer(0);
    if (transfer == NULL) {
        return FREESPACE_ERROR_OUT_OF_MEMORY;
    }

    transfer->dev_handle = device->handle_;
    transfer->endpoint = device->writeEndpointAddress_;
    transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
    transfer->timeout = timeoutMs;
    transfer->buffer = (unsigned char*) message;
    transfer->length = length;
    transfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER;

    if (callback != NULL) {
        struct SendTransferInfo* info = (struct SendTransferInfo*) malloc(sizeof(struct SendTransferInfo));
    	if (info == NULL) {
    	    libusb_free_transfer(transfer);
            return FREESPACE_ERROR_OUT_OF_MEMORY;
    	}
    	info->id = id;
        info->callback = callback;
        info->cookie = cookie;
    	transfer->callback = sendCallback;
    	transfer->user_data = info;
    } else {
    	transfer->callback = NULL;
    	transfer->user_data = NULL;
    }

    rc = libusb_submit_transfer(transfer);

    return libusb_to_freespace_error(rc);
#endif
}