summaryrefslogtreecommitdiffstats
path: root/binding/bluetooth-common.h
blob: 616e3226f32339b5c4314e037b967951a22456e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<
/*
 * Copyright 2018 Konsulko Group
 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
 * Author: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef BLUETOOTH_COMMON_H
#define BLUETOOTH_COMMON_H

#include <stddef.h>

#define _GNU_SOURCE
#include <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <glib-object.h>

#include <json-c/json.h>

#define AFB_BINDING_VERSION 3
#include <afb/afb-binding.h>

struct call_work;

struct bluetooth_state {
	GMainLoop *loop;
	GDBusConnection *conn;
	guint device_sub;
	guint autoconnect_sub;

	afb_event_t adapter_changes_event;
	afb_event_t device_changes_event;
	afb_event_t media_event;
	afb_event_t agent_event;

	/* NOTE: single connection allowed for now */
	/* NOTE: needs locking and a list */
	GMutex cw_mutex;
	int next_cw_id;
	GSList *cw_pending;
	struct call_work *cw;

	/* agent */
	GDBusNodeInfo *introspection_data;
	guint agent_id;
	guint registration_id;
	gchar *agent_path;
	gboolean agent_registered;

	/* mediaplayer */
	gchar *mediaplayer_path;

	/* adapter */
	gchar *adapter;
};

struct init_data {
	GCond cond;
	GMutex mutex;
	gboolean init_done;
	afb_api_t api;
	gchar *default_adapter;
	struct bluetooth_state *ns; /* before setting afb_api_set_userdata() */
	int rc;
};

struct agent_data {
	int pin_code;
	gchar *fixed_pincode;
	gchar *device_path;
};

struct call_work {
	struct bluetooth_state *ns;
	int id;
	gchar *access_type;
	gchar *type_arg;
	gchar *method;
	gchar *bluez_method;
	struct bluez_pending_work *cpw;
	afb_req_t request;
	struct agent_data agent_data;
	GDBusMethodInvocation *invocation;
};

/* agent methods in bluetooth-agent.c */

int bluetooth_register_agent(struct init_data *id);

void bluetooth_unregister_agent(struct bluetooth_state *ns);

/* conf methods in bluetooth-conf.c */

gchar *get_default_adapter(afb_api_t api);
int set_default_adapter(afb_api_t api, const char *adapter);

int set_pincode(afb_api_t api, const char *pincode, char **error);
gchar *get_pincode(afb_api_t api);

/* utility methods in bluetooth-util.c */

extern gboolean auto_lowercase_keys;

void signal_init_done(struct init_data *id, int rc);

int str2boolean(const char *value);

json_object *json_object_copy(json_object *jval);

gchar *key_dbus_to_json(const gchar *key, gboolean auto_lower);

json_object *simple_gvariant_to_json(GVariant *var, json_object *parent,
		gboolean recurse);

void json_process_path(json_object *jresp, const char *path);

gchar *return_bluez_path(afb_req_t request);

gchar **json_array_to_strv(json_object *jobj);

/**
 * Structure for converting from dbus properties to json
 * and vice-versa.
 * Note this is _not_ a generic dbus json bridge since
 * some constructs are not easily mapped.
 */
struct property_info {
	const char *name;	/* the connman property name */
	const char *json_name;	/* the json name (if NULL autoconvert) */
	const char *fmt;
	unsigned int flags;
	const struct property_info *sub;
};

#define PI_CONFIG	(1U << 0)

const struct property_info *property_by_dbus_name(
		const struct property_info *pi,
		const gchar *dbus_name,
		gboolean *is_config);
const struct property_info *property_by_json_name(
		const struct property_info *pi,
		const gchar *json_name,
		gboolean *is_config);
const struct property_info *property_by_name(
		const struct property_info *pi,
		gboolean is_json_name, const gchar *name,
		gboolean *is_config);

gchar *property_get_json_name(const struct property_info *pi,
		const gchar *name);
gchar *property_get_name(const struct property_info *pi,
		const gchar *json_name);

gchar *configuration_dbus_name(const gchar *dbus_name);
gchar *configuration_json_name(const gchar *json_name);

gchar *property_name_dbus2json(const struct property_info *pi,
		gboolean is_config);

json_object *property_dbus2json(
		const struct property_info **pip,
		const gchar *key, GVariant *var,
		gboolean *is_config);

gboolean root_property_dbus2json(
		json_object *jparent,
		const struct property_info *pi,
		const gchar *key, GVariant *var,
		gboolean *is_config);

GVariant *property_json_to_gvariant(
		const struct property_info *pi,
		const char *fmt,	/* if NULL use pi->fmt */
		const struct property_info *pi_parent,
		json_object *jval,
		GError **error);

typedef enum {
	NB_ERROR_BAD_TECHNOLOGY,
	NB_ERROR_BAD_SERVICE,
	NB_ERROR_OUT_OF_MEMORY,
	NB_ERROR_NO_TECHNOLOGIES,
	NB_ERROR_NO_SERVICES,
	NB_ERROR_BAD_PROPERTY,
	NB_ERROR_UNIMPLEMENTED,
	NB_ERROR_UNKNOWN_PROPERTY,
	NB_ERROR_UNKNOWN_TECHNOLOGY,
	NB_ERROR_UNKNOWN_SERVICE,
	NB_ERROR_MISSING_ARGUMENT,
	NB_ERROR_ILLEGAL_ARGUMENT,
	NB_ERROR_CALL_IN_PROGRESS,
} NBError;

#define NB_ERROR (nb_error_quark())

extern GQuark nb_error_quark(void);

json_object *get_property_collect(json_object *jreqprop, json_object *jprop,
		GError **error);
json_object *get_named_property(const struct property_info *pi,
		gboolean is_json_name, const char *name, json_object *jprop);

#endif