diff options
Diffstat (limited to 'network/manager.c')
-rw-r--r-- | network/manager.c | 786 |
1 files changed, 75 insertions, 711 deletions
diff --git a/network/manager.c b/network/manager.c index dd23b58d..27573101 100644 --- a/network/manager.c +++ b/network/manager.c @@ -45,8 +45,8 @@ #include "textfile.h" #include "glib-helper.h" -#define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" - +#include "../hcid/adapter.h" +#include "../hcid/device.h" #include "error.h" #include "bridge.h" #include "manager.h" @@ -54,578 +54,10 @@ #define MAX_NAME_SIZE 256 -struct pending_reply { - DBusConnection *conn; - DBusMessage *msg; - bdaddr_t src; /* Source address */ - bdaddr_t dst; /* Destination address */ - char *addr; /* Destination address */ - char *path; /* D-Bus object path */ - char *adapter_path; /* Default adapter path */ - uint16_t id; /* Role */ -}; - static struct network_conf *conf = NULL;/* Network service configuration */ -static GSList *server_paths = NULL; /* Network registered servers paths */ -static GSList *connection_paths = NULL; /* Network registered connections paths */ -static int default_index = -1; /* Network default connection path index */ -static int net_uid = 0; /* Network objects identifier */ static DBusConnection *connection = NULL; -static void pending_reply_free(struct pending_reply *pr) -{ - if (pr->addr) - g_free(pr->addr); - if (pr->path) - g_free(pr->path); - if (pr->adapter_path) - g_free(pr->adapter_path); - if (pr->msg) - dbus_message_unref(pr->msg); - if (pr->conn) - dbus_connection_unref(pr->conn); -} - -static inline DBusMessage *does_not_exist(DBusMessage *msg) -{ - return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", - "No such connection"); -} - -static inline DBusMessage *already_exists(DBusMessage *msg) -{ - return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", - "Connection already exists"); -} - -static inline DBusMessage *not_supported(DBusMessage *msg) -{ - return g_dbus_create_error(msg, ERROR_INTERFACE ".NotSupported", - "Not supported"); -} - -static inline DBusMessage *connection_is_busy(DBusMessage *msg) -{ - return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", - "Connection is Busy"); -} - -static inline DBusMessage *adapter_not_available(DBusMessage *msg) -{ - return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", - "Adapter not available"); -} - -static void create_path(DBusConnection *conn, DBusMessage *msg, - const char *path, const char *sname) -{ - /* emit signal when it is a new path */ - if (sname) { - g_dbus_emit_signal(conn, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - sname, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - } - - g_dbus_send_reply(conn, msg, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); -} - -static DBusMessage *list_paths(DBusConnection *conn, DBusMessage *msg, - GSList *list) -{ - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter array_iter; - - reply = dbus_message_new_method_return(msg); - if (reply == NULL) - return NULL; - - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_TYPE_STRING_AS_STRING, &array_iter); - - for (; list; list = list->next) { - dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, - &list->data); - } - - dbus_message_iter_close_container(&iter, &array_iter); - - return reply; -} - -static const char *last_connection_used(DBusConnection *conn) -{ - const char *path = NULL; - GSList *l; - int i; - - for (i = g_slist_length (connection_paths) -1; i > -1; i--) { - path = g_slist_nth_data (connection_paths, i); - if (connection_is_connected(path)) - break; - } - - /* No connection connected fallback to last connection */ - if (i == -1) { - l = g_slist_last(connection_paths); - path = l->data; - } - - return path; -} - -static DBusMessage *remove_path(DBusConnection *conn, - DBusMessage *msg, GSList **list, - const char *sname) -{ - const char *path; - GSList *l; - - if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID) == FALSE) - return NULL; - - l = g_slist_find_custom(*list, path, (GCompareFunc) strcmp); - if (!l) - return does_not_exist(msg); - - /* Remove references from the storage */ - if (*list == connection_paths) { - if (connection_has_pending(path)) - return connection_is_busy(msg); - - connection_remove_stored(path); - /* Reset default connection */ - if (l == g_slist_nth(*list, default_index)) { - const char *dpath; - - dpath = last_connection_used(conn); - connection_store(dpath, TRUE); - } - } - - g_free(l->data); - *list = g_slist_remove(*list, l->data); - - g_dbus_emit_signal(conn, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - sname, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - g_dbus_unregister_interface(conn, path, NETWORK_CONNECTION_INTERFACE); - - return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); -} - -static void records_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct pending_reply *pr = data; - int len; - sdp_data_t *d; - sdp_record_t *rec = NULL; - char name[MAX_NAME_SIZE], *desc = NULL; - - if (err < 0) { - error_connection_attempt_failed(pr->conn, pr->msg, -err); - goto fail; - } - - if (!recs || !recs->data) { - error_not_supported(pr->conn, pr->msg); - error("Invalid PAN service record"); - goto fail; - } - - rec = recs->data; - - /* Concat remote name and service name */ - memset(name, 0, MAX_NAME_SIZE); - if (read_remote_name(&pr->src, &pr->dst, name, MAX_NAME_SIZE) < 0) - len = 0; - else - len = strlen(name); - - d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); - if (d) { - snprintf(name + len, MAX_NAME_SIZE - len, - len ? " (%.*s)" : "%.*s", d->unitSize, d->val.str); - } - - /* Extract service description from record */ - d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); - if (d) { - desc = g_new0(char, d->unitSize); - snprintf(desc, d->unitSize, "%.*s", - d->unitSize, d->val.str); - } - - sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); - - if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name, - desc) < 0) { - error_failed(pr->conn, pr->msg, "D-Bus path registration failed"); - goto fail; - } - - connection_store(pr->path, FALSE); - connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); - - create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); - -fail: - g_free(desc); - pending_reply_free(pr); -} - -static DBusMessage *list_servers(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - return list_paths(conn, msg, server_paths); -} - -static DBusMessage *find_server(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *pattern; - const char *path; - GSList *list; - - if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INVALID) == FALSE) - return NULL; - - for (list = server_paths; list; list = list->next) { - path = (const char *) list->data; - if (server_find_data(path, pattern) == 0) - break; - } - - if (list == NULL) - return does_not_exist(msg); - - return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); -} - -static DBusMessage *list_connections(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - return list_paths(conn, msg, connection_paths); -} - -static GSList *find_connection_pattern(DBusConnection *conn, - const char *pattern) -{ - const char *path; - GSList *list; - - if (pattern == NULL) - return NULL; - - for (list = connection_paths; list; list = list->next) { - path = (const char *) list->data; - if (connection_find_data(path, pattern) == 0) - break; - } - - return list; -} - -static DBusMessage *find_connection(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *pattern; - const char *path; - GSList *list; - - if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INVALID) == FALSE) - return NULL; - - list = find_connection_pattern(conn, pattern); - if (list == NULL) - return does_not_exist(msg); - - path = list->data; - - return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); -} - -static DBusMessage *create_connection(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct pending_reply *pr; - const char *addr; - const char *str; - bdaddr_t src; - uint16_t id; - int dev_id, err; - char key[32]; - GSList *l; - uuid_t uuid; - - if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, - DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID) == FALSE) - return NULL; - - id = bnep_service_id(str); - if (id != BNEP_SVC_GN && id != BNEP_SVC_NAP && id != BNEP_SVC_PANU) - return not_supported(msg); - - snprintf(key, 32, "%s#%s", addr, bnep_name(id)); - - /* Checks if the connection was already been made */ - for (l = connection_paths; l; l = l->next) { - if (connection_find_data(l->data, key) == 0) - return already_exists(msg); - } - - bacpy(&src, BDADDR_ANY); - dev_id = hci_get_route(&src); - if (dev_id < 0 || hci_devba(dev_id, &src) < 0) - return adapter_not_available(msg); - - pr = g_new0(struct pending_reply, 1); - - /* FIXME just to maintain compatibility */ - pr->adapter_path = g_strdup_printf("/org/bluez/hci%d", dev_id); - if (!pr->adapter_path) { - pending_reply_free (pr); - return adapter_not_available(msg); - } - - pr->conn = dbus_connection_ref(conn); - pr->msg = dbus_message_ref(msg); - bacpy(&pr->src, &src); - str2ba(addr, &pr->dst); - pr->addr = g_strdup(addr); - pr->id = id; - pr->path = g_new0(char, MAX_PATH_LENGTH); - snprintf(pr->path, MAX_PATH_LENGTH, - NETWORK_PATH "/connection%d", net_uid++); - - sdp_uuid16_create(&uuid, pr->id); - err = bt_search_service(&pr->src, &pr->dst, &uuid, records_cb, pr, - NULL); - if (err < 0) { - pending_reply_free(pr); - return not_supported(msg); - } - - return NULL; -} - -static DBusMessage *remove_connection(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); -} - -static DBusMessage *last_connection(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path; - - if (connection_paths == NULL || - g_slist_length(connection_paths) == 0) - return does_not_exist(msg); - - path = last_connection_used(conn); - - return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); -} - -static DBusMessage *default_connection(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path; - - if (connection_paths == NULL || - g_slist_length (connection_paths) == 0) - return does_not_exist(msg); - - path = g_slist_nth_data (connection_paths, default_index); - - if (path == NULL) { - path = last_connection_used(conn); - connection_store(path, TRUE); - } - - return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); -} - -static DBusMessage *change_default_connection(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path; - const char *pattern; - GSList *list; - - if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INVALID) == FALSE) - return NULL; - - if (connection_paths == NULL || - g_slist_length(connection_paths) == 0) - return does_not_exist(msg); - - list = g_slist_find_custom(connection_paths, pattern, - (GCompareFunc) strcmp); - - /* Find object path via pattern */ - if (list == NULL) { - list = find_connection_pattern(conn, pattern); - if (list == NULL) - return does_not_exist(msg); - - path = list->data; - } else - path = list->data; - - default_index = g_slist_position(connection_paths, list); - connection_store(path, TRUE); - - g_dbus_emit_signal(connection, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - "DefaultConnectionChanged", - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); -} - -static void manager_unregister(void *data) -{ - info("Unregistered manager path"); - - if (server_paths) { - g_slist_foreach(server_paths, (GFunc) g_free, NULL); - g_slist_free(server_paths); - server_paths = NULL; - } - - if (connection_paths) { - g_slist_foreach(connection_paths, (GFunc) g_free, NULL); - g_slist_free(connection_paths); - connection_paths = NULL; - } - - bnep_kill_all_connections(); -} - -static void parse_stored_connection(char *key, char *value, void *data) -{ - bdaddr_t dst, *src = data; - char path[MAX_PATH_LENGTH]; - char addr[18]; - const char *ptr; - char *name; - int len, id; - - /* Format: XX:XX:XX:XX:XX:XX#{NAP, GN} name:description */ - - /* Parsing the key: address#role */ - ptr = strchr(key, '#'); - - /* Empty address or invalid len */ - if (!ptr || ((ptr - key) != 17)) - return; - - memset(addr, 0, 18); - strncpy(addr, key, 17); - str2ba(addr, &dst); - - /* Empty role */ - if (++ptr == NULL) - return; - - if (strcasecmp("nap", ptr) == 0) - id = BNEP_SVC_NAP; - else if (strcasecmp("gn", ptr) == 0) - id = BNEP_SVC_GN; - else if (strcasecmp("panu", ptr) == 0) - id = BNEP_SVC_PANU; - else - return; - - snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH "/connection%d", net_uid++); - - /* Parsing the value: name and description */ - ptr = strchr(value, ':'); - - /* Empty name */ - if (!ptr) - return; - - len = ptr-value; - name = g_malloc0(len + 1); - strncpy(name, value, len); - - /* Empty description */ - if (++ptr == NULL) { - g_free(name); - return; - } - - if (connection_register(path, src, &dst, id, name, ptr) == 0) { - char *rpath = g_strdup(path); - connection_paths = g_slist_append(connection_paths, rpath); - } - - g_free(name); -} - -static void register_connections_stored(const char *adapter) -{ - char filename[PATH_MAX + 1]; - char *pattern; - struct stat st; - GSList *list; - bdaddr_t src; - bdaddr_t default_src; - int dev_id; - - create_name(filename, PATH_MAX, STORAGEDIR, adapter, "network"); - - str2ba(adapter, &src); - - if (stat(filename, &st) < 0) - return; - - if (!(st.st_mode & __S_IFREG)) - return; - - textfile_foreach(filename, parse_stored_connection, &src); - - /* Check default connection for current default adapter */ - bacpy(&default_src, BDADDR_ANY); - dev_id = hci_get_route(&default_src); - if (dev_id < 0 || hci_devba(dev_id, &default_src) < 0) - return; - - if (bacmp(&default_src, &src) != 0) - return; - - pattern = textfile_get(filename, "default"); - if (!pattern) - return; - - list = find_connection_pattern(connection, pattern); - if (!list) - return; - default_index = g_slist_position(connection_paths, list); -} - static void register_server(uint16_t id) { char path[MAX_PATH_LENGTH]; @@ -637,10 +69,6 @@ static void register_server(uint16_t id) snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH "/%s", bnep_name(id)); - if (g_slist_find_custom(server_paths, path, - (GCompareFunc) strcmp)) - return; - bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(&src); if (dev_id < 0 || hci_devba(dev_id, &src)) @@ -650,133 +78,90 @@ static void register_server(uint16_t id) return; server_store(path); - - server_paths = g_slist_append(server_paths, g_strdup(path)); } -static void register_servers_stored(const char *adapter, const char *profile) +static int network_probe(struct btd_device *device, uint16_t id) { - char filename[PATH_MAX + 1]; - char path[MAX_PATH_LENGTH]; - uint16_t id; - struct stat s; - bdaddr_t src; + struct adapter *adapter = device_get_adapter(device); + const gchar *path = device_get_path(device); + const char *source, *destination; + bdaddr_t src, dst; - if (strcmp(profile, "nap") == 0) - id = BNEP_SVC_NAP; - else if (strcmp(profile, "gn") == 0) - id = BNEP_SVC_GN; - else - id = BNEP_SVC_PANU; + DBG("path %s", path); - create_name(filename, PATH_MAX, STORAGEDIR, adapter, profile); + source = adapter->address; + destination = device_get_address(device); - str2ba(adapter, &src); + str2ba(source, &src); + str2ba(destination, &dst); - if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH "/%s", profile); - if (server_register_from_file(path, &src, id, filename) == 0) { - server_paths = g_slist_append(server_paths, - g_strdup(path)); - } - } + return connection_register(path, &src, &dst, id); } -static void register_stored(void) +static int panu_probe(struct btd_device *device, GSList *records) { - char dirname[PATH_MAX + 1]; - struct dirent *de; - DIR *dir; - - snprintf(dirname, PATH_MAX, "%s", STORAGEDIR); + return network_probe(device, BNEP_SVC_PANU); +} - dir = opendir(dirname); - if (!dir) - return; +static int gn_probe(struct btd_device *device, GSList *records) +{ + return network_probe(device, BNEP_SVC_GN); +} - while ((de = readdir(dir)) != NULL) { - if (!isdigit(de->d_name[0])) - continue; +static int nap_probe(struct btd_device *device, GSList *records) +{ + return network_probe(device, BNEP_SVC_NAP); +} - /* Connection objects */ - if (conf->connection_enabled) - register_connections_stored(de->d_name); +static void network_remove(struct btd_device *device, uint16_t id) +{ + const gchar *path = device_get_path(device); - /* Server objects */ - if (conf->server_enabled) { - /* NAP objects */ - register_servers_stored(de->d_name, "nap"); + DBG("path %s", path); - /* GN objects */ - register_servers_stored(de->d_name, "gn"); + connection_unregister(path, id); +} - /* PANU objects */ - register_servers_stored(de->d_name, "panu"); - } - } +static void panu_remove(struct btd_device *device) +{ + network_remove(device, BNEP_SVC_PANU); +} - closedir(dir); +static void gn_remove(struct btd_device *device) +{ + network_remove(device, BNEP_SVC_GN); } -static GDBusMethodTable connection_methods[] = { - { "ListConnections", "", "as", list_connections }, - { "FindConnection", "s", "s", find_connection }, - { "CreateConnection", "ss", "s", create_connection, - G_DBUS_METHOD_FLAG_ASYNC }, - { "RemoveConnection", "s", "", remove_connection }, - { "LastConnection", "", "s", last_connection }, - { "DefaultConnection", "", "s", default_connection }, - { "ChangeDefaultConnection", "s", "s", change_default_connection }, - { } -}; +static void nap_remove(struct btd_device *device) +{ + network_remove(device, BNEP_SVC_NAP); +} -static GDBusSignalTable connection_signals[] = { - { "ConnectionCreated", "s" }, - { "ConnectionRemoved", "s" }, - { "DefaultConnectionChanged", "s" }, - { } +static struct btd_device_driver network_panu_driver = { + .name = "network-panu", + .uuids = BTD_UUIDS(PANU_UUID), + .probe = panu_probe, + .remove = panu_remove, }; -static GDBusMethodTable server_methods[] = { - { "ListServers", "", "as", list_servers }, - { "FindServer", "s", "s", find_server }, - { } +static struct btd_device_driver network_gn_driver = { + .name = "network-gn", + .uuids = BTD_UUIDS(GN_UUID), + .probe = gn_probe, + .remove = gn_remove, }; -static GDBusMethodTable manager_methods[] = { - { "ListServers", "", "as", list_servers }, - { "FindServer", "s", "s", find_server }, - { "ListConnections", "", "as", list_connections }, - { "FindConnection", "s", "s", find_connection }, - { "CreateConnection", "ss", "s", create_connection, - G_DBUS_METHOD_FLAG_ASYNC }, - { "RemoveConnection", "s", "", remove_connection }, - { "LastConnection", "", "s", last_connection }, - { "DefaultConnection", "", "s", default_connection }, - { "ChangeDefaultConnection", "s", "s", change_default_connection }, - { } +static struct btd_device_driver network_nap_driver = { + .name = "network-nap", + .uuids = BTD_UUIDS(NAP_UUID), + .probe = nap_probe, + .remove = nap_remove, }; int network_manager_init(DBusConnection *conn, struct network_conf *service_conf) { - GDBusMethodTable *methods = NULL; - GDBusSignalTable *signals = NULL; - conf = service_conf; - if (conf->server_enabled && conf->connection_enabled) { - methods = manager_methods; - signals = connection_signals; - } else if (conf->connection_enabled) { - methods = connection_methods; - signals = connection_signals; - } else if (conf->server_enabled) - methods = server_methods; - else { - error ("All interfaces were disabled"); - return -1; - } - if (bnep_init(conf->panu_script, conf->gn_script, conf->nap_script)) { error("Can't init bnep module"); return -1; @@ -788,41 +173,29 @@ int network_manager_init(DBusConnection *conn, struct network_conf *service_conf * (setup connection request) contains the destination service * field that defines which service the source is connecting to. */ - if (conf->server_enabled) { - if (bridge_init(conf->gn_iface, conf->nap_iface) < 0) { - error("Can't init bridge module"); - return -1; - } - - if (server_init(conn, conf->iface_prefix, conf->security) < 0) - return -1; - } - - if (conf->connection_enabled) { - if (connection_init(conn, conf->iface_prefix) < 0) - return -1; - } - - if (g_dbus_register_interface(conn, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - methods, signals, NULL, - NULL, manager_unregister) == FALSE) { - error("Failed to register %s interface to %s", - NETWORK_MANAGER_INTERFACE, NETWORK_PATH); + if (bridge_init(conf->gn_iface, conf->nap_iface) < 0) { + error("Can't init bridge module"); return -1; } - connection = dbus_connection_ref(conn); - - info("Registered manager path:%s", NETWORK_PATH); - - register_stored(); + if (server_init(conn, conf->iface_prefix, conf->security) < 0) + return -1; /* Register PANU, GN and NAP servers if they don't exist */ + /* FIXME: server should be registered as adapter driver */ register_server(BNEP_SVC_PANU); register_server(BNEP_SVC_GN); register_server(BNEP_SVC_NAP); + if (connection_init(conn, conf->iface_prefix) < 0) + return -1; + + btd_register_device_driver(&network_panu_driver); + btd_register_device_driver(&network_gn_driver); + btd_register_device_driver(&network_nap_driver); + + connection = dbus_connection_ref(conn); + return 0; } @@ -831,11 +204,12 @@ void network_manager_exit(void) if (conf->server_enabled) server_exit(); - if (conf->connection_enabled) + if (conf->connection_enabled) { + btd_unregister_device_driver(&network_panu_driver); + btd_unregister_device_driver(&network_gn_driver); + btd_unregister_device_driver(&network_nap_driver); connection_exit(); - - g_dbus_unregister_interface(connection, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE); + } dbus_connection_unref(connection); connection = NULL; @@ -843,13 +217,3 @@ void network_manager_exit(void) bnep_cleanup(); bridge_cleanup(); } - -static inline int create_filename(char *buf, size_t size, - bdaddr_t *bdaddr, const char *name) -{ - char addr[18]; - - ba2str(bdaddr, addr); - - return create_name(buf, size, STORAGEDIR, addr, name); -} |