struct carrier_data *__near_agent_handover_request_data( enum ho_agent_carrier carrier, struct carrier_data *data) { DBusMessage *message; DBusMessage *reply; DBusError error; struct carrier_data *data_reply; struct near_handover_agent *agent = NULL; agent = g_hash_table_lookup(ho_agent_hash, GINT_TO_POINTER(carrier)); if (!agent) return NULL; message = dbus_message_new_method_call(agent->sender, agent->path, NFC_HANDOVER_AGENT_INTERFACE, "RequestOOB"); if (!message) return NULL; prepare_data(message, data); dbus_error_init(&error); reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error); dbus_message_unref(message); if (!reply) { if (dbus_error_is_set(&error)) { near_error("RequestOOB failed: %s", error.message); dbus_error_free(&error); } else { near_error("RequestOOB failed"); } return NULL; } data_reply = parse_reply(reply); dbus_message_unref(reply); DBG("OOB data %p", data_reply); return data_reply; }
int __near_adapter_get_targets_done(uint32_t idx) { struct near_adapter *adapter; DBG("idx %d", idx); adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx)); if (!adapter) return -ENODEV; if (g_hash_table_size(adapter->devices) > 0) return 0; if (g_hash_table_size(adapter->tags) > 0) return 0; near_error("No targets found - Polling error"); adapter->polling = false; polling_changed(adapter); g_idle_add(poll_error, adapter); return 0; }
/* This function reads the MAD2 sector */ static int mifare_read_MAD2(void *data) { struct mifare_cookie *mf_ck = data; int err = 0; DBG(""); /* As auth is ok, allocate Mifare Access Directory v1 */ mf_ck->mad_2 = g_try_malloc0(STD_SECTOR_SIZE); if (!mf_ck->mad_2) { near_error("Memory allocation failed (MAD2)"); err = -ENOMEM; goto out_err; } err = mifare_read_sector(data, (uint8_t *) mf_ck->mad_2, (int) STD_SECTOR_SIZE, MAD2_SECTOR, /* sector 0x10 */ WITH_TRAILER, /* Want Trailer */ read_MAD2_complete); if (err < 0) goto out_err; return err; out_err: return mifare_release(err, mf_ck); }
static DBusMessage *start_poll_loop(DBusConnection *conn, DBusMessage *msg, void *data) { struct near_adapter *adapter = data; const char *dbus_mode; int err; DBG("conn %p", conn); if (!adapter->powered) { near_error("Adapter is down, can not start polling"); return __near_error_failed(msg, ENODEV); } dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dbus_mode, DBUS_TYPE_INVALID); DBG("Mode %s", dbus_mode); if (g_strcmp0(dbus_mode, "Initiator") == 0) adapter->poll_mode = NEAR_ADAPTER_MODE_INITIATOR; else if (g_strcmp0(dbus_mode, "Target") == 0) adapter->poll_mode = NEAR_ADAPTER_MODE_TARGET; else if (g_strcmp0(dbus_mode, "Dual") == 0) adapter->poll_mode = NEAR_ADAPTER_MODE_DUAL; else adapter->poll_mode = NEAR_ADAPTER_MODE_INITIATOR; err = adapter_start_poll(adapter); if (err < 0) return __near_error_failed(msg, -err); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); }
static gboolean snep_core_push_event(GIOChannel *channel, GIOCondition condition, gpointer data) { int err; DBG("push_event condition 0x%x", condition); if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { near_error("Error with SNEP channel"); free_snep_core_push_data(data, -1); return FALSE; } err = snep_core_push_response(data); if (err <= 0) { free_snep_core_push_data(data, err); return FALSE; } return TRUE; }
static void open_channel_cb(void *context, uint8_t *apdu, size_t apdu_length, int err) { struct open_channel_context *ctx = context; struct seel_apdu *select_aid; DBG(""); if (err || !apdu) return open_channel_error(ctx, err); /* Check response status */ err = __seel_apdu_resp_status(apdu, apdu_length); if (err) { DBG("err %d", err); return open_channel_error(ctx, err); } ctx->channel = apdu[0]; DBG("Channel %d", ctx->channel); select_aid = __seel_apdu_select_aid(ctx->channel, ctx->aid, ctx->aid_len); /* Send the AID selection APDU */ err = __seel_se_queue_io(ctx->se, select_aid, select_aid_cb, ctx); if (err < 0) { near_error("AID err %d", err); return; } return; }
/* * This function is called when a new client (Phdc Agent) connects on the * same p2p service as the one we previously registered. We have to find the * right Phdc Manager (with the service name) to send it the file descriptor. */ static bool phdc_p2p_newclient(char *service_name, int agent_fd, gpointer data) { DBusMessage *msg; DBusMessageIter args; struct near_phdc_data *mgr; DBG(""); if ((!agent_fd) || (!service_name)) return false; DBG("service name: %s fd: %d", service_name, agent_fd); /* Look for existing service name */ mgr = g_hash_table_lookup(mgr_list, service_name); if (!mgr) return false; mgr->p2p_driver->user_data = mgr; /* Call the pdhc manager */ msg = dbus_message_new_method_call(mgr->sender, mgr->path, PHDC_MANAGER_IFACE, AGENT_NEWCONNECTION); if (!msg) { near_error("msg NULL"); return false; } /* Add args */ dbus_message_iter_init_append(msg, &args); if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UNIX_FD, &agent_fd)) { near_error("out of memory"); return false; } dbus_message_set_no_reply(msg, TRUE); if (g_dbus_send_message(phdc_conn, msg) == FALSE) { near_error("Dbus send failed"); return false; } return true; }
static int nfc_netlink_event(struct nl_msg *n, void *arg) { struct sockaddr_nl *src = nlmsg_get_src(n); struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(n)); DBG("event 0x%x", gnlh->cmd); if (src->nl_pid) { near_error("WARNING: Wrong netlink message sender %d", src->nl_pid); return NL_SKIP; } switch (gnlh->cmd) { case NFC_EVENT_TARGETS_FOUND: DBG("Targets found"); nfc_netlink_event_targets_found(gnlh); break; case NFC_EVENT_TARGET_LOST: DBG("Target lost"); nfc_netlink_event_target_lost(gnlh); break; case NFC_EVENT_DEVICE_ADDED: DBG("Adapter added"); nfc_netlink_event_adapter(gnlh, true); break; case NFC_EVENT_DEVICE_REMOVED: DBG("Adapter removed"); nfc_netlink_event_adapter(gnlh, false); break; case NFC_CMD_DEP_LINK_UP: DBG("DEP link is up"); nfc_netlink_event_dep_up(gnlh); break; case NFC_CMD_DEP_LINK_DOWN: DBG("DEP link is down"); nfc_netlink_event_dep_down(gnlh); break; case NFC_EVENT_TM_ACTIVATED: DBG("Target mode activated"); nfc_netlink_event_tm_activated(gnlh); break; case NFC_EVENT_TM_DEACTIVATED: DBG("Target mode deactivated"); nfc_netlink_event_tm_deactivated(gnlh); break; } return NL_SKIP; }
static int nfc_netlink_event_adapter(struct genlmsghdr *gnlh, bool add) { struct nlattr *attrs[NFC_ATTR_MAX + 1]; uint32_t idx; DBG(""); nla_parse(attrs, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NFC_ATTR_DEVICE_INDEX]) { near_error("Missing device index"); return -ENODEV; } idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]); if (add && (!attrs[NFC_ATTR_DEVICE_NAME] || !attrs[NFC_ATTR_PROTOCOLS])) { near_error("Missing attributes"); return -EINVAL; } if (add) { char *name; uint32_t protocols; bool powered; name = nla_get_string(attrs[NFC_ATTR_DEVICE_NAME]); protocols = nla_get_u32(attrs[NFC_ATTR_PROTOCOLS]); if (!attrs[NFC_ATTR_DEVICE_POWERED]) powered = false; else powered = nla_get_u8(attrs[NFC_ATTR_DEVICE_POWERED]); return __near_manager_adapter_add(idx, name, protocols, powered); } else { __near_manager_adapter_remove(idx); } return 0; }
static void phdc_p2p_close(int agent_fd, int err, gpointer data) { DBusMessage *msg; DBusMessageIter args; struct near_phdc_data *mgr; mgr = (struct near_phdc_data *)data; DBG("fd: %d err: %d mgr:%p", agent_fd, err, mgr); if (!mgr) { near_error("mgr is null"); return; } msg = dbus_message_new_method_call(mgr->sender, mgr->path, PHDC_MANAGER_IFACE, AGENT_DISCONNECT); if (!msg) { near_error("msg NULL"); return; } dbus_message_iter_init_append(msg, &args); if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UNIX_FD, &agent_fd)) { near_error("out of memory"); return; } dbus_message_iter_init_append(msg, &args); if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &err)) { near_error("out of memory"); return; } dbus_message_set_no_reply(msg, TRUE); if (g_dbus_send_message(phdc_conn, msg) == FALSE) near_error("Dbus send failed"); return; }
/* * If one of NFC sectors isn't writable, * tag size for writing is smaller than actual memory size, * so calculate it and check if it is enough for ndef message. */ static int writing_not_permitted(void *data) { struct mifare_cookie *mf_ck = data; unsigned int new_tag_size = 0; int sector_id; int i; sector_id = GPOINTER_TO_INT(mf_ck->acc_sect->data); DBG("Writing sector %i not permitted", sector_id); /* Read only sector found, calculate new tag size */ if (sector_id <= MAD_V1_AIDS_LEN) { for (i = GPOINTER_TO_INT(mf_ck->g_sect_list->data); i < sector_id; i++) new_tag_size += SECTOR_SIZE; } else { /* Start from first NFC sector */ for (i = GPOINTER_TO_INT(mf_ck->g_sect_list->data); i <= MAD_V1_AIDS_LEN; i++) new_tag_size += SECTOR_SIZE; /* * If any of previous sector was NFC, skip MAD2 * If not, leave "i" as it was */ if (i < MAD2_SECTOR) i = MAD2_SECTOR + 1; for (; i < sector_id; i++) { if (i < T4K_BOUNDARY) new_tag_size += SECTOR_SIZE; else new_tag_size += BIG_SECTOR_SIZE; } } DBG("TAG writable sectors' size: [%d].", new_tag_size); /* Check if there's enough space on tag */ if (new_tag_size < mf_ck->ndef->length) { near_error("Not enough space on tag"); if (mf_ck->cb) mf_ck->cb(mf_ck->adapter_idx, mf_ck->target_idx, -ENOSPC); mifare_release(0, data); return -ENOSPC; } /* Enough space on tag, continue writing */ mifare_write_NFC(data); return 0; }
static void select_aid_cb(void *context, uint8_t *apdu, size_t apdu_length, int err) { struct open_channel_context *ctx = context; struct seel_apdu *close_channel; struct seel_channel *channel; char *path; DBusConnection *conn; int ret; conn = near_dbus_get_connection(); if (err != 0) { /* * err != 0 means SW != 9000. * In this case, we need to clean the previously * allocated logical channel. */ close_channel = __seel_apdu_close_logical_channel(ctx->channel); if (!close_channel) goto err; ret = __seel_se_queue_io(ctx->se, close_channel, NULL, ctx); if (ret < 0) { near_error("close channel error %d", ret); err = ret; } goto err; } channel = __seel_channel_add(ctx->se, ctx->channel, ctx->aid, ctx->aid_len, false); if (!channel) { err = -ENOMEM; goto err; } path = __seel_channel_get_path(channel); g_hash_table_replace(ctx->se->channel_hash, path, channel); g_dbus_send_reply(conn, ctx->msg, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); dbus_message_unref(ctx->msg); ctx->msg = NULL; g_free(ctx); return; err: return open_channel_error(ctx, err); }
int mifare_check_presence(uint32_t adapter_idx, uint32_t target_idx, near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype) { struct mifare_cmd cmd; struct mifare_cookie *cookie; uint8_t *key_ref = MAD_public_key; DBG(""); /* Check supported and tested Mifare type */ switch (tgt_subtype) { case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K: case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K: break; default: near_error("Mifare tag type %d not supported.", tgt_subtype); return -1; } /* Alloc global cookie */ cookie = g_try_malloc0(sizeof(struct mifare_cookie)); if (!cookie) return -ENOMEM; /* Get the nfcid1 */ cookie->nfcid1 = near_tag_get_nfcid(adapter_idx, target_idx, &cookie->nfcid1_len); cookie->adapter_idx = adapter_idx; cookie->target_idx = target_idx; cookie->cb = cb; /* * To check presence of Mifare Classic Tag, * send authentication command instead of read one */ cmd.cmd = MF_CMD_AUTH_KEY_A; /* Authenticate the 1st block of the MAD sector */ cmd.block = MAD1_1ST_BLOCK; /* Store the AUTH KEY */ memcpy(&cmd.key, key_ref, MAD_KEY_LEN); /* add the UID */ memcpy(&cmd.nfcid, cookie->nfcid1, cookie->nfcid1_len); return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd, sizeof(cmd) - NFC_NFCID1_MAXSIZE + cookie->nfcid1_len, check_presence, cookie, mifare_release); }
static int nfc_netlink_event_dep_up(struct genlmsghdr *gnlh) { struct nlattr *attrs[NFC_ATTR_MAX + 1]; uint32_t idx, target_idx = 0; uint8_t rf_mode; DBG(""); nla_parse(attrs, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NFC_ATTR_DEVICE_INDEX]) { near_error("Missing device index"); return -ENODEV; } if (!attrs[NFC_ATTR_COMM_MODE] || !attrs[NFC_ATTR_RF_MODE]) { near_error("Missing rf or comm modes"); return -ENODEV; } idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]); rf_mode = nla_get_u8(attrs[NFC_ATTR_RF_MODE]); if (rf_mode == NFC_RF_INITIATOR) { if (!attrs[NFC_ATTR_TARGET_INDEX]) { near_error("Missing target index"); return -ENODEV; }; target_idx = nla_get_u32(attrs[NFC_ATTR_TARGET_INDEX]); DBG("%d %d", idx, target_idx); return __near_adapter_set_dep_state(idx, true); } else { return -EOPNOTSUPP; } }
static int adapter_add_tag(struct near_adapter *adapter, uint32_t target_idx, uint32_t protocols, uint16_t sens_res, uint8_t sel_res, uint8_t *nfcid, uint8_t nfcid_len, uint8_t iso15693_dsfid, uint8_t iso15693_uid_len, uint8_t *iso15693_uid) { struct near_tag *tag; uint32_t tag_type; int err; tag = __near_tag_add(adapter->idx, target_idx, protocols, sens_res, sel_res, nfcid, nfcid_len, iso15693_dsfid, iso15693_uid_len, iso15693_uid); if (!tag) return -ENODEV; g_hash_table_insert(adapter->tags, GINT_TO_POINTER(target_idx), tag); tag_type = __near_tag_get_type(tag); err = near_adapter_connect(adapter->idx, target_idx, tag_type); if (err < 0) { near_error("Could not connect"); return err; } err = __near_tag_read(tag, tag_read_cb); if (err < 0) { near_error("Could not read the tag"); near_adapter_disconnect(adapter->idx); __near_adapter_remove_target(adapter->idx, target_idx); } return err; }
static int se_toggle(struct seel_se *se, bool enable) { DBG(""); if (se->ctrl_driver == NULL) { near_error("No controller driver"); return -EOPNOTSUPP; } if (enable) return se->ctrl_driver->enable_se(se->ctrl_idx, se->se_idx); else return se->ctrl_driver->disable_se(se->ctrl_idx, se->se_idx); }
/* add the new phdc manager if the associated service is not already there */ static int manager_add_to_list(struct near_phdc_data *mgr) { DBG(" mgr service name %s", mgr->p2p_driver->service_name); if (g_hash_table_lookup(mgr_list, mgr->p2p_driver->service_name)) { near_error("[%s] already present", mgr->p2p_driver->service_name); return -EALREADY; } g_hash_table_insert(mgr_list, mgr->p2p_driver->service_name, mgr); return 0; }
/* * MIFARE: entry point: * Read all the MAD sectors (0x00, 0x10) to get the Application Directory * entries. * On sector 0x00, App. directory is on block 0x01 & block 0x02 * On sector 0x10, App. directory is on block 0x40, 0x41 & 0x42 * On reading, CRC is ignored. */ int mifare_read(uint32_t adapter_idx, uint32_t target_idx, near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype) { struct mifare_cookie *cookie; int err; DBG(""); /*Check supported and tested Mifare type */ switch (tgt_subtype) { case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K: case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K: break; default: near_error("Mifare tag type [%d] not supported.", tgt_subtype); return -1; } /* Alloc global cookie */ cookie = g_try_malloc0(sizeof(struct mifare_cookie)); if (!cookie) return -ENOMEM; /* Get the nfcid1 */ cookie->nfcid1 = near_tag_get_nfcid(adapter_idx, target_idx, &cookie->nfcid1_len); cookie->adapter_idx = adapter_idx; cookie->target_idx = target_idx; cookie->cb = cb; /* check access rights - while reading just check read only */ cookie->acc_check_function = mifare_check_read_only; /* * Need to unlock before reading * This will check if public keys are allowed (and, so, NDEF could * be "readable"... */ err = mifare_unlock_sector(MAD1_1ST_BLOCK, /* related block */ mifare_read_MAD1, /* callback function */ cookie); /* target data */ if (err < 0) return mifare_release(err, cookie); return 0; }
static void close_channel_error(struct close_channel_context *ctx, int err) { DBusMessage *reply; DBusConnection *conn; near_error("error %d", err); conn = near_dbus_get_connection(); reply = __near_error_failed(ctx->msg, -err); if (reply != NULL) g_dbus_send_message(conn, reply); dbus_message_unref(ctx->msg); ctx->msg = NULL; g_free(ctx); }
static DBusMessage *close_channel(DBusConnection *conn, DBusMessage *msg, void *data) { struct seel_se *se = data; const char *path; int err; struct close_channel_context *ctx; struct seel_apdu *close_channel; if (se->enabled == false) return __near_error_failed(msg, ENODEV); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return __near_error_invalid_arguments(msg); ctx = g_try_malloc0(sizeof(struct open_channel_context)); if (ctx == NULL) return __near_error_failed(msg, ENOMEM); ctx->channel = g_hash_table_lookup(se->channel_hash, path); if (!ctx->channel) { g_free(ctx); return __near_error_invalid_arguments(msg); } ctx->se = se; ctx->chn = __seel_channel_get_channel(ctx->channel); close_channel = __seel_apdu_close_logical_channel(ctx->chn); if (!close_channel) { g_free(ctx); return __near_error_failed(msg, ENOMEM); } ctx->msg = dbus_message_ref(msg); err = __seel_se_queue_io(se, close_channel, close_channel_cb, ctx); if (err < 0) { near_error("close channel error %d", err); return NULL; } return NULL; }
static gboolean poll_error(gpointer user_data) { struct near_adapter *adapter = user_data; bool reset; DBG("adapter %d", adapter->idx); reset = near_setting_get_bool("ResetOnError"); if (reset) { near_error("Resetting nfc%d", adapter->idx); __near_netlink_adapter_enable(adapter->idx, false); __near_netlink_adapter_enable(adapter->idx, true); } adapter_start_poll(adapter); return FALSE; }
static int adapter_add_device(struct near_adapter *adapter, uint32_t target_idx, uint8_t *nfcid, uint8_t nfcid_len) { struct near_device *device; int err; DBG(); device = __near_device_add(adapter->idx, target_idx, nfcid, nfcid_len); if (!device) return -ENODEV; g_hash_table_insert(adapter->devices, GINT_TO_POINTER(target_idx), device); /* For p2p, reading is listening for an incoming connection */ err = __near_device_listen(device, device_read_cb); if (err < 0) { near_error("Could not read device"); return err; } adapter->device_link = device; if (adapter->dep_up) { if (!__near_device_register_interface(device)) return -ENODEV; return 0; } err = __near_netlink_dep_link_up(adapter->idx, target_idx, NFC_COMM_ACTIVE, NFC_RF_INITIATOR); if (err < 0) adapter->device_link = NULL; DBG("Starting DEP timer"); adapter->dep_timer = g_timeout_add_seconds(1, dep_timer, adapter); return err; }
static DBusMessage *open_channel(DBusConnection *conn, DBusMessage *msg, void *data) { struct seel_se *se = data; unsigned char *aid; int aid_len, err; struct open_channel_context *ctx; struct seel_apdu *open_channel; DBG(""); if (se->enabled == false) return __near_error_failed(msg, ENODEV); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &aid, &aid_len, DBUS_TYPE_INVALID)) return __near_error_invalid_arguments(msg); ctx = g_try_malloc0(sizeof(struct open_channel_context)); if (ctx == NULL) return __near_error_failed(msg, ENOMEM); open_channel = __seel_apdu_open_logical_channel(); if (open_channel == NULL) { g_free(ctx); return __near_error_failed(msg, ENOMEM); } ctx->msg = dbus_message_ref(msg); ctx->se = se; ctx->aid = aid; ctx->aid_len = aid_len; err = __seel_se_queue_io(se, open_channel, open_channel_cb, ctx); if (err < 0) { near_error("open channel error %d", err); return NULL; } return NULL; }
static int __nl_send_msg(struct nl_sock *sock, struct nl_msg *msg, int (*rx_handler)(struct nl_msg *, void *), int (*finish_handler)(struct nl_msg *, void *), void *data) { struct nl_cb *cb; int err, done; struct send_msg_data send_data; DBG(""); cb = nl_cb_alloc(NL_CB_DEFAULT); if (!cb) return -ENOMEM; err = nl_send_auto_complete(sock, msg); if (err < 0) { nl_cb_put(cb); near_error("%s", strerror(err)); return err; } err = done = 0; send_data.done = &done; send_data.data = data; send_data.finish_handler = finish_handler; nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, __finish_handler, &send_data); nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done); if (rx_handler) nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data); while (err == 0 && done == 0) nl_recvmsgs(sock, cb); nl_cb_put(cb); return err; }
static int nfc_netlink_event_tm_deactivated(struct genlmsghdr *gnlh) { struct nlattr *attrs[NFC_ATTR_MAX + 1]; uint32_t idx; DBG(""); nla_parse(attrs, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NFC_ATTR_DEVICE_INDEX]) { near_error("Missing device index"); return -ENODEV; } idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]); DBG("%d", idx); return __near_adapter_remove_device(idx); }
static int nfc_netlink_event_dep_down(struct genlmsghdr *gnlh) { struct nlattr *attrs[NFC_ATTR_MAX + 1]; uint32_t idx; DBG(""); nla_parse(attrs, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); if (!attrs[NFC_ATTR_DEVICE_INDEX]) { near_error("Missing device index"); return -ENODEV; } idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]); __near_adapter_set_dep_state(idx, false); return 0; }
/* * This code will read the ndef message. * return <0 on error * ==0 if not more bytes * >0 if there's still some data to read */ static int snep_core_read_ndef(int client_fd, struct p2p_snep_data *snep_data) { int bytes_recv, remaining_bytes; DBG(""); remaining_bytes = snep_data->nfc_data_length - snep_data->nfc_data_current_length; bytes_recv = recv(client_fd, snep_data->nfc_data_ptr, remaining_bytes, MSG_DONTWAIT); if (bytes_recv < 0) { near_error("%d %s", bytes_recv, strerror(errno)); /* Some more data should show up */ if (errno == EAGAIN) return EAGAIN; /* Positive !!*/ goto out; } snep_data->nfc_data_current_length += bytes_recv; snep_data->nfc_data_ptr += bytes_recv; /* Is the read complete ? */ if (snep_data->nfc_data_length == snep_data->nfc_data_current_length) return 0; if (!snep_data->respond_continue) { snep_data->respond_continue = TRUE; near_snep_core_response_noinfo(client_fd, NEAR_SNEP_RESP_CONTINUE); } return 1; out: g_hash_table_remove(snep_client_hash, GINT_TO_POINTER(client_fd)); return -errno; /* Negative on error */ }
int __near_adapter_set_dep_state(uint32_t idx, bool dep) { struct near_adapter *adapter; DBG("idx %d", idx); adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(idx)); if (!adapter) return -ENODEV; adapter->dep_up = dep; if (!dep && adapter->constant_poll) { /* * The immediate polling may fail if the adapter is busy in * that very moment. In this case we need to try polling later * again, so constant polling will work properly. */ if(adapter_start_poll(adapter) == -EBUSY) { near_error("Adapter is busy, retry polling later"); g_timeout_add_seconds(1, dep_timer, adapter); } } if (!dep) { uint32_t target_idx; target_idx = __neard_device_get_idx(adapter->device_link); __near_adapter_remove_target(idx, target_idx); } else { if (adapter->dep_timer > 0) g_source_remove(adapter->dep_timer); if (!__near_device_register_interface(adapter->device_link)) return -ENODEV; } return 0; }
/* * Function called to read the first MAD sector * MAD is mandatory */ static int mifare_read_MAD1(uint8_t *resp, int length, void *data) { struct mifare_cookie *mf_ck = data; int err = 0; DBG("%p %d", data, length); if (length < 0) { err = length; return err; } /* * As auth is ok, allocate Mifare Access Directory v1 * allocated size is also STD_SECTOR_SIZE */ mf_ck->mad_1 = g_try_malloc0(STD_SECTOR_SIZE); if (!mf_ck->mad_1) { near_error("Memory allocation failed (MAD1)"); err = -ENOMEM; goto out_err; } /* Call to mifare_read_sector */ err = mifare_read_sector(data, (uint8_t *)mf_ck->mad_1, /* where to store */ (int) STD_SECTOR_SIZE, /* allocated size */ MAD1_SECTOR, /* sector 0 */ WITH_TRAILER, /* Want Trailer */ read_MAD1_complete); if (err < 0) goto out_err; return err; out_err: return mifare_release(err, mf_ck); }
static gboolean adapter_recv_event(GIOChannel *channel, GIOCondition condition, gpointer user_data) { struct near_adapter *adapter = user_data; struct near_adapter_ioreq *req; GList *first; int sk; DBG("condition 0x%x", condition); if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { near_error("Error while reading NFC bytes"); adapter_flush_rx(adapter, -EIO); near_adapter_disconnect(adapter->idx); adapter->presence_timeout = g_timeout_add_seconds(2 * CHECK_PRESENCE_PERIOD, check_presence, adapter); return FALSE; } sk = g_io_channel_unix_get_fd(channel); first = g_list_first(adapter->ioreq_list); if (!first) return TRUE; req = first->data; req->len = recv(sk, req->buf, sizeof(req->buf), 0); adapter->ioreq_list = g_list_remove(adapter->ioreq_list, req); g_idle_add(execute_recv_cb, req); return TRUE; }