verify.c 6.39 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
/*
 * 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.
 */

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

Daniel Drake's avatar
Daniel Drake committed
26
static DBusGProxy *manager = NULL;
Daniel Drake's avatar
Daniel Drake committed
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
98
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
99
static void create_manager(void)
Daniel Drake's avatar
Daniel Drake committed
100
101
102
{
	GError *error = NULL;

103
	connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
Daniel Drake's avatar
Daniel Drake committed
104
105
106
	if (connection == NULL)
		g_error("Failed to connect to session bus: %s", error->message);

107
	manager = dbus_g_proxy_new_for_name(connection,
Daniel Drake's avatar
Daniel Drake committed
108
		"net.reactivated.Fprint", "/net/reactivated/Fprint/Manager",
109
		"net.reactivated.Fprint.Manager");
Daniel Drake's avatar
Daniel Drake committed
110
111
}

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

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

Daniel Drake's avatar
Daniel Drake committed
128
129
130
131
	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
132
133
	}

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

Daniel Drake's avatar
Daniel Drake committed
137
138
139
140
141
142
143
144
	/* 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
145
		g_error("failed to claim device: %s", error->message);
Daniel Drake's avatar
Daniel Drake committed
146
	return dev;
Daniel Drake's avatar
Daniel Drake committed
147
148
}

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

156
	if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, &fingers, &error))
Daniel Drake's avatar
Daniel Drake committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
		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));

175
	return fingernum;
Daniel Drake's avatar
Daniel Drake committed
176
177
}

178
179
180
181
182
183
184
185
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;
}

186
static void do_verify(DBusGProxy *dev, guint32 finger_num)
Daniel Drake's avatar
Daniel Drake committed
187
188
{
	GError *error;
189
190
	gboolean verify_completed = FALSE;

Daniel Drake's avatar
Daniel Drake committed
191
192
	dbus_g_proxy_add_signal(dev, "VerifyStatus", G_TYPE_INT, NULL);
	dbus_g_proxy_connect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result),
193
		&verify_completed, NULL);
Daniel Drake's avatar
Daniel Drake committed
194

195
	if (!net_reactivated_Fprint_Device_verify_start(dev, finger_num, &error))
Daniel Drake's avatar
Daniel Drake committed
196
197
		g_error("VerifyStart failed: %s", error->message);

198
199
	while (!verify_completed)
		g_main_context_iteration(NULL, TRUE);
Daniel Drake's avatar
Daniel Drake committed
200

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

Daniel Drake's avatar
Daniel Drake committed
203
	if (!net_reactivated_Fprint_Device_verify_stop(dev, &error))
Daniel Drake's avatar
Daniel Drake committed
204
205
206
		g_error("VerifyStop failed: %s", error->message);
}

Daniel Drake's avatar
Daniel Drake committed
207
static void release_device(DBusGProxy *dev)
Daniel Drake's avatar
Daniel Drake committed
208
209
{
	GError *error = NULL;
Daniel Drake's avatar
Daniel Drake committed
210
	if (!net_reactivated_Fprint_Device_release(dev, &error))
Daniel Drake's avatar
Daniel Drake committed
211
212
213
		g_error("ReleaseDevice failed: %s", error->message);
}

214
215
216
217
218
219
220
221
222
223
static gboolean set_username(DBusGProxy *dev, const char *username)
{
	GError *error = NULL;
	if (!net_reactivated_Fprint_Device_set_username(dev, username, &error)) {
		g_error("SetUsename failed: %s", error->message);
		return FALSE;
	}
	return TRUE;
}

Daniel Drake's avatar
Daniel Drake committed
224
225
226
int main(int argc, char **argv)
{
	GMainLoop *loop;
Daniel Drake's avatar
Daniel Drake committed
227
	DBusGProxy *dev;
228
	guint32 finger_num;
Daniel Drake's avatar
Daniel Drake committed
229
230
231

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

Daniel Drake's avatar
Daniel Drake committed
234
	dev = open_device();
235
236
237
238
	if (argc == 2) {
		if (set_username(dev, argv[1]) == FALSE)
			return 1;
	}
239
240
	finger_num = find_finger(dev);
	do_verify(dev, finger_num);
Daniel Drake's avatar
Daniel Drake committed
241
	release_device(dev);
Daniel Drake's avatar
Daniel Drake committed
242
243
244
	return 0;
}