예제 #1
0
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;
}
예제 #2
0
파일: adapter.c 프로젝트: aklein53/neard
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;
}
예제 #3
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);
}
예제 #4
0
파일: adapter.c 프로젝트: aklein53/neard
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);
}
예제 #5
0
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;
}
예제 #6
0
파일: se.c 프로젝트: aklein53/neard
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;
}
예제 #7
0
/*
 * 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;
}
예제 #8
0
파일: netlink.c 프로젝트: aklein53/neard
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;
}
예제 #9
0
파일: netlink.c 프로젝트: aklein53/neard
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;
}
예제 #10
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;
}
예제 #11
0
/*
 * 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;
}
예제 #12
0
파일: se.c 프로젝트: aklein53/neard
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);
}
예제 #13
0
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);
}
예제 #14
0
파일: netlink.c 프로젝트: aklein53/neard
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;
	}
}
예제 #15
0
파일: adapter.c 프로젝트: aklein53/neard
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;
}
예제 #16
0
파일: se.c 프로젝트: aklein53/neard
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);
}
예제 #17
0
/* 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;
}
예제 #18
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;
}
예제 #19
0
파일: se.c 프로젝트: aklein53/neard
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);
}
예제 #20
0
파일: se.c 프로젝트: aklein53/neard
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;
}
예제 #21
0
파일: adapter.c 프로젝트: aklein53/neard
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;
}
예제 #22
0
파일: adapter.c 프로젝트: aklein53/neard
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;
}
예제 #23
0
파일: se.c 프로젝트: aklein53/neard
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;
}
예제 #24
0
파일: netlink.c 프로젝트: aklein53/neard
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;
}
예제 #25
0
파일: netlink.c 프로젝트: aklein53/neard
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);
}
예제 #26
0
파일: netlink.c 프로젝트: aklein53/neard
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;
}
예제 #27
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 */
}
예제 #28
0
파일: adapter.c 프로젝트: aklein53/neard
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;
}
예제 #29
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);
}
예제 #30
0
파일: adapter.c 프로젝트: aklein53/neard
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;
}