From: Jose Antonio Santos Cadenas <santoscadenas@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: Jose Antonio Santos Cadenas <santoscadenas@gmail.com>
Subject: [PATCH 03/32] Add functions to resiger health instances in SDP
Date: Fri, 4 Jun 2010 10:29:56 +0200 [thread overview]
Message-ID: <1275640225-4186-4-git-send-email-santoscadenas@gmail.com> (raw)
In-Reply-To: <1275640225-4186-3-git-send-email-santoscadenas@gmail.com>
---
health/hdp.c | 5 +-
health/hdp_util.c | 393 +++++++++++++++++++++++++++++++++++++++++++++++++++++
health/hdp_util.h | 1 +
3 files changed, 398 insertions(+), 1 deletions(-)
diff --git a/health/hdp.c b/health/hdp.c
index 2dec069..454483d 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -101,7 +101,10 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
/* TODO: Create mcap instance */
- /* TODO: Create SDP record if needed. */
+ if (!hdp_register_sdp_record(hdpi)) {
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+ "Session can't be registered");
+ }
return g_dbus_create_error(msg,
ERROR_INTERFACE ".HealthError",
diff --git a/health/hdp_util.c b/health/hdp_util.c
index a215d5a..cc5dc2e 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -24,8 +24,14 @@
*/
#include <gdbus.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
#include "log.h"
+#include "sdpd.h"
+
#include "hdp_types.h"
+#include "hdp_util.h"
+#include "mcap.h"
typedef gboolean (*parse_item_f)(DBusMessageIter *iter, GError **err,
gpointer user_data);
@@ -445,3 +451,390 @@ error:
free_config(config);
return NULL;
}
+
+static gboolean is_session_role(struct hdp_instance *hdps, HdpRole role)
+{
+ GSList *l;
+ struct hdp_supp_fts *fts;
+
+ if (!hdps->config)
+ return FALSE;
+ for (l = hdps->config->supp_fts; l; l = l->next) {
+ fts = l->data;
+ if (fts->role == role)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean register_service_protocols(struct hdp_instance *hdps,
+ sdp_record_t *sdp_record)
+{
+ gboolean error = FALSE;
+ uuid_t l2cap_uuid, mcap_c_uuid;
+ sdp_list_t *l2cap_list = NULL,
+ *proto_list = NULL,
+ *mcap_list = NULL,
+ *access_proto_list = NULL;
+ sdp_data_t *psm = NULL,
+ *mcap_ver = NULL;
+ uint16_t version = MCAP_VERSION;
+
+ // set l2cap information
+ sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+ l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
+ if (!l2cap_list) {
+ error = TRUE;
+ goto end;
+ }
+ psm = sdp_data_alloc(SDP_UINT16, &hdps->ccpsm);
+ if (!psm) {
+ error = TRUE;
+ goto end;
+ }
+ if (!sdp_list_append(l2cap_list, psm)) {
+ error = TRUE;
+ goto end;
+ }
+ proto_list = sdp_list_append(NULL, l2cap_list);
+ if (!proto_list) {
+ error = TRUE;
+ goto end;
+ }
+
+ // set mcap information
+ sdp_uuid16_create(&mcap_c_uuid, MCAP_CTRL_UUID);
+ mcap_list = sdp_list_append(NULL, &mcap_c_uuid);
+ if (!mcap_list) {
+ error = TRUE;
+ goto end;
+ }
+ mcap_ver = sdp_data_alloc(SDP_UINT16, &version);
+ if (!mcap_ver) {
+ error = TRUE;
+ goto end;
+ }
+ if (!sdp_list_append( mcap_list, mcap_ver)) {
+ error = TRUE;
+ goto end;
+ }
+ if (!sdp_list_append( proto_list, mcap_list)) {
+ error = TRUE;
+ goto end;
+ }
+
+ // attach protocol information to service record
+ access_proto_list = sdp_list_append(NULL, proto_list);
+ if (!access_proto_list) {
+ error = TRUE;
+ goto end;
+ }
+ if (sdp_set_access_protos(sdp_record, access_proto_list) < 0)
+ error = TRUE;
+end:
+ if (l2cap_list)
+ sdp_list_free(l2cap_list, NULL);
+ if (mcap_list)
+ sdp_list_free(mcap_list, NULL);
+ if (proto_list)
+ sdp_list_free(proto_list, NULL);
+ if (access_proto_list)
+ sdp_list_free(access_proto_list, NULL);
+ if (psm)
+ sdp_data_free(psm);
+ if (mcap_ver)
+ sdp_data_free(mcap_ver);
+ return !error;
+}
+
+static gboolean register_service_profiles(sdp_record_t *sdp_record)
+{
+ gboolean error = FALSE;
+ sdp_list_t *profile_list = NULL;
+ sdp_profile_desc_t hdp_profile;
+
+ // set hdp information
+ sdp_uuid16_create( &hdp_profile.uuid, MDP_SVCLASS_ID);
+ hdp_profile.version = HDP_VERSION;
+ profile_list = sdp_list_append(NULL, &hdp_profile);
+ if (!profile_list)
+ return FALSE;
+ // set profile descriptor list
+ if (sdp_set_profile_descs(sdp_record, profile_list) < 0)
+ error = TRUE;
+
+ sdp_list_free(profile_list, NULL);
+ return !error;
+}
+
+static gboolean register_service_aditional_protocols(struct hdp_instance *hdps,
+ sdp_record_t *sdp_record)
+{
+ gboolean error = FALSE;
+ uuid_t l2cap_uuid, mcap_d_uuid;
+ sdp_list_t *l2cap_list = NULL,
+ *proto_list = NULL,
+ *mcap_list = NULL,
+ *access_proto_list = NULL;
+ sdp_data_t *psm = NULL;
+
+ // set l2cap information
+ sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+ l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
+ if (!l2cap_list) {
+ error = TRUE;
+ goto end;
+ }
+ psm = sdp_data_alloc(SDP_UINT16, &hdps->dcpsm);
+ if (!psm) {
+ error = TRUE;
+ goto end;
+ }
+ if (!sdp_list_append(l2cap_list, psm)) {
+ error = TRUE;
+ goto end;
+ }
+ proto_list = sdp_list_append(NULL, l2cap_list);
+ if (!proto_list) {
+ error = TRUE;
+ goto end;
+ }
+
+ // set mcap information
+ sdp_uuid16_create(&mcap_d_uuid, MCAP_DATA_UUID);
+ mcap_list = sdp_list_append(NULL, &mcap_d_uuid);
+ if (!mcap_list) {
+ error = TRUE;
+ goto end;
+ }
+ if (!sdp_list_append( proto_list, mcap_list)) {
+ error = TRUE;
+ goto end;
+ }
+
+ // attach protocol information to service record
+ access_proto_list = sdp_list_append(NULL, proto_list);
+ if (!access_proto_list) {
+ error = TRUE;
+ goto end;
+ }
+ if (sdp_set_add_access_protos(sdp_record, access_proto_list) < 0)
+ error = TRUE;
+end:
+ if (l2cap_list)
+ sdp_list_free(l2cap_list, NULL);
+ if (mcap_list)
+ sdp_list_free(mcap_list, NULL);
+ if (proto_list)
+ sdp_list_free(proto_list, NULL);
+ if (access_proto_list)
+ sdp_list_free(access_proto_list, NULL);
+ if (psm)
+ sdp_data_free(psm);
+ return !error;
+}
+
+static sdp_list_t *feature_to_sdplist(struct hdp_supp_fts *fts,
+ struct hdp_feature *f)
+{
+ sdp_data_t *mdepid,
+ *dtype = NULL,
+ *role = NULL,
+ *desc = NULL;
+ sdp_list_t *f_list = NULL;
+
+ mdepid = sdp_data_alloc(SDP_UINT8, &fts->mdepid);
+ if (!mdepid)
+ return NULL;
+ dtype = sdp_data_alloc(SDP_UINT16, &f->dtype);
+ if (!dtype)
+ goto error;
+ role = sdp_data_alloc(SDP_UINT8, &fts->role);
+ if (!role)
+ goto error;
+ if (f->dscr) {
+ desc = sdp_data_alloc(SDP_TEXT_STR8, f->dscr);
+ if (!desc)
+ goto error;
+ }
+ f_list = sdp_list_append(NULL, mdepid);
+ if (!f_list)
+ goto error;
+ if (!sdp_list_append(f_list, dtype))
+ goto error;
+ if (!sdp_list_append(f_list, role))
+ goto error;
+ if (desc)
+ if (!sdp_list_append(f_list, desc))
+ goto error;
+ return f_list;
+error:
+ if (f_list)
+ sdp_list_free(f_list, NULL);
+ if (mdepid)
+ sdp_data_free(mdepid);
+ if (dtype)
+ sdp_data_free(dtype);
+ if (role)
+ sdp_data_free(role);
+ if (desc)
+ sdp_data_free(desc);
+ return NULL;
+}
+
+static gboolean register_features(struct hdp_supp_fts *fts,
+ sdp_list_t **sup_features)
+{
+ GSList *l;
+ sdp_list_t *hdp_feature = NULL;
+
+ for (l = fts->features; l; l = l->next){
+ hdp_feature = feature_to_sdplist(fts, l->data);
+ if (!hdp_feature)
+ goto error;
+
+ if (!*sup_features) {
+ *sup_features = sdp_list_append(NULL, hdp_feature);
+ if (!*sup_features)
+ goto error;
+ } else if (!sdp_list_append(*sup_features, hdp_feature))
+ goto error;
+ hdp_feature = NULL;
+ }
+ return TRUE;
+error:
+ if (hdp_feature)
+ sdp_list_free(hdp_feature, (sdp_free_func_t)sdp_data_free);
+ return FALSE;
+}
+
+static void free_hdp_list(void *list)
+{
+ sdp_list_t *hdp_list = list;
+
+ sdp_list_free(hdp_list, (sdp_free_func_t)sdp_data_free);
+}
+
+static gboolean register_service_sup_features(struct hdp_config *config,
+ sdp_record_t *sdp_record)
+{
+ GSList *l;
+ sdp_list_t *sup_features = NULL;
+ for (l = config->supp_fts; l; l = l->next) {
+ if (!register_features(l->data, &sup_features))
+ return FALSE;
+ }
+ if (sdp_set_supp_feat(sdp_record, sup_features) < 0) {
+ sdp_list_free(sup_features, free_hdp_list);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean register_data_exchange_spec(struct hdp_config *config,
+ sdp_record_t *record)
+{
+ sdp_data_t *spec;
+
+ spec = sdp_data_alloc(SDP_UINT8, &config->data_spec);
+ if (!spec)
+ return FALSE;
+ if (sdp_attr_add(record, SDP_ATTR_DATA_EXCHANGE_SPEC, spec) < 0) {
+ sdp_data_free(spec);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean register_mcap_features(sdp_record_t *sdp_record)
+{
+ sdp_data_t *mcap_proc;
+ uint8_t mcap_sup_proc = MCAP_SUP_PROC;
+
+ mcap_proc = sdp_data_alloc(SDP_UINT8, &mcap_sup_proc);
+ if (!mcap_proc)
+ return FALSE;
+ if (sdp_attr_add(sdp_record, SDP_ATTR_MCAP_SUPPORTED_PROCEDURES,
+ mcap_proc) < 0) {
+ sdp_data_free(mcap_proc);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean set_sdp_services_uuid(sdp_record_t *record, HdpRole role)
+{
+ uuid_t svc_uuid_source, svc_uuid_sink;
+ sdp_list_t *svc_list = NULL;
+
+ sdp_uuid16_create(&svc_uuid_sink, MDP_SINK_SVCLASS_ID);
+ sdp_uuid16_create(&svc_uuid_source, MDP_SOURCE_SVCLASS_ID);
+
+ sdp_get_service_classes(record, &svc_list);
+
+ if (role == HDP_SOURCE) {
+ if (sdp_list_find(svc_list, &svc_uuid_source, sdp_uuid_cmp) == NULL)
+ svc_list = sdp_list_append(svc_list, &svc_uuid_source);
+ }
+ else if (role == HDP_SINK) {
+ if (sdp_list_find(svc_list, &svc_uuid_sink, sdp_uuid_cmp) == NULL)
+ svc_list = sdp_list_append(svc_list, &svc_uuid_sink);
+ }
+
+ if (sdp_set_service_classes(record, svc_list) < 0) {
+ sdp_list_free(svc_list, NULL);
+ return FALSE;
+ }
+
+ sdp_list_free(svc_list, NULL);
+ return TRUE;
+}
+
+gboolean hdp_register_sdp_record(struct hdp_instance *hdps)
+{
+ sdp_record_t *sdp_record;
+ struct hdp_config *config;
+ bdaddr_t addr;
+
+ if (!hdps->config) /* Record is not needed */
+ return TRUE;
+ config = hdps->config;
+
+ sdp_record = sdp_record_alloc();
+ if (!sdp_record)
+ return FALSE;
+ sdp_record->handle = 0xffffffff; /* Set automatically */
+
+ if (is_session_role(hdps, HDP_SINK))
+ set_sdp_services_uuid(sdp_record, HDP_SINK);
+ if (is_session_role(hdps, HDP_SOURCE))
+ set_sdp_services_uuid(sdp_record, HDP_SOURCE);
+
+ if (!register_service_protocols(hdps, sdp_record))
+ goto error;
+ if (!register_service_profiles(sdp_record))
+ goto error;
+ if (!register_service_aditional_protocols(hdps, sdp_record))
+ goto error;
+ sdp_set_info_attr(sdp_record, config->svc_name, config->svc_prov,
+ config->svc_dsc);
+ if (!register_service_sup_features(config, sdp_record))
+ goto error;
+ if (!register_data_exchange_spec(config, sdp_record))
+ goto error;
+
+ register_mcap_features(sdp_record);
+
+ adapter_get_address(hdps->adapter->btd_adapter, &addr);
+
+ if (add_record_to_server(&addr, sdp_record) < 0)
+ goto error;
+ hdps->sdp_handler = sdp_record->handle;
+ return TRUE;
+error:
+ if (sdp_record)
+ sdp_record_free(sdp_record);
+ return FALSE;
+}
diff --git a/health/hdp_util.h b/health/hdp_util.h
index f09e9a6..fb114c7 100644
--- a/health/hdp_util.h
+++ b/health/hdp_util.h
@@ -30,5 +30,6 @@
#include "hdp_types.h"
struct hdp_config *hdp_get_config(DBusMessageIter *iter, GError **err);
+gboolean hdp_register_sdp_record(struct hdp_instance *hdps);
#endif /* __HDP_UTIL_H__ */
--
1.6.3.3
next prev parent reply other threads:[~2010-06-04 8:29 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-04 8:29 [PATCH 00/32] Health Device Prifile (HDP) -- updated Jose Antonio Santos Cadenas
2010-06-04 8:29 ` [PATCH 01/32] Add Health api description Jose Antonio Santos Cadenas
2010-06-04 8:29 ` [PATCH 02/32] Initial support for HDP Jose Antonio Santos Cadenas
2010-06-04 8:29 ` Jose Antonio Santos Cadenas [this message]
2010-06-04 8:29 ` [PATCH 04/32] Initial support for hdp_device_drivers Jose Antonio Santos Cadenas
2010-06-04 8:29 ` [PATCH 05/32] Register healt_driver interfaces in d-bus Jose Antonio Santos Cadenas
2010-06-04 8:29 ` [PATCH 06/32] Add delete instance petition Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 07/32] Add watcher to control client disconections to delete hdp instance Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 08/32] Work in getting remote SDP records Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 09/32] Adds functions to get remote suported features from its SDP record Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 10/32] Insert end_point in array returned by get_health_instances Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 11/32] Initial support for connecting instances Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 12/32] Complete the response dictionary in GetHealthInstances response Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 13/32] Implement connection of health instances Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 14/32] Manage mcap instances Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 15/32] Implement connect MCL callback in health instances connection Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 16/32] Register Health link int the bus when MCL is connected Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 17/32] Analize remote record looking for psm Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 18/32] Unify the creation of health links Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 19/32] Remove hdp_device pointer from health link struct Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 20/32] Release health link resources Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 21/32] Manage mcap disconnections and reconnections Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 22/32] Initial work for disconnecting health links Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 23/32] Avoid multiple links with the same device Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 24/32] Disconnect health link petition Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 25/32] Create new structure to manage data channels in HDP Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 26/32] Implement connect data channel callback Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 27/32] Change function name when retreiving remote SDP records Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 28/32] Changed HEALTH_MANAGER_INTERFACE to HEALTH_MANAGER Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 29/32] Call the agent when a new Health Link is created Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 30/32] Add a test that creates a simple health agent Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 31/32] Send MCL disconnect callback to agents Jose Antonio Santos Cadenas
2010-06-04 8:30 ` [PATCH 32/32] Add support for mcl reconnections Jose Antonio Santos Cadenas
-- strict thread matches above, loose matches on Subject: below --
2010-06-02 13:18 [PATCH 00/32] Health device profile (HDP) Jose Antonio Santos Cadenas
2010-06-02 13:18 ` [PATCH 01/32] Add Health api description Jose Antonio Santos Cadenas
2010-06-02 13:18 ` [PATCH 02/32] Initial support for HDP Jose Antonio Santos Cadenas
2010-06-02 13:18 ` [PATCH 03/32] Add functions to resiger health instances in SDP Jose Antonio Santos Cadenas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1275640225-4186-4-git-send-email-santoscadenas@gmail.com \
--to=santoscadenas@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).