3 * neard - Near Field Communication manager
5 * Copyright (C) 2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
42 enum near_target_type type;
48 static DBusConnection *connection = NULL;
50 static GHashTable *target_hash;
52 static void free_target(gpointer data)
54 struct near_target *target = data;
56 if (target->tag != NULL)
57 __near_tag_free(target->tag);
62 const char *__near_target_get_path(struct near_target *target)
73 uint16_t __near_target_get_tag_type(struct near_target *target)
75 return target->tag_type;
78 uint32_t __near_target_get_idx(struct near_target *target)
83 uint32_t __near_target_get_adapter_idx(struct near_target *target)
85 return target->adapter_idx;
88 uint32_t __near_target_get_protocols(struct near_target *target)
90 return target->protocols;
93 static void append_protocols(DBusMessageIter *iter, void *user_data)
95 struct near_target *target = user_data;
98 DBG("protocols 0x%x", target->protocols);
100 if (target->protocols & NFC_PROTO_FELICA_MASK) {
103 dbus_message_iter_append_basic(iter,
104 DBUS_TYPE_STRING, &str);
107 if (target->protocols & NFC_PROTO_MIFARE_MASK) {
110 dbus_message_iter_append_basic(iter,
111 DBUS_TYPE_STRING, &str);
114 if (target->protocols & NFC_PROTO_JEWEL_MASK) {
117 dbus_message_iter_append_basic(iter,
118 DBUS_TYPE_STRING, &str);
121 if (target->protocols & NFC_PROTO_ISO14443_MASK) {
124 dbus_message_iter_append_basic(iter,
125 DBUS_TYPE_STRING, &str);
128 if (target->protocols & NFC_PROTO_NFC_DEP_MASK) {
131 dbus_message_iter_append_basic(iter,
132 DBUS_TYPE_STRING, &str);
136 static void append_tag_type(DBusMessageIter *iter, void *user_data)
138 struct near_target *target = user_data;
141 DBG("tag 0x%x", target->tag_type);
143 if (target->tag_type & NEAR_TAG_NFC_TYPE1) {
146 dbus_message_iter_append_basic(iter,
147 DBUS_TYPE_STRING, &str);
150 if (target->tag_type & NEAR_TAG_NFC_TYPE2) {
153 dbus_message_iter_append_basic(iter,
154 DBUS_TYPE_STRING, &str);
157 if (target->tag_type & NEAR_TAG_NFC_TYPE3) {
160 dbus_message_iter_append_basic(iter,
161 DBUS_TYPE_STRING, &str);
164 if (target->tag_type & NEAR_TAG_NFC_TYPE4) {
167 dbus_message_iter_append_basic(iter,
168 DBUS_TYPE_STRING, &str);
171 if (target->tag_type & NEAR_TAG_NFC_DEP) {
174 dbus_message_iter_append_basic(iter,
175 DBUS_TYPE_STRING, &str);
179 static const char *type2string(enum near_target_type type)
184 case NEAR_TARGET_TYPE_TAG:
186 case NEAR_TARGET_TYPE_DEVICE:
193 static DBusMessage *get_properties(DBusConnection *conn,
194 DBusMessage *msg, void *data)
196 struct near_target *target = data;
198 DBusMessageIter array, dict;
201 DBG("conn %p", conn);
203 reply = dbus_message_new_method_return(msg);
207 type = type2string(target->type);
209 dbus_message_iter_init_append(reply, &array);
211 near_dbus_dict_open(&array, &dict);
213 near_dbus_dict_append_basic(&dict, "Type",
214 DBUS_TYPE_STRING, &type);
216 if (target->type == NEAR_TARGET_TYPE_DEVICE)
217 near_dbus_dict_append_array(&dict, "Protocols",
218 DBUS_TYPE_STRING, append_protocols, target);
220 if (target->type == NEAR_TARGET_TYPE_TAG)
221 near_dbus_dict_append_array(&dict, "TagType",
222 DBUS_TYPE_STRING, append_tag_type, target);
224 near_dbus_dict_close(&array, &dict);
229 static DBusMessage *set_property(DBusConnection *conn,
230 DBusMessage *msg, void *data)
232 DBG("conn %p", conn);
234 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
237 static GDBusMethodTable target_methods[] = {
238 { "GetProperties", "", "a{sv}", get_properties },
239 { "SetProperty", "sv", "", set_property },
243 static GDBusSignalTable target_signals[] = {
244 { "PropertyChanged", "sv" },
248 #define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \
249 NFC_PROTO_MIFARE_MASK)
250 #define NFC_TAG_A_TYPE2 0x00
251 #define NFC_TAG_A_TYPE4 0x01
252 #define NFC_TAG_A_NFC_DEP 0x02
253 #define NFC_TAG_A_TYPE4_DEP 0x03
255 #define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5)
257 static void find_tag_type(struct near_target *target,
258 uint16_t sens_res, uint8_t sel_res)
260 DBG("protocols 0x%x sens_res 0x%x sel_res 0x%x", target->protocols,
263 if (target->type != NEAR_TARGET_TYPE_TAG) {
264 target->tag_type = NEAR_TAG_NFC_UNKNOWN;
268 if (target->protocols & NFC_TAG_A) {
269 uint8_t proto = NFC_TAG_A_SEL_PROT(sel_res);
271 DBG("proto 0x%x", proto);
274 case NFC_TAG_A_TYPE2:
275 target->tag_type = NEAR_TAG_NFC_TYPE2;
277 case NFC_TAG_A_TYPE4:
278 target->tag_type = NEAR_TAG_NFC_TYPE4;
280 case NFC_TAG_A_NFC_DEP:
281 target->tag_type = NEAR_TAG_NFC_DEP;
283 case NFC_TAG_A_TYPE4_DEP:
284 target->tag_type = NEAR_TAG_NFC_TYPE4 |
290 target->tag_type = NEAR_TAG_NFC_UNKNOWN;
293 DBG("tag type 0x%x", target->tag_type);
296 int __near_target_add(uint32_t adapter_idx, uint32_t target_idx,
297 uint32_t protocols, enum near_target_type type,
298 uint16_t sens_res, uint8_t sel_res)
300 struct near_target *target;
302 if (g_hash_table_lookup(target_hash,
303 GINT_TO_POINTER(target_idx)) != NULL)
306 target = g_try_malloc0(sizeof(struct near_target));
310 target->path = g_strdup_printf("%s/nfc%d/target%d", NFC_PATH,
311 adapter_idx, target_idx);
312 if (target->path == NULL) {
317 target->idx = target_idx;
318 target->adapter_idx = adapter_idx;
319 target->protocols = protocols;
321 find_tag_type(target, sens_res, sel_res);
323 g_hash_table_insert(target_hash, GINT_TO_POINTER(target_idx), target);
325 DBG("connection %p", connection);
327 g_dbus_register_interface(connection, target->path,
328 NFC_TARGET_INTERFACE,
329 target_methods, target_signals,
332 return __near_adapter_add_target(adapter_idx, target);
335 void __near_target_remove(uint32_t target_idx)
337 struct near_target *target;
339 target = g_hash_table_lookup(target_hash, GINT_TO_POINTER(target_idx));
343 __near_adapter_remove_target(target->adapter_idx, target);
345 g_dbus_unregister_interface(connection, target->path,
346 NFC_TARGET_INTERFACE);
348 g_hash_table_remove(target_hash, GINT_TO_POINTER(target_idx));
351 struct near_tag *near_target_get_tag(uint32_t target_idx, size_t data_length)
353 struct near_target *target;
355 target = g_hash_table_lookup(target_hash, GINT_TO_POINTER(target_idx));
359 if (target->tag != NULL)
362 target->tag = __near_tag_new(target->adapter_idx, target_idx, data_length);
363 if (target->tag == NULL)
366 /* TODO reference the tag, or add tag reference count API */
370 int __near_target_init(void)
374 connection = near_dbus_get_connection();
376 target_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
382 void __near_target_cleanup(void)
386 g_hash_table_destroy(target_hash);