Hello,

Just installed libhid in the opensuse platform and running a c program to
communicate with the card reader

i | libhidapi-devel   | Development libraries and header files for hidapi
                | package
i | libhidapi-hidraw0 | Simple library for communicating with USB and
Bluetooth HID devices | package
i | libhidapi-libusb0 | Simple library for communicating with USB and
Bluetooth HID devices | package

But when I run it, it always give me 13 error code. Not sure what it means,
is there somewhere I can debug it?

hid_force_open failed with return code 13

Thank you for your help

Regards

Shen
/*
 * This application prints and sets properties for a MagTek card reader.
 *
 * All property values and USB communication is based on the document
 * USB KB SURESWIPE & USB KB SWIPE READER TECHNICAL REFERENCE MANUAL
 * Manual Part Number 99875206 Rev 14, which can be downloaded from
 * http://www.magtek.com/documentation/public/99875206-14.02.pdf
 *
 * Copyright (C) 2009 Redpill Linpro AS.
 * 
 * This program is part of Bifrost.
 * 
 * Bifrost is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * Bifrost is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Bifrost.  If not, see <http://www.gnu.org/licenses/>.
 */

#include </usr/include/linux/hid.h>
#include </usr/include/linux/hidraw.h>
#include </usr/include/linux/hiddev.h>
#include <stdio.h>
#include <string.h>

struct property_info_st {
	int nr;
	char* name;
	char* description;
	int printable;
} property_info[] = {
	{0, "SOFTWARE_ID", "The device’s software identifier", 1},
	{1, "SERIAL_NUM", "The device’s serial number", 0},
	{2, "POLLING_INTERVAL", "The interrupt pipe’s polling interval", 0},
	{3, "TRACK_ID_ENABLE", "Track enable / ID enable", 0},
	{4, "TRACK_DATA_SEND_FLAGS", "Track data send flags", 0},
	{5, "TERMINATION_CHAR", "Terminating char / per track or card flag", 0},
	{6, "SS_TK2_7BITS", "Start sentinel char for track 2 – 7 bit data", 0},
	{7, "Reserved", "for future use", 0},
	{8, "SS_TK3_ISO_ABA", "Start sentinel char for track 3 – ISO/ABA", 0},
	{9, "SS_TK3_AAMVA", "Start sentinel char for track 3 - AAMVA", 0},
	{10, "SS_TK3_7BITS", "Start sentinel char for track 3 – 7 bit data", 0},
	{11, "PRE_CARD_CHAR", "Pre card char", 0},
	{12, "POST_CARD_CHAR", "Post card char", 0},
	{13, "PRE_TK_CHAR", "Pre track char", 0},
	{14, "POST_TK_CHAR", "Post track char", 0},
	{15, "ASCII_TO_KEYPRESS_CONVERSION_TYPE", "Type of conversion performed when converting ASCII data to key strokes", 0},
	{16, "INTERFACE_TYPE", "Type of USB interface", 0},
	{17, "ACTIVE_KEYMAP", "Selects which key map to uses", 0},
	{18, "PRE_CARD_STRING", "Pre card string", 0},
	{19, "POST_CARD_STRING", "Post card string", 0},
	{20, "SS_TK1_ISO_ABA", "Start sentinel char for track 1 – ISO/ABA", 0},
	{21, "SS_TK2_ISO_ABA", "Start sentinel char for track 2 – ISO/ABA", 0},
	{22, "ES", "End sentinel char for all tracks/formats", 0},
};


int path[2] = {0x00010006, 0xff000020};
int vendor_id =  0x0801;
int product_id = 0x0001;
int property_count = 22;
HIDInterface* hid;

int
send_command(char buffer[], const int buffer_len, char data[], int* data_len) {
	int i;
	hid_return ret;
	char temp_buffer[24] = {0};

	for (i = 0; i < buffer_len; i++)
		temp_buffer[i] = buffer[i];

	hid_set_feature_report(hid, NULL, 0, temp_buffer, 24);
	ret = hid_get_feature_report(hid, path, 0, temp_buffer, 24);
	if (ret != HID_RET_SUCCESS) {
		fprintf(stderr, "hid_get_feature_report failed with return code %d\n", ret);
		return -1;
	}
	if (data_len != NULL) {
		if (temp_buffer[0] == 0) {
			for (i = 0; i < temp_buffer[1]; i++)
				data[i] = temp_buffer[2 + i];
			*data_len = temp_buffer[1];
		}
		else
			*data_len = 0;
	}

	return temp_buffer[0];
}

int
send_reset() {
	char command[] = {0x02, 0x0};
	
	return send_command(command, 2, NULL, NULL);
}

int
set_property(int property, int value) {
	char command[] = {0x01, 0x02, property, value};

	return send_command(command, 4, NULL, NULL);
}

const char*
get_property(int property) {
	static char value[120];
	char command[3];
	char data[20];
	int data_len, i;

	command[0] = 0;
	command[1] = 1;
	command[2] = property; 
	if (send_command(command, 3, data, &data_len) != 0) {
		sprintf(value, "Error reading value\n");
	}
	
	value[0] = '\0';
	if (property_info[property].printable) {
		memcpy(value, data, data_len);
		value[data_len] = '\0';
	}
	else {
		for (i = 0; i < data_len; i++)
			sprintf(value, "%s0x%.2hhx ", value, data[i]);
	}

	return value;
}

void
print_property(int property) {
	printf("%s\n", get_property(property));
}


void
print_properties() {

	int p, i;
	printf("Nr|%-33s|Value\n", "Name");
	for (p = 0; p <= property_count; p++)
		printf("%02d|%-33s|%s\n", p, property_info[p].name, get_property(p));
}

void
print_usage() {
	printf( "Usage: magtek -p [property] | -s <property nr> <value>\n");
	printf( "    %-25s %s\n", "-p [property]", "prints the property, or all properties if omitted");
	printf( "    %-25s %s\n", "-s <property> <value>", "sets the property");
}

int
get_hex_val(char val) {
	if (val <= '9')
		return val - '0';
	else
		return 10 + val - 'a';
}

int
get_int(char* integer) {
	if (strncmp(integer, "0x", 2) == 0 
		&& strlen(integer) > 2) {
		int value =  get_hex_val(integer[2]);
		
		integer += 3;
		while (*integer) {
			value = value * 16 + get_hex_val(*integer);
			integer++;
		}

		return value;
	}
	else
		return atoi(integer);
}


extern HIDDebugLevel hid_debug_level;
extern FILE* hid_debug_stream;
int
main(int argc, char** argv) {
	//hid_debug_level = HID_DEBUG_ALL;
	hid_debug_stream = stderr;
	hid_return ret;
	if(hid_debug_level)
		fprintf (stderr, "hid_debug_level: %X\n", hid_debug_level);
	HIDInterfaceMatcher matcher = { 0x0801, product_id, NULL, NULL, 0 };
	char input_buffer[64];
	int exit_code = 0;

	if (argc == 1) {
		fprintf( stderr, "Error: Missing command\n");
		print_usage();
		return -1;
	}

	ret = hid_init();
	if (ret != HID_RET_SUCCESS) {
		fprintf(stderr, "hid_init failed with return code %d\n", ret);
		return 1;
	}

	hid = hid_new_HIDInterface();
	if (hid == 0) {
		fprintf(stderr, "hid_new_HIDInterface() failed, out of memory?\n");
		return 1;
	}

	ret = hid_force_open(hid, 0, &matcher, 3);
	if (ret != HID_RET_SUCCESS) {
		fprintf(stderr, "hid_force_open failed with return code %d\n", ret);
		return 1;
	}

	if (strcmp(argv[1], "-p") == 0) {
		if (argc == 3)
			print_property(get_int(argv[2]));
		else
			print_properties();
	}
	else if (strcmp(argv[1], "-s") == 0) {
		int property, value;
		if (argc == 3) {
			printf("Error: Missing value to set for property %s\n", argv[2]);
			print_usage();
			exit_code = -1;
		}
		else if (argc > 4) {
			printf("Error: Too many arguments\n");
			print_usage();
			exit_code = -1;
		}
		property = get_int(argv[2]);
		value = get_int(argv[3]);
		if (set_property(property, value) != 0) {
			printf("Could not set property %d to %d\n", property, value);
		}
		send_reset();
	}
	else {
		fprintf(stderr, "Error: Bad option %s\n", argv[1]);
		print_usage();
		exit_code = -1;
	}

	ret = hid_close(hid);
	if (ret != HID_RET_SUCCESS) {
		fprintf(stderr, "hid_close failed with return code %d\n", ret);
		exit_code = 1;
	}

	hid_delete_HIDInterface(&hid);

	ret = hid_cleanup();
	if (ret != HID_RET_SUCCESS) {
		fprintf(stderr, "hid_cleanup failed with return code %d\n", ret);
		exit_code = 1;
	}

	return exit_code;
}
_______________________________________________
libhid-discuss mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/libhid-discuss
http://libhid.alioth.debian.org/

Reply via email to