<commit_before>/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2009  <NAME> <<EMAIL>>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <errno.h>

#include <dbus/dbus.h>
#include <glib.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include "logging.h"
#include "device.h"
#include "manager.h"
#include "avdtp.h"
#include "sink.h"
#include "a2dp.h"
#include "sdpd.h"

/* The duration that streams without users are allowed to stay in
 * STREAMING state. */
#define SUSPEND_TIMEOUT 5
#define RECONFIGURE_TIMEOUT 500

#ifndef MIN
# define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif

#ifndef MAX
# define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif

struct a2dp_sep {
	uint8_t type;
	uint8_t codec;
	struct avdtp_local_sep *sep;
	struct avdtp *session;
	struct avdtp_stream *stream;
	guint suspend_timer;
	gboolean locked;
	gboolean suspending;
	gboolean starting;
};

struct a2dp_setup_cb {
	a2dp_config_cb_t config_cb;
	a2dp_stream_cb_t resume_cb;
	a2dp_stream_cb_t suspend_cb;
	void *user_data;
	unsigned int id;
};

struct a2dp_setup {
	struct avdtp *session;
	struct a2dp_sep *sep;
	struct avdtp_stream *stream;
	struct avdtp_error *err;
	GSList *client_caps;
	gboolean reconfigure;
	gboolean canceled;
	gboolean start;
	GSList *cb;
	int ref;
};

static DBusConnection *connection = NULL;

struct a2dp_server {
	bdaddr_t src;
	GSList *sinks;
	GSList *sources;
	uint32_t source_record_id;
	uint32_t sink_record_id;
};

static GSList *servers = NULL;
static GSList *setups = NULL;
static unsigned int cb_id = 0;

static struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
{
	setup->ref++;

	debug("setup_ref(%p): ref=%d", setup, setup->ref);

	return setup;
}

static void setup_free(struct a2dp_setup *s)
{
	debug("setup_free(%p)", s);
	setups = g_slist_remove(setups, s);
	if (s->session)
		avdtp_unref(s->session);
	g_slist_foreach(s->cb, (GFunc) g_free, NULL);
	g_slist_free(s->cb);
	g_free(s);
}

static void setup_unref(struct a2dp_setup *setup)
{
	setup->ref--;

	debug("setup_unref(%p): ref=%d", setup, setup->ref);

	if (setup->ref <= 0)
		setup_free(setup);
}

static struct audio_device *a2dp_get_dev(struct avdtp *session)
{
	bdaddr_t src, dst;

	avdtp_get_peers(session, &src, &dst);

	return manager_find_device(NULL, &src, &dst, NULL, FALSE);
}

static gboolean finalize_config(struct a2dp_setup *s)
{
	GSList *l;

	setup_ref(s);
	for (l = s->cb; l != NULL; l = l->next) {
		struct a2dp_setup_cb *cb = l->data;
		struct avdtp_stream *stream = s->err ? NULL : s->stream;

		if (!cb->config_cb)
			continue;

		cb->config_cb(s->session, s->sep, stream, s->err,
							cb->user_data);
		cb->config_cb = NULL;
		setup_unref(s);
	}

	setup_unref(s);
	return FALSE;
}

static gboolean finalize_config_errno(struct a2dp_setup *s, int err)
{
	struct avdtp_error avdtp_err;

	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
	s->err = err ? &avdtp_err : NULL;

	return finalize_config(s);
}

static gboolean finalize_resume(struct a2dp_setup *s)
{
	GSList *l;

	setup_ref(s);
	for (l = s->cb; l != NULL; l = l->next) {
		struct a2dp_setup_cb *cb = l->data;

		if (cb->resume_cb) {
			cb->resume_cb(s->session, s->err, cb->user_data);
			cb->resume_cb = NULL;
			setup_unref(s);
		}
	}

	setup_unref(s);
	return FALSE;
}<commit_msg>Null pointer check on cb in finalize_resume().<commit_after>/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2009  <NAME> <<EMAIL>>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <errno.h>

#include <dbus/dbus.h>
#include <glib.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include "logging.h"
#include "device.h"
#include "manager.h"
#include "avdtp.h"
#include "sink.h"
#include "a2dp.h"
#include "sdpd.h"

/* The duration that streams without users are allowed to stay in
 * STREAMING state. */
#define SUSPEND_TIMEOUT 5
#define RECONFIGURE_TIMEOUT 500

#ifndef MIN
# define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif

#ifndef MAX
# define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif

struct a2dp_sep {
	uint8_t type;
	uint8_t codec;
	struct avdtp_local_sep *sep;
	struct avdtp *session;
	struct avdtp_stream *stream;
	guint suspend_timer;
	gboolean locked;
	gboolean suspending;
	gboolean starting;
};

struct a2dp_setup_cb {
	a2dp_config_cb_t config_cb;
	a2dp_stream_cb_t resume_cb;
	a2dp_stream_cb_t suspend_cb;
	void *user_data;
	unsigned int id;
};

struct a2dp_setup {
	struct avdtp *session;
	struct a2dp_sep *sep;
	struct avdtp_stream *stream;
	struct avdtp_error *err;
	GSList *client_caps;
	gboolean reconfigure;
	gboolean canceled;
	gboolean start;
	GSList *cb;
	int ref;
};

static DBusConnection *connection = NULL;

struct a2dp_server {
	bdaddr_t src;
	GSList *sinks;
	GSList *sources;
	uint32_t source_record_id;
	uint32_t sink_record_id;
};

static GSList *servers = NULL;
static GSList *setups = NULL;
static unsigned int cb_id = 0;

static struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
{
	setup->ref++;

	debug("setup_ref(%p): ref=%d", setup, setup->ref);

	return setup;
}

static void setup_free(struct a2dp_setup *s)
{
	debug("setup_free(%p)", s);
	setups = g_slist_remove(setups, s);
	if (s->session)
		avdtp_unref(s->session);
	g_slist_foreach(s->cb, (GFunc) g_free, NULL);
	g_slist_free(s->cb);
	g_free(s);
}

static void setup_unref(struct a2dp_setup *setup)
{
	setup->ref--;

	debug("setup_unref(%p): ref=%d", setup, setup->ref);

	if (setup->ref <= 0)
		setup_free(setup);
}

static struct audio_device *a2dp_get_dev(struct avdtp *session)
{
	bdaddr_t src, dst;

	avdtp_get_peers(session, &src, &dst);

	return manager_find_device(NULL, &src, &dst, NULL, FALSE);
}

static gboolean finalize_config(struct a2dp_setup *s)
{
	GSList *l;

	setup_ref(s);
	for (l = s->cb; l != NULL; l = l->next) {
		struct a2dp_setup_cb *cb = l->data;
		struct avdtp_stream *stream = s->err ? NULL : s->stream;

		if (!cb->config_cb)
			continue;

		cb->config_cb(s->session, s->sep, stream, s->err,
							cb->user_data);
		cb->config_cb = NULL;
		setup_unref(s);
	}

	setup_unref(s);
	return FALSE;
}

static gboolean finalize_config_errno(struct a2dp_setup *s, int err)
{
	struct avdtp_error avdtp_err;

	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
	s->err = err ? &avdtp_err : NULL;

	return finalize_config(s);
}

static gboolean finalize_resume(struct a2dp_setup *s)
{
	GSList *l;

	setup_ref(s);
	for (l = s->cb; l != NULL; l = l->next) {
		struct a2dp_setup_cb *cb = l->data;

		if (cb && cb->resume_cb) {
			cb->resume_cb(s->session, s->err, cb->user_data);
			cb->resume_cb = NULL;
			setup_unref(s);
		}
	}

	setup_unref(s);
	return FALSE;
}
{'fraction_non_alphanumeric': 0.12624864604645564, 'fraction_numerical': 0.014201468287399205, 'mean_word_length': 4.333761232349166, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '169147', 'n_tokens_mistral': 3357, 'n_tokens_neox': 3218, 'n_words': 897}