dissect_usb_hid_generic_desktop_controls_page(tvbuff_t *tvb, packet_info _U_ *pinfo,
        proto_tree *tree, hid_field_t *field, int *bit_offset)
{
    gint ret = 0;
    guint32 usage;
    unsigned int usage_count = wmem_array_get_count(field->usages);

    if ((field->properties & HID_MAIN_TYPE) != HID_MAIN_VARIABLE)
        return -1;

    if (usage_count != field->report_count)
        return -1;

    for(unsigned int i = 0; i < usage_count; i++) {
        usage = *((guint32*) wmem_array_index(field->usages, i));
        switch (usage)
        {
            case USBHID_GENERIC_DESKTOP_CONTROLS_X:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_x);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_Y:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_y);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_Z:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_z);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_RX:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_rx);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_RY:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_ry);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_RZ:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_rz);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_SLIDER:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_slider);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VX:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vx);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VY:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vy);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VZ:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vz);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VBRX:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbrx);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VBRY:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbry);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VBRZ:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbrz);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VNO:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vno);
                break;

            default:
                proto_tree_add_bits_item(tree, hf_usbhid_unknown_data, tvb, *bit_offset, field->report_size, ENC_NA);
                break;
        }

        if (ret)
            return ret;
    }

    return 0;
}
dissect_usb_hid_generic_desktop_controls_page(tvbuff_t *tvb, packet_info _U_ *pinfo,
        proto_tree *tree, hid_field_t *field, int *bit_offset)
{
    gint ret = 0;
    guint32 usage;
    unsigned int usage_count = wmem_array_get_count(field->usages);

    if ((field->properties & HID_MAIN_TYPE) != HID_MAIN_VARIABLE)
        return -1;

    if (usage_count != field->report_count)
        return -1;

    for(unsigned int i = 0; i < usage_count; i++) {
        usage = *((guint32*) wmem_array_index(field->usages, i));
        switch (usage)
        {
            case USBHID_GENERIC_DESKTOP_CONTROLS_X:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_x);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_Y:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_y);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_Z:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_z);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_RX:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_rx);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_RY:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_ry);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_RZ:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_rz);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_SLIDER:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_slider);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VX:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vx);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VY:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vy);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VZ:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vz);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VBRX:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbrx);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VBRY:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbry);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VBRZ:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbrz);
                break;

            case USBHID_GENERIC_DESKTOP_CONTROLS_VNO:
                ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vno);
                break;

            default:
                proto_tree_add_bits_item(tree, hf_usbhid_unknown_data, tvb, *bit_offset, field->report_size, ENC_NA);
                break;
        }

        if (ret)
            return ret;
    }

    return 0;
}