diff options
| -rw-r--r-- | hcid/dbus.c | 44 | ||||
| -rw-r--r-- | hcid/dbus.h | 5 | ||||
| -rw-r--r-- | hcid/security.c | 12 | 
3 files changed, 60 insertions, 1 deletions
| diff --git a/hcid/dbus.c b/hcid/dbus.c index 8f0217ec..ce6f4e70 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -285,6 +285,7 @@ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *m  static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data);  static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data);  static DBusMessage* handle_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data);  static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data);  static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data);  static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data); @@ -295,6 +296,7 @@ static const struct service_data hci_services[] = {  	{ HCI_CANCEL_PERIODIC_INQ,	handle_cancel_periodic_inq_req,	HCI_CANCEL_PERIODIC_INQ_SIGNATURE	},  	{ HCI_ROLE_SWITCH,		handle_role_switch_req,		HCI_ROLE_SWITCH_SIGNATURE		},  	{ HCI_INQ,			handle_inq_req,			HCI_INQ_SIGNATURE			}, +	{ HCI_CANCEL_INQ,		handle_cancel_inq_req,		HCI_CANCEL_INQ_SIGNATURE		},  	{ HCI_REMOTE_NAME,		handle_remote_name_req,		HCI_REMOTE_NAME_SIGNATURE		},  	{ HCI_CONNECTIONS,		handle_display_conn_req,	HCI_CONNECTIONS_SIGNATURE		},  	{ HCI_AUTHENTICATE,		handle_auth_req,		HCI_AUTHENTICATE_SIGNATURE		}, @@ -1383,6 +1385,48 @@ failed:  	return reply;  } +static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data) +{ +	DBusMessage *reply = NULL; +	struct hci_request rq; +	struct hci_dbus_data *dbus_data = data; +	int dev_id = -1, dd = -1; + +	if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { +		if ((dev_id = hci_get_route(NULL)) < 0) { +			syslog(LOG_ERR, "Bluetooth device is not available"); +			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); +			goto failed; +		} +	} else +		dev_id = dbus_data->id; + +	dd = hci_open_dev(dev_id); +	if (dd < 0) { +		syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	memset(&rq, 0, sizeof(rq)); +	rq.ogf = OGF_LINK_CTL; +	rq.ocf = OCF_INQUIRY_CANCEL; + +	if (hci_send_req(dd, &rq, 100) < 0) { +		syslog(LOG_ERR, "Unable to cancel inquiry: %s", strerror(errno)); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	reply = dbus_message_new_method_return(msg); + +failed: +	if (dd >= 0) +		hci_close_dev(dd); + +	return reply; +} +  static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data)  {  	DBusMessageIter iter; diff --git a/hcid/dbus.h b/hcid/dbus.h index b12934b3..0e18aea3 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -105,10 +105,11 @@  #define HCI_PERIODIC_INQ		"PeriodicInquiry"  #define HCI_CANCEL_PERIODIC_INQ		"CancelPeriodic"  #define HCI_INQ				"Inquiry" +#define HCI_CANCEL_INQ			"CancelInquiry"  #define HCI_ROLE_SWITCH			"RoleSwitch"  #define HCI_REMOTE_NAME			"RemoteName"  #define HCI_CONNECTIONS			"Connections" -#define HCI_AUTHENTICATE			"Authenticate" +#define HCI_AUTHENTICATE		"Authenticate"  #define HCI_PERIODIC_INQ_SIGNATURE			DBUS_TYPE_BYTE_AS_STRING\ @@ -122,6 +123,8 @@  							DBUS_TYPE_BYTE_AS_STRING\  							__END_SIG__ +#define HCI_CANCEL_INQ_SIGNATURE			__END_SIG__ +  #define HCI_ROLE_SWITCH_SIGNATURE			DBUS_TYPE_STRING_AS_STRING\  							DBUS_TYPE_BYTE_AS_STRING\  							__END_SIG__ diff --git a/hcid/security.c b/hcid/security.c index f53d33d1..670f8dde 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -493,6 +493,14 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr)  		hcid_dbus_inquiry_start(sba);  } +static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) +{ +	evt_cmd_complete *evt = ptr; + +	if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL)) +		hcid_dbus_inquiry_complete(sba); +} +  static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr)  {  	evt_remote_name_req_complete *evt = ptr; @@ -679,6 +687,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer  		cmd_status(dev, &di->bdaddr, ptr);  		break; +	case EVT_CMD_COMPLETE: +		cmd_complete(dev, &di->bdaddr, ptr); +		break; +  	case EVT_REMOTE_NAME_REQ_COMPLETE:  		remote_name_information(dev, &di->bdaddr, ptr);  		break; | 
