diff options
Diffstat (limited to 'hcid')
-rw-r--r-- | hcid/dbus.c | 109 | ||||
-rw-r--r-- | hcid/dbus.h | 4 |
2 files changed, 102 insertions, 11 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c index 59d45634..8cd0a28a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -225,6 +225,7 @@ static DBusMessage* handle_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); +static DBusMessage* handle_auth_req(DBusMessage *msg, void *data); static const struct service_data hci_services[] = { { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_SIGNATURE }, @@ -233,6 +234,7 @@ static const struct service_data hci_services[] = { { HCI_INQ, handle_inq_req, HCI_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 }, { NULL, NULL, NULL } }; @@ -1150,7 +1152,8 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } else dev_id = dbus_data->id; - if ((sock = hci_open_dev(dev_id)) < 0) { + sock = hci_open_dev(dev_id); + if (sock < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1163,9 +1166,9 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &max_period); - if ((length >= min_period) || (min_period >= max_period)) { - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); - goto failed; + if (length >= min_period || min_period >= max_period) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); + goto failed; } inq_param.num_rsp = 100; @@ -1182,14 +1185,14 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) inq_mode.mode = 1; //INQUIRY_WITH_RSSI; if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, - WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { + WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { syslog(LOG_ERR, "Can't set inquiry mode:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (hci_send_cmd(sock, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, - PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { + PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; @@ -1243,7 +1246,7 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) } failed: - if (sock > 0) + if (sock >= 0) close(sock); return reply; @@ -1512,7 +1515,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) dbus_message_iter_close_container(&iter, &array_iter); failed: - if (sk > 0) + if (sk >= 0) close(sk); if (cl) @@ -1521,6 +1524,90 @@ failed: return reply; } +static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) +{ + struct hci_request rq; + auth_requested_cp cp; + evt_cmd_status rp; + DBusMessageIter iter; + DBusMessage *reply = NULL; + char *str_bdaddr = NULL; + struct hci_dbus_data *dbus_data = data; + struct hci_conn_info_req *cr = NULL; + bdaddr_t bdaddr; + int dev_id = -1; + int sock = -1; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &str_bdaddr); + str2ba(str_bdaddr, &bdaddr); + + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + + if (dev_id < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); + goto failed; + } + + if (dbus_data->id != DEFAULT_DEVICE_PATH_ID && dbus_data->id != dev_id) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); + goto failed; + } + + sock = hci_open_dev(dev_id); + if (sock < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); + goto failed; + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + + if (ioctl(sock, HCIGETCONNINFO, (unsigned long) cr) < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + memset(&cp, 0, sizeof(cp)); + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; + + if (hci_send_req(sock, &rq, 25000) < 0) { + syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (rp.status) { + syslog(LOG_ERR, "Authentication command failed with status 0x%02X", rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); + goto failed; + } + +failed: + if (sock >= 0) + close(sock); + + if (cr) + free(cr); + + return reply; +} + /***************************************************************** * * Section reserved to Manager D-Bus message handlers @@ -1600,12 +1687,12 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) dbus_message_iter_close_container(&iter, &array_iter); failed: + if (sock >= 0) + close(sock); + if (dl) free(dl); - if (sock > 0) - close(sock); - return reply; } diff --git a/hcid/dbus.h b/hcid/dbus.h index 8ba4af91..5cbf74ae 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -129,6 +129,7 @@ #define HCI_ROLE_SWITCH "RoleSwitch" #define HCI_REMOTE_NAME "RemoteName" #define HCI_CONNECTIONS "Connections" +#define HCI_AUTHENTICATE "Authenticate" #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ @@ -173,6 +174,9 @@ DBUS_STRUCT_END_CHAR_AS_STRING\ __END_SIG__ +#define HCI_AUTHENTICATE_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ + __END_SIG__ + /* BLUEZ_DBUS_ERROR * EFailed error messages signature is : su |