verify.c 6.53 KB
Newer Older
Daniel Drake's avatar
Daniel Drake committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * fprintd example to verify a fingerprint
 * Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
 *
 * This program 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.
 * 
 * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdlib.h>
#include <dbus/dbus-glib-bindings.h>
Daniel Drake's avatar
Daniel Drake committed
22
23
#include "manager-dbus-glue.h"
#include "device-dbus-glue.h"
Daniel Drake's avatar
Daniel Drake committed
24

Daniel Drake's avatar
Daniel Drake committed
25
static DBusGProxy *manager = NULL;
Daniel Drake's avatar
Daniel Drake committed
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
static DBusGConnection *connection = NULL;

enum fp_verify_result {
	VERIFY_NO_MATCH = 0,
	VERIFY_MATCH = 1,
	VERIFY_RETRY = 100,
	VERIFY_RETRY_TOO_SHORT = 101,
	VERIFY_RETRY_CENTER_FINGER = 102,
	VERIFY_RETRY_REMOVE_FINGER = 103,
};

static const char *verify_result_str(int result)
{
	switch (result) {
	case VERIFY_NO_MATCH:
		return "No match";
	case VERIFY_MATCH:
		return "Match!";
	case VERIFY_RETRY:
		return "Retry scan";
	case VERIFY_RETRY_TOO_SHORT:
		return "Swipe too short, please retry";
	case VERIFY_RETRY_CENTER_FINGER:
		return "Finger not centered, please retry";
	case VERIFY_RETRY_REMOVE_FINGER:
		return "Please remove finger and retry";
	default:
		return "Unknown";
	}
}

enum fp_finger {
	LEFT_THUMB = 1, /** thumb (left hand) */
	LEFT_INDEX, /** index finger (left hand) */
	LEFT_MIDDLE, /** middle finger (left hand) */
	LEFT_RING, /** ring finger (left hand) */
	LEFT_LITTLE, /** little finger (left hand) */
	RIGHT_THUMB, /** thumb (right hand) */
	RIGHT_INDEX, /** index finger (right hand) */
	RIGHT_MIDDLE, /** middle finger (right hand) */
	RIGHT_RING, /** ring finger (right hand) */
	RIGHT_LITTLE, /** little finger (right hand) */
};

static const char *fingerstr(guint32 fingernum)
{
	switch (fingernum) {
	case LEFT_THUMB:
		return "Left thumb";
	case LEFT_INDEX:
		return "Left index finger";
	case LEFT_MIDDLE:
		return "Left middle finger";
	case LEFT_RING:
		return "Left ring finger";
	case LEFT_LITTLE:
		return "Left little finger";
	case RIGHT_THUMB:
		return "Right thumb";
	case RIGHT_INDEX:
		return "Right index finger";
	case RIGHT_MIDDLE:
		return "Right middle finger";
	case RIGHT_RING:
		return "Right ring finger";
	case RIGHT_LITTLE:
		return "Right little finger";
	default:
		return "Unknown finger";
	}
}

Daniel Drake's avatar
Daniel Drake committed
98
static void create_manager(void)
Daniel Drake's avatar
Daniel Drake committed
99
100
101
102
103
104
105
{
	GError *error = NULL;

	connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
	if (connection == NULL)
		g_error("Failed to connect to session bus: %s", error->message);

Daniel Drake's avatar
Daniel Drake committed
106
107
108
109
	manager = dbus_g_proxy_new_for_name_owner(connection,
		"net.reactivated.Fprint", "/net/reactivated/Fprint/Manager",
		"net.reactivated.Fprint.Manager", &error);
	if (manager == NULL)
Daniel Drake's avatar
Daniel Drake committed
110
111
112
		g_error("Failed to create proxy: %s", error->message);
}

Daniel Drake's avatar
Daniel Drake committed
113
static DBusGProxy *open_device(void)
Daniel Drake's avatar
Daniel Drake committed
114
115
{
	GError *error = NULL;
Daniel Drake's avatar
Daniel Drake committed
116
117
118
	GPtrArray *devices;
	gchar *path;
	DBusGProxy *dev;
Daniel Drake's avatar
Daniel Drake committed
119
120
	guint i;

Daniel Drake's avatar
Daniel Drake committed
121
	if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error))
Daniel Drake's avatar
Daniel Drake committed
122
123
		g_error("list_devices failed: %s", error->message);
	
Daniel Drake's avatar
Daniel Drake committed
124
	if (devices->len == 0) {
Daniel Drake's avatar
Daniel Drake committed
125
126
127
128
		g_print("No devices found\n");
		exit(1);
	}

Daniel Drake's avatar
Daniel Drake committed
129
130
131
132
	g_print("found %d devices\n", devices->len);
	for (i = 0; i < devices->len; i++) {
		path = g_ptr_array_index(devices, i);
		g_print("Device at %s\n", path);
Daniel Drake's avatar
Daniel Drake committed
133
134
	}

Daniel Drake's avatar
Daniel Drake committed
135
136
	path = g_ptr_array_index(devices, 0);
	g_print("Using device %s\n", path);
Daniel Drake's avatar
Daniel Drake committed
137

Daniel Drake's avatar
Daniel Drake committed
138
139
140
141
142
143
144
145
	/* FIXME use for_name_owner?? */
	dev = dbus_g_proxy_new_for_name(connection, "net.reactivated.Fprint",
		path, "net.reactivated.Fprint.Device");
	
	g_ptr_array_foreach(devices, (GFunc) g_free, NULL);
	g_ptr_array_free(devices, TRUE);

	if (!net_reactivated_Fprint_Device_claim(dev, &error))
Daniel Drake's avatar
Daniel Drake committed
146
		g_error("failed to claim device: %s", error->message);
Daniel Drake's avatar
Daniel Drake committed
147
	return dev;
Daniel Drake's avatar
Daniel Drake committed
148
149
}

Daniel Drake's avatar
Daniel Drake committed
150
static guint32 find_finger(DBusGProxy *dev)
Daniel Drake's avatar
Daniel Drake committed
151
152
153
154
155
156
157
{
	GError *error = NULL;
	GArray *fingers;
	guint i;
	int fingernum;
	guint32 print_id;

Daniel Drake's avatar
Daniel Drake committed
158
	if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, &fingers, &error))
Daniel Drake's avatar
Daniel Drake committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
		g_error("ListEnrolledFingers failed: %s", error->message);

	if (fingers->len == 0) {
		g_print("No fingers enrolled for this device.\n");
		exit(1);
	}

	g_print("Listing enrolled fingers:\n");
	for (i = 0; i < fingers->len; i++) {
		fingernum = g_array_index(fingers, guint32, i);
		g_print(" - #%d: %s\n", fingernum, fingerstr(fingernum));
	}

	fingernum = g_array_index(fingers, guint32, 0);
	g_array_free(fingers, TRUE);

	g_print("Verifying: %s\n", fingerstr(fingernum));
Daniel Drake's avatar
Daniel Drake committed
176
	if (!net_reactivated_Fprint_Device_load_print_data(dev, fingernum, &print_id, &error))
Daniel Drake's avatar
Daniel Drake committed
177
178
179
180
181
		g_error("LoadPrintData failed: %s", error->message);

	return print_id;
}

182
183
184
185
186
187
188
189
190
static void verify_result(GObject *object, int result, void *user_data)
{
	gboolean *verify_completed = user_data;
	g_print("Verify result: %s (%d)\n", verify_result_str(result), result);
	if (result == VERIFY_NO_MATCH || result == VERIFY_MATCH)
		*verify_completed = TRUE;
}

static void do_verify(DBusGProxy *dev, guint32 print_id)
Daniel Drake's avatar
Daniel Drake committed
191
192
{
	GError *error;
193
194
	gboolean verify_completed = FALSE;

Daniel Drake's avatar
Daniel Drake committed
195
196
	dbus_g_proxy_add_signal(dev, "VerifyStatus", G_TYPE_INT, NULL);
	dbus_g_proxy_connect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result),
197
		&verify_completed, NULL);
Daniel Drake's avatar
Daniel Drake committed
198

Daniel Drake's avatar
Daniel Drake committed
199
	if (!net_reactivated_Fprint_Device_verify_start(dev, print_id, &error))
Daniel Drake's avatar
Daniel Drake committed
200
201
		g_error("VerifyStart failed: %s", error->message);

202
203
	while (!verify_completed)
		g_main_context_iteration(NULL, TRUE);
Daniel Drake's avatar
Daniel Drake committed
204

Daniel Drake's avatar
Daniel Drake committed
205
	dbus_g_proxy_disconnect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result), &verify_completed);
Daniel Drake's avatar
Daniel Drake committed
206

Daniel Drake's avatar
Daniel Drake committed
207
	if (!net_reactivated_Fprint_Device_verify_stop(dev, &error))
Daniel Drake's avatar
Daniel Drake committed
208
209
210
		g_error("VerifyStop failed: %s", error->message);
}

Daniel Drake's avatar
Daniel Drake committed
211
static void unload_print(DBusGProxy *dev, guint32 print_id)
Daniel Drake's avatar
Daniel Drake committed
212
213
{
	GError *error = NULL;
Daniel Drake's avatar
Daniel Drake committed
214
	if (!net_reactivated_Fprint_Device_unload_print_data(dev, print_id, &error))
Daniel Drake's avatar
Daniel Drake committed
215
216
217
		g_error("UnloadPrint failed: %s", error->message);
}

Daniel Drake's avatar
Daniel Drake committed
218
static void release_device(DBusGProxy *dev)
Daniel Drake's avatar
Daniel Drake committed
219
220
{
	GError *error = NULL;
Daniel Drake's avatar
Daniel Drake committed
221
	if (!net_reactivated_Fprint_Device_release(dev, &error))
Daniel Drake's avatar
Daniel Drake committed
222
223
224
225
226
227
		g_error("ReleaseDevice failed: %s", error->message);
}

int main(int argc, char **argv)
{
	GMainLoop *loop;
Daniel Drake's avatar
Daniel Drake committed
228
	DBusGProxy *dev;
Daniel Drake's avatar
Daniel Drake committed
229
230
231
232
	guint32 print_id;

	g_type_init();
	loop = g_main_loop_new(NULL, FALSE);
Daniel Drake's avatar
Daniel Drake committed
233
	create_manager();
Daniel Drake's avatar
Daniel Drake committed
234

Daniel Drake's avatar
Daniel Drake committed
235
236
	dev = open_device();
	print_id = find_finger(dev);
237
	do_verify(dev, print_id);
Daniel Drake's avatar
Daniel Drake committed
238
239
	unload_print(dev, print_id);
	release_device(dev);
Daniel Drake's avatar
Daniel Drake committed
240
241
242
	return 0;
}