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
38 /* We check for the tag being present every 2 seconds */
39 #define CHECK_PRESENCE_PERIOD 2
41 static DBusConnection *connection = NULL;
43 static GHashTable *adapter_hash;
54 near_bool_t constant_poll;
58 struct near_tag *tag_link;
62 struct near_tag *device_link;
70 guint presence_timeout;
73 struct near_adapter_ioreq {
76 unsigned char buf[1024];
86 static void free_adapter(gpointer data)
88 struct near_adapter *adapter = data;
90 if (adapter->presence_timeout > 0)
91 g_source_remove(adapter->presence_timeout);
93 g_free(adapter->name);
94 g_free(adapter->path);
98 static void free_tag(gpointer data)
100 struct near_tag *tag = data;
102 __near_tag_remove(tag);
105 static void polling_changed(struct near_adapter *adapter)
108 near_dbus_property_changed_basic(adapter->path,
109 NFC_ADAPTER_INTERFACE, "Polling",
110 DBUS_TYPE_BOOLEAN, &adapter->polling);
113 static int adapter_start_poll(struct near_adapter *adapter)
117 if (g_hash_table_size(adapter->tags) > 0) {
118 DBG("Clearing tags");
120 g_hash_table_remove_all(adapter->tags);
121 __near_adapter_tags_changed(adapter->idx);
124 err = __near_netlink_start_poll(adapter->idx, adapter->protocols);
128 adapter->polling = TRUE;
130 polling_changed(adapter);
135 static void append_path(gpointer key, gpointer value, gpointer user_data)
137 struct near_adapter *adapter = value;
138 DBusMessageIter *iter = user_data;
140 DBG("%s", adapter->path);
142 if (adapter->path == NULL)
145 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
150 void __near_adapter_list(DBusMessageIter *iter, void *user_data)
152 g_hash_table_foreach(adapter_hash, append_path, iter);
155 static void append_protocols(DBusMessageIter *iter, void *user_data)
157 struct near_adapter *adapter = user_data;
160 DBG("protocols 0x%x", adapter->protocols);
162 if (adapter->protocols & NFC_PROTO_FELICA_MASK) {
165 dbus_message_iter_append_basic(iter,
166 DBUS_TYPE_STRING, &str);
169 if (adapter->protocols & NFC_PROTO_MIFARE_MASK) {
172 dbus_message_iter_append_basic(iter,
173 DBUS_TYPE_STRING, &str);
176 if (adapter->protocols & NFC_PROTO_JEWEL_MASK) {
179 dbus_message_iter_append_basic(iter,
180 DBUS_TYPE_STRING, &str);
183 if (adapter->protocols & NFC_PROTO_ISO14443_MASK) {
186 dbus_message_iter_append_basic(iter,
187 DBUS_TYPE_STRING, &str);
190 if (adapter->protocols & NFC_PROTO_NFC_DEP_MASK) {
193 dbus_message_iter_append_basic(iter,
194 DBUS_TYPE_STRING, &str);
198 static void append_tag_path(gpointer key, gpointer value, gpointer user_data)
200 struct near_tag *tag = value;
201 DBusMessageIter *iter = user_data;
202 const char *tag_path;
204 tag_path = __near_tag_get_path(tag);
205 if (tag_path == NULL)
210 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
214 static void append_tags(DBusMessageIter *iter, void *user_data)
216 struct near_adapter *adapter = user_data;
220 g_hash_table_foreach(adapter->tags, append_tag_path, iter);
223 void __near_adapter_tags_changed(uint32_t adapter_idx)
225 struct near_adapter *adapter;
229 adapter = g_hash_table_lookup(adapter_hash,
230 GINT_TO_POINTER(adapter_idx));
234 near_dbus_property_changed_array(adapter->path,
235 NFC_ADAPTER_INTERFACE, "Tags",
236 DBUS_TYPE_OBJECT_PATH, append_tags,
239 static DBusMessage *get_properties(DBusConnection *conn,
240 DBusMessage *msg, void *data)
242 struct near_adapter *adapter = data;
244 DBusMessageIter array, dict;
246 DBG("conn %p", conn);
248 reply = dbus_message_new_method_return(msg);
252 dbus_message_iter_init_append(reply, &array);
254 near_dbus_dict_open(&array, &dict);
256 near_dbus_dict_append_basic(&dict, "Powered",
257 DBUS_TYPE_BOOLEAN, &adapter->powered);
259 near_dbus_dict_append_basic(&dict, "Polling",
260 DBUS_TYPE_BOOLEAN, &adapter->polling);
262 near_dbus_dict_append_array(&dict, "Protocols",
263 DBUS_TYPE_STRING, append_protocols, adapter);
265 near_dbus_dict_append_array(&dict, "Tags",
266 DBUS_TYPE_OBJECT_PATH, append_tags, adapter);
268 near_dbus_dict_close(&array, &dict);
273 static DBusMessage *set_property(DBusConnection *conn,
274 DBusMessage *msg, void *data)
276 struct near_adapter *adapter = data;
277 DBusMessageIter iter, value;
281 DBG("conn %p", conn);
283 if (dbus_message_iter_init(msg, &iter) == FALSE)
284 return __near_error_invalid_arguments(msg);
286 dbus_message_iter_get_basic(&iter, &name);
287 dbus_message_iter_next(&iter);
288 dbus_message_iter_recurse(&iter, &value);
290 type = dbus_message_iter_get_arg_type(&value);
292 if (g_str_equal(name, "Powered") == TRUE) {
295 if (type != DBUS_TYPE_BOOLEAN)
296 return __near_error_invalid_arguments(msg);
298 dbus_message_iter_get_basic(&value, &powered);
300 err = __near_netlink_adapter_enable(adapter->idx, powered);
302 return __near_error_failed(msg, -err);
304 adapter->powered = powered;
306 return __near_error_invalid_property(msg);
308 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
311 static DBusMessage *start_poll(DBusConnection *conn,
312 DBusMessage *msg, void *data)
314 struct near_adapter *adapter = data;
317 DBG("conn %p", conn);
319 err = adapter_start_poll(adapter);
321 return __near_error_failed(msg, -err);
323 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
326 static DBusMessage *stop_poll(DBusConnection *conn,
327 DBusMessage *msg, void *data)
329 struct near_adapter *adapter = data;
332 DBG("conn %p", conn);
334 err = __near_netlink_stop_poll(adapter->idx);
336 return __near_error_failed(msg, -err);
338 adapter->polling = FALSE;
340 polling_changed(adapter);
342 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
345 static int __push_ndef_queue(struct near_adapter *adapter,
346 struct near_ndef_message *ndef)
348 if (adapter == NULL || ndef == NULL)
351 adapter->ndef_q = g_list_append(adapter->ndef_q, ndef);
356 static struct near_ndef_message *
357 __pop_ndef_queue(struct near_adapter *adapter)
360 struct near_ndef_message *ndef;
365 list = g_list_first(adapter->ndef_q);
371 adapter->ndef_q = g_list_remove(adapter->ndef_q, ndef);
376 static int __publish_text_record(DBusMessage *msg, void *data)
378 DBusMessageIter iter, arr_iter;
379 struct near_ndef_message *ndef;
380 char *cod = NULL, *lang = NULL, *rep = NULL;
384 dbus_message_iter_init(msg, &iter);
385 dbus_message_iter_recurse(&iter, &arr_iter);
387 while (dbus_message_iter_get_arg_type(&arr_iter) !=
390 DBusMessageIter ent_iter;
391 DBusMessageIter var_iter;
393 dbus_message_iter_recurse(&arr_iter, &ent_iter);
394 dbus_message_iter_get_basic(&ent_iter, &key);
395 dbus_message_iter_next(&ent_iter);
396 dbus_message_iter_recurse(&ent_iter, &var_iter);
398 switch (dbus_message_iter_get_arg_type(&var_iter)) {
399 case DBUS_TYPE_STRING:
400 if (g_strcmp0(key, "Encoding") == 0)
401 dbus_message_iter_get_basic(&var_iter, &cod);
402 else if (g_strcmp0(key, "Language") == 0)
403 dbus_message_iter_get_basic(&var_iter, &lang);
404 else if (g_strcmp0(key, "Representation") == 0)
405 dbus_message_iter_get_basic(&var_iter, &rep);
410 dbus_message_iter_next(&arr_iter);
413 ndef = near_ndef_prepare_text_record(cod, lang, rep);
417 return __push_ndef_queue(data, ndef);
420 static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx,
423 static gboolean check_presence(gpointer user_data)
425 struct near_adapter *adapter = user_data;
426 struct near_tag *tag;
434 tag = adapter->tag_link;
438 err = __near_tag_check_presence(tag, tag_present_cb);
440 DBG("Could not check target presence");
442 near_adapter_disconnect(adapter->idx);
443 if (adapter->constant_poll == TRUE)
444 adapter_start_poll(adapter);
450 static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx,
453 struct near_adapter *adapter;
457 adapter = g_hash_table_lookup(adapter_hash,
458 GINT_TO_POINTER(adapter_idx));
465 near_adapter_disconnect(adapter->idx);
466 if (adapter->constant_poll == TRUE)
467 adapter_start_poll(adapter);
472 adapter->presence_timeout =
473 g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
474 check_presence, adapter);
477 static char *get_uri_field(DBusMessage *msg)
479 DBusMessageIter iter, arr_iter;
484 dbus_message_iter_init(msg, &iter);
485 dbus_message_iter_recurse(&iter, &arr_iter);
487 while (dbus_message_iter_get_arg_type(&arr_iter) !=
490 DBusMessageIter ent_iter;
491 DBusMessageIter var_iter;
493 dbus_message_iter_recurse(&arr_iter, &ent_iter);
494 dbus_message_iter_get_basic(&ent_iter, &key);
495 dbus_message_iter_next(&ent_iter);
496 dbus_message_iter_recurse(&ent_iter, &var_iter);
498 switch (dbus_message_iter_get_arg_type(&var_iter)) {
499 case DBUS_TYPE_STRING:
500 if (g_strcmp0(key, "URI") == 0)
501 dbus_message_iter_get_basic(&var_iter, &uri);
506 dbus_message_iter_next(&arr_iter);
512 static int publish_uri_record(DBusMessage *msg, void *data)
514 struct near_ndef_message *ndef;
516 const char *uri_prefix = NULL;
522 uri = get_uri_field(msg);
526 for (i = 1; i <= NFC_MAX_URI_ID; i++) {
527 uri_prefix = __near_ndef_get_uri_prefix(i);
529 if (uri_prefix != NULL &&
530 g_str_has_prefix(uri, uri_prefix) == TRUE)
534 /* If uri_prefix is NULL then ID will be zero */
535 if (uri_prefix == NULL) {
539 id_len = strlen(uri_prefix);
541 uri_len = strlen(uri) - id_len;
542 ndef = near_ndef_prepare_uri_record(i, uri_len,
543 (uint8_t *)(uri + id_len));
547 return __push_ndef_queue(data, ndef);
550 static int publish_sp_record(DBusMessage *msg, void *data)
552 struct near_ndef_message *ndef;
554 const char *uri_prefix;
560 /* Currently this funtion supports only mandatory URI record,
561 * TODO: Other records support */
562 uri = get_uri_field(msg);
566 for (i = 1; i <= NFC_MAX_URI_ID; i++) {
567 uri_prefix = __near_ndef_get_uri_prefix(i);
569 if (uri_prefix != NULL &&
570 g_str_has_prefix(uri, uri_prefix) == TRUE)
574 if (uri_prefix == NULL) {
578 id_len = strlen(uri_prefix);
580 uri_len = strlen(uri) - id_len;
581 ndef = near_ndef_prepare_smartposter_record(i, uri_len,
582 (uint8_t *)(uri + id_len));
586 return __push_ndef_queue(data, ndef);
589 static void __add_ndef_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
591 struct near_adapter *adapter;
595 adapter = g_hash_table_lookup(adapter_hash,
596 GINT_TO_POINTER(adapter_idx));
600 adapter->presence_timeout =
601 g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
602 check_presence, adapter);
605 static DBusMessage *publish(DBusConnection *conn,
606 DBusMessage *msg, void *data)
608 DBusMessageIter iter;
609 DBusMessageIter arr_iter;
610 struct near_adapter *adapter = data;
612 DBG("conn %p", conn);
614 dbus_message_iter_init(msg, &iter);
615 dbus_message_iter_recurse(&iter, &arr_iter);
617 while (dbus_message_iter_get_arg_type(&arr_iter) !=
619 const char *key, *value;
620 DBusMessageIter ent_iter;
621 DBusMessageIter var_iter;
623 dbus_message_iter_recurse(&arr_iter, &ent_iter);
624 dbus_message_iter_get_basic(&ent_iter, &key);
626 if (g_strcmp0(key, "Type") != 0) {
627 dbus_message_iter_next(&arr_iter);
631 dbus_message_iter_next(&ent_iter);
632 dbus_message_iter_recurse(&ent_iter, &var_iter);
634 switch (dbus_message_iter_get_arg_type(&var_iter)) {
635 case DBUS_TYPE_STRING:
636 dbus_message_iter_get_basic(&var_iter, &value);
638 if (g_strcmp0(value, "Text") == 0) {
639 if (__publish_text_record(msg, adapter) < 0)
643 } else if (g_strcmp0(value, "URI") == 0) {
644 if (publish_uri_record(msg, adapter) < 0)
649 } else if (g_strcmp0(value, "SmartPoster") == 0) {
650 if (publish_sp_record(msg, adapter) < 0)
656 DBG(" '%s' not supported", value);
663 dbus_message_iter_next(&arr_iter);
667 return g_dbus_create_error(msg, "org.neard.Error.InvalidArguments",
668 "Invalid arguments");
671 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
674 static GDBusMethodTable adapter_methods[] = {
675 { "GetProperties", "", "a{sv}", get_properties },
676 { "SetProperty", "sv", "", set_property },
677 { "StartPoll", "", "", start_poll },
678 { "StopPoll", "", "", stop_poll },
679 { "Publish", "a{sv}", "", publish },
683 static GDBusSignalTable adapter_signals[] = {
684 { "PropertyChanged", "sv" },
690 struct near_adapter * __near_adapter_create(uint32_t idx,
691 const char *name, uint32_t protocols, near_bool_t powered)
693 struct near_adapter *adapter;
695 adapter = g_try_malloc0(sizeof(struct near_adapter));
699 adapter->name = g_strdup(name);
700 if (adapter->name == NULL) {
705 adapter->protocols = protocols;
706 adapter->powered = powered;
707 adapter->constant_poll = near_setting_get_bool("ConstantPoll");
708 adapter->dep_up = FALSE;
709 adapter->tags = g_hash_table_new_full(g_direct_hash, g_direct_equal,
711 adapter->tag_sock = -1;
713 adapter->path = g_strdup_printf("%s/nfc%d", NFC_PATH, idx);
718 void __near_adapter_destroy(struct near_adapter *adapter)
722 free_adapter(adapter);
725 const char *__near_adapter_get_path(struct near_adapter *adapter)
727 return adapter->path;
730 struct near_adapter *__near_adapter_get(uint32_t idx)
732 return g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
735 int near_adapter_get_dep_state(uint32_t idx)
737 struct near_adapter *adapter;
741 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
745 return adapter->dep_up;
748 int near_adapter_set_dep_state(uint32_t idx, near_bool_t dep)
750 struct near_adapter *adapter;
754 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
758 adapter->dep_up = dep;
763 int __near_adapter_add(struct near_adapter *adapter)
765 uint32_t idx = adapter->idx;
767 DBG("%s", adapter->path);
769 if (g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx)) != NULL)
772 g_hash_table_insert(adapter_hash, GINT_TO_POINTER(idx), adapter);
774 DBG("connection %p", connection);
776 g_dbus_register_interface(connection, adapter->path,
777 NFC_ADAPTER_INTERFACE,
778 adapter_methods, adapter_signals,
779 NULL, adapter, NULL);
784 void __near_adapter_remove(struct near_adapter *adapter)
786 DBG("%s", adapter->path);
788 g_dbus_unregister_interface(connection, adapter->path,
789 NFC_ADAPTER_INTERFACE);
791 g_hash_table_remove(adapter_hash, GINT_TO_POINTER(adapter->idx));
795 static int dep_link_up(uint32_t idx, uint32_t target_idx)
797 return __near_netlink_dep_link_up(idx, target_idx,
798 NFC_COMM_ACTIVE, NFC_RF_INITIATOR);
801 static int dep_link_down(uint32_t idx)
803 return __near_netlink_dep_link_down(idx);
807 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
809 struct near_adapter *adapter;
810 struct near_tag *tag;
811 struct near_ndef_message *ndef, *ndef_with_header = NULL;
815 DBG("status %d", status);
817 adapter = g_hash_table_lookup(adapter_hash,
818 GINT_TO_POINTER(adapter_idx));
823 near_adapter_disconnect(adapter->idx);
824 if (adapter->constant_poll == TRUE)
825 adapter_start_poll(adapter);
830 __near_adapter_tags_changed(adapter_idx);
832 /* Check if adapter ndef queue has any ndef messages,
833 * then write the ndef data on tag. */
834 if (g_list_length(adapter->ndef_q) == 0)
837 tag = g_hash_table_lookup(adapter->tags,
838 GINT_TO_POINTER(target_idx));
842 ndef = __pop_ndef_queue(adapter);
846 tag_type = __near_tag_get_type(tag);
848 /* Add NDEF header information depends upon tag type */
850 case NFC_PROTO_JEWEL:
851 case NFC_PROTO_MIFARE:
852 ndef_with_header = g_try_malloc0(sizeof(
853 struct near_ndef_message));
854 if (ndef_with_header == NULL)
857 ndef_with_header->offset = 0;
858 ndef_with_header->length = ndef->length + 3;
859 ndef_with_header->data = g_try_malloc0(ndef->length + 3);
860 if (ndef_with_header->data == NULL)
863 ndef_with_header->data[0] = TLV_NDEF;
864 ndef_with_header->data[1] = ndef->length;
865 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
866 ndef_with_header->data[ndef->length + 2] = TLV_END;
870 case NFC_PROTO_FELICA:
871 ndef_with_header = g_try_malloc0(sizeof(
872 struct near_ndef_message));
873 if (ndef_with_header == NULL)
876 ndef_with_header->offset = 0;
877 ndef_with_header->length = ndef->length;
878 ndef_with_header->data = g_try_malloc0(
879 ndef_with_header->length);
880 if (ndef_with_header->data == NULL)
883 memcpy(ndef_with_header->data, ndef->data, ndef->length);
887 case NFC_PROTO_ISO14443:
888 ndef_with_header = g_try_malloc0(sizeof(
889 struct near_ndef_message));
890 if (ndef_with_header == NULL)
893 ndef_with_header->offset = 0;
894 ndef_with_header->length = ndef->length + 2;
895 ndef_with_header->data = g_try_malloc0(ndef->length + 2);
896 if (ndef_with_header->data == NULL)
899 ndef_with_header->data[0] = (uint8_t)(ndef->length >> 8);
900 ndef_with_header->data[1] = (uint8_t)(ndef->length);
901 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
912 err = __near_tag_add_ndef(tag, ndef_with_header, __add_ndef_cb);
914 g_free(ndef_with_header->data);
915 g_free(ndef_with_header);
922 if (ndef_with_header != NULL) {
923 g_free(ndef_with_header->data);
924 g_free(ndef_with_header);
928 adapter->presence_timeout =
929 g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
930 check_presence, adapter);
933 static int adapter_add_tag(struct near_adapter *adapter, uint32_t target_idx,
935 uint16_t sens_res, uint8_t sel_res,
936 uint8_t *nfcid, uint8_t nfcid_len)
938 struct near_tag *tag;
942 tag = __near_tag_add(adapter->idx, target_idx, protocols,
948 g_hash_table_insert(adapter->tags, GINT_TO_POINTER(target_idx),
951 tag_type = __near_tag_get_type(tag);
953 err = near_adapter_connect(adapter->idx, target_idx, tag_type);
955 near_error("Could not connect");
959 return __near_tag_read(tag, tag_read_cb);
962 int __near_adapter_add_target(uint32_t idx, uint32_t target_idx,
963 uint32_t protocols, uint16_t sens_res, uint8_t sel_res,
964 uint8_t *nfcid, uint8_t nfcid_len)
966 struct near_adapter *adapter;
970 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
974 adapter->polling = FALSE;
975 polling_changed(adapter);
977 if (protocols & NFC_PROTO_NFC_DEP_MASK)
980 return adapter_add_tag(adapter, target_idx, protocols,
981 sens_res, sel_res, nfcid, nfcid_len);
985 int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx)
987 struct near_adapter *adapter;
988 struct near_tag *tag;
992 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
996 tag = g_hash_table_lookup(adapter->tags, GINT_TO_POINTER(target_idx));
998 g_hash_table_remove(adapter->tags, GINT_TO_POINTER(target_idx));
1000 __near_adapter_tags_changed(idx);
1004 /* TODO search for devices */
1009 static void adapter_flush_rx(struct near_adapter *adapter, int error)
1013 for (list = adapter->ioreq_list; list; list = list->next) {
1014 struct near_adapter_ioreq *req = list->data;
1019 req->cb(NULL, error, req->data);
1023 g_list_free(adapter->ioreq_list);
1024 adapter->ioreq_list = NULL;
1027 static gboolean execute_recv_cb(gpointer user_data)
1029 struct near_adapter_ioreq *req = user_data;
1031 DBG("data %p", req->data);
1033 req->cb(req->buf, req->len, req->data);
1040 static gboolean adapter_recv_event(GIOChannel *channel, GIOCondition condition,
1043 struct near_adapter *adapter = user_data;
1044 struct near_adapter_ioreq *req;
1048 DBG("condition 0x%x", condition);
1050 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
1051 near_error("Error while reading NFC bytes");
1053 adapter_flush_rx(adapter, -EIO);
1057 sk = g_io_channel_unix_get_fd(channel);
1058 first = g_list_first(adapter->ioreq_list);
1063 req->len = recv(sk, req->buf, sizeof(req->buf), 0);
1065 adapter->ioreq_list = g_list_remove(adapter->ioreq_list, req);
1067 g_idle_add(execute_recv_cb, req);
1072 int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol)
1074 struct near_adapter *adapter;
1075 struct near_tag *tag;
1076 struct sockaddr_nfc addr;
1081 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
1082 if (adapter == NULL)
1085 if (adapter->tag_sock != -1)
1088 tag = g_hash_table_lookup(adapter->tags,
1089 GINT_TO_POINTER(target_idx));
1093 sock = socket(AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW);
1097 addr.sa_family = AF_NFC;
1099 addr.target_idx = target_idx;
1100 addr.nfc_protocol = protocol;
1102 err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
1108 adapter->tag_sock = sock;
1109 adapter->tag_link = tag;
1111 if (adapter->channel == NULL)
1112 adapter->channel = g_io_channel_unix_new(adapter->tag_sock);
1114 g_io_channel_set_flags(adapter->channel, G_IO_FLAG_NONBLOCK, NULL);
1115 g_io_channel_set_close_on_unref(adapter->channel, TRUE);
1117 if (adapter->watch == 0)
1118 adapter->watch = g_io_add_watch(adapter->channel,
1119 G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
1120 adapter_recv_event, adapter);
1125 int near_adapter_disconnect(uint32_t idx)
1127 struct near_adapter *adapter;
1128 uint32_t target_idx;
1133 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
1134 if (adapter == NULL)
1137 DBG("link %p", adapter->tag_link);
1139 if (adapter->tag_link == NULL)
1142 tag_type = __near_tag_get_type(adapter->tag_link);
1143 target_idx = __near_tag_get_idx(adapter->tag_link);
1145 DBG("tag type %d", tag_type);
1147 __near_adapter_remove_target(adapter->idx, target_idx);
1149 if (adapter->tag_sock == -1)
1152 if (adapter->watch > 0) {
1153 g_source_remove(adapter->watch);
1157 adapter->channel = NULL;
1158 close(adapter->tag_sock);
1159 adapter->tag_sock = -1;
1160 adapter->tag_link = NULL;
1165 int near_adapter_send(uint32_t idx, uint8_t *buf, size_t length,
1166 near_recv cb, void *data)
1168 struct near_adapter *adapter;
1169 struct near_adapter_ioreq *req = NULL;
1174 adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx));
1175 if (adapter == NULL)
1178 if (adapter->tag_sock == -1 || adapter->tag_link == NULL)
1181 if (cb != NULL && adapter->watch != 0) {
1182 req = g_try_malloc0(sizeof(*req));
1186 DBG("req %p cb %p data %p", req, cb, data);
1188 req->target_idx = __near_tag_get_idx(adapter->tag_link);
1192 adapter->ioreq_list =
1193 g_list_append(adapter->ioreq_list, req);
1196 err = send(adapter->tag_sock, buf, length, 0);
1204 GList *last = g_list_last(adapter->ioreq_list);
1207 adapter->ioreq_list =
1208 g_list_delete_link(adapter->ioreq_list, last);
1214 int __near_adapter_init(void)
1218 connection = near_dbus_get_connection();
1220 adapter_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1221 NULL, free_adapter);
1226 void __near_adapter_cleanup(void)
1230 g_hash_table_destroy(adapter_hash);
1231 adapter_hash = NULL;