diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2005-08-25 18:32:40 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2005-08-25 18:32:40 +0000 | 
| commit | 4eb7a31e82e765a2ccb74b0fb4637c3cdf386786 (patch) | |
| tree | 1b82805db1e6c6f8ff24e46c13d765cf5a2066bf | |
| parent | a4d0ca683bcbdda57c1035764752669bceb5b339 (diff) | |
Update D-Bus support for inquiry and connection tracking
| -rw-r--r-- | hcid/dbus.c | 114 | ||||
| -rw-r--r-- | hcid/hcid.h | 16 | ||||
| -rw-r--r-- | hcid/security.c | 59 | 
3 files changed, 167 insertions, 22 deletions
| diff --git a/hcid/dbus.c b/hcid/dbus.c index de51eee6..b6f516c0 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -112,7 +112,6 @@ error:  				OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);  } -  static void free_pin_req(void *req)  {  	free(req); @@ -173,15 +172,93 @@ failed:  				OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr);  } -void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) +void hcid_dbus_inquiry_start(bdaddr_t *local)  {  	DBusMessage *message; -	char local_addr[18], peer_addr[18]; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +	DBusMessageIter iter; +#endif +	char local_addr[18]; + +	ba2str(local, local_addr); + +	message = dbus_message_new_signal("/org/bluez/DevAgent", +				"org.bluez.DevAgent", "InquiryStart"); +	if (message == NULL) { +		syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message"); +		goto failed; +	} +  #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS -	char *local_ptr = local_addr, *peer_ptr = peer_addr; +	dbus_message_append_args(message, +					DBUS_TYPE_STRING, local_addr, +					DBUS_TYPE_INVALID);  #else +	dbus_message_append_iter_init(message, &iter); + +	dbus_message_iter_append_string(&iter, local_addr); +#endif + +	if (dbus_connection_send(connection, message, NULL) == FALSE) { +		syslog(LOG_ERR, "Can't send D-BUS inquiry start message"); +		goto failed; +	} + +	dbus_connection_flush(connection); + +failed: +	dbus_message_unref(message); + +	return; +} + +void hcid_dbus_inquiry_complete(bdaddr_t *local) +{ +	DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS  	DBusMessageIter iter;  #endif +	char local_addr[18]; + +	ba2str(local, local_addr); + +	message = dbus_message_new_signal("/org/bluez/DevAgent", +				"org.bluez.DevAgent", "InquiryComplete"); +	if (message == NULL) { +		syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); +		goto failed; +	} + +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +	dbus_message_append_args(message, +					DBUS_TYPE_STRING, local_addr, +					DBUS_TYPE_INVALID); +#else +	dbus_message_append_iter_init(message, &iter); + +	dbus_message_iter_append_string(&iter, local_addr); +#endif + +	if (dbus_connection_send(connection, message, NULL) == FALSE) { +		syslog(LOG_ERR, "Can't send D-BUS inquiry complete message"); +		goto failed; +	} + +	dbus_connection_flush(connection); + +failed: +	dbus_message_unref(message); + +	return; +} + +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) +{ +	DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +	DBusMessageIter iter; +#endif +	char local_addr[18], peer_addr[18];  	ba2str(local, local_addr);  	ba2str(peer, peer_addr); @@ -195,10 +272,10 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i  #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS  	dbus_message_append_args(message, -					DBUS_TYPE_STRING, &local_ptr, -					DBUS_TYPE_STRING, &peer_ptr, -					DBUS_TYPE_UINT32, &class, -					DBUS_TYPE_INT32, &rssi, +					DBUS_TYPE_STRING, local_addr, +					DBUS_TYPE_STRING, peer_addr, +					DBUS_TYPE_UINT32, class, +					DBUS_TYPE_INT32, rssi,  					DBUS_TYPE_INVALID);  #else  	dbus_message_append_iter_init(message, &iter); @@ -225,13 +302,10 @@ failed:  void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)  {  	DBusMessage *message; -	char local_addr[18], peer_addr[18]; -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS -	char *local_ptr = local_addr, *peer_ptr = peer_addr; -	char *name_ptr = name; -#else +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS  	DBusMessageIter iter;  #endif +	char local_addr[18], peer_addr[18];  	ba2str(local, local_addr);  	ba2str(peer, peer_addr); @@ -245,9 +319,9 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)  #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS  	dbus_message_append_args(message, -					DBUS_TYPE_STRING, &local_ptr, -					DBUS_TYPE_STRING, &peer_ptr, -					DBUS_TYPE_STRING, &name_ptr, +					DBUS_TYPE_STRING, local_addr, +					DBUS_TYPE_STRING, peer_addr, +					DBUS_TYPE_STRING, name,  					DBUS_TYPE_INVALID);  #else  	dbus_message_append_iter_init(message, &iter); @@ -270,6 +344,14 @@ failed:  	return;  } +void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) +{ +} + +void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) +{ +} +  gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)  {  	DBusWatch *watch = (DBusWatch *) data; diff --git a/hcid/hcid.h b/hcid/hcid.h index 4a433984..39b2cd09 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -123,15 +123,19 @@ void toggle_pairing(int enable);  #ifdef ENABLE_DBUS  gboolean hcid_dbus_init(void);  void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); +void hcid_dbus_inquiry_start(bdaddr_t *local); +void hcid_dbus_inquiry_complete(bdaddr_t *local);  void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi);  void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); +void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); +void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason);  #else -static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) -{ -} -static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) -{ -} +static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} +static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} +static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) {} +static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) {} +static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {} +static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {}  #endif  int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); diff --git a/hcid/security.c b/hcid/security.c index 7eec9e76..00204ace 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -482,6 +482,17 @@ reject:  	return;  } +static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) +{ +	evt_cmd_status *evt = ptr; + +	if (evt->status) +		return; + +	if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) +		hcid_dbus_inquiry_start(sba); +} +  static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr)  {  	evt_remote_name_req_complete *evt = ptr; @@ -516,6 +527,11 @@ static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr)  				evt->lmp_ver, btohs(evt->lmp_subver));  } +static inline void inquiry_complete(int dev, bdaddr_t *sba, void *ptr) +{ +	hcid_dbus_inquiry_complete(sba); +} +  static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr)  {  	uint8_t num = *(uint8_t *) ptr++; @@ -599,6 +615,29 @@ static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr  	write_features_info(sba, &dba, evt->features);  } +static inline void conn_complete(int dev, bdaddr_t *sba, void *ptr) +{ +	evt_conn_complete *evt = ptr; + +	if (evt->status) +		return; + +	hcid_dbus_conn_complete(sba, &evt->bdaddr); +} + +static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr) +{ +	evt_disconn_complete *evt = ptr; +	bdaddr_t dba; + +	if (evt->status) +		return; + +	bacpy(&dba, BDADDR_ANY); + +	hcid_dbus_disconn_complete(sba, &dba, evt->reason); +} +  static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data)  {  	unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; @@ -638,6 +677,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer  		return TRUE;  	switch (eh->evt) { +	case EVT_CMD_STATUS: +		cmd_status(dev, &di->bdaddr, ptr); +		break; +  	case EVT_REMOTE_NAME_REQ_COMPLETE:  		remote_name_information(dev, &di->bdaddr, ptr);  		break; @@ -650,6 +693,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer  		remote_features_information(dev, &di->bdaddr, ptr);  		break; +	case EVT_INQUIRY_COMPLETE: +		inquiry_complete(dev, &di->bdaddr, ptr); +		break; +  	case EVT_INQUIRY_RESULT:  		inquiry_result(dev, &di->bdaddr, eh->plen, ptr);  		break; @@ -661,6 +708,14 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer  	case EVT_EXTENDED_INQUIRY_RESULT:  		extended_inquiry_result(dev, &di->bdaddr, eh->plen, ptr);  		break; + +	case EVT_CONN_COMPLETE: +		conn_complete(dev, &di->bdaddr, ptr); +		break; + +	case EVT_DISCONN_COMPLETE: +		disconn_complete(dev, &di->bdaddr, ptr); +		break;  	}  	if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -709,6 +764,7 @@ void start_security_manager(int hdev)  	/* Set filter */  	hci_filter_clear(&flt);  	hci_filter_set_ptype(HCI_EVENT_PKT, &flt); +	hci_filter_set_event(EVT_CMD_STATUS, &flt);  	hci_filter_set_event(EVT_PIN_CODE_REQ, &flt);  	hci_filter_set_event(EVT_LINK_KEY_REQ, &flt);  	hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); @@ -716,9 +772,12 @@ void start_security_manager(int hdev)  	hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt);  	hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt);  	hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); +	hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt);  	hci_filter_set_event(EVT_INQUIRY_RESULT, &flt);  	hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt);  	hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); +	hci_filter_set_event(EVT_CONN_COMPLETE, &flt); +	hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt);  	if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {  		syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)",  						hdev, strerror(errno), errno); | 
