Skip to content

Commit

Permalink
[core] Expose LLCP version and the list of P2P services. JB#53077
Browse files Browse the repository at this point in the history
Plugins will need those in order to build the list of LLCP options
exchanged during the link activation.

Also added the following functions:

  nfc_manager_add_service_registered_handler()
  nfc_manager_add_service_unregistered_handler()

to track changes in the service list.
  • Loading branch information
monich committed Feb 19, 2021
1 parent 2f8657c commit 5b702eb
Show file tree
Hide file tree
Showing 12 changed files with 336 additions and 129 deletions.
30 changes: 27 additions & 3 deletions core/include/nfc_manager.h
Expand Up @@ -50,6 +50,9 @@ struct nfc_manager {
int error;
/* Since 1.1.0 */
NFC_MODE mode;
/* Since 1.1.1 */
NFC_LLCP_VERSION llcp_version;
NfcPeerService* const* services;
};

GType nfc_manager_get_type() NFCD_EXPORT;
Expand All @@ -73,6 +76,13 @@ void
NfcAdapter* adapter,
void* user_data);

typedef
void
(*NfcManagerServiceFunc)(
NfcManager* manager,
NfcPeerService* service,
void* user_data);

NfcManager*
nfc_manager_ref(
NfcManager* manager)
Expand Down Expand Up @@ -157,6 +167,13 @@ nfc_manager_add_enabled_changed_handler(
void* user_data)
NFCD_EXPORT;

gulong
nfc_manager_add_stopped_handler(
NfcManager* manager,
NfcManagerFunc func,
void* user_data)
NFCD_EXPORT;

gulong
nfc_manager_add_mode_changed_handler(
NfcManager* manager,
Expand All @@ -165,10 +182,17 @@ nfc_manager_add_mode_changed_handler(
NFCD_EXPORT;

gulong
nfc_manager_add_stopped_handler(
nfc_manager_add_service_registered_handler(
NfcManager* manager,
NfcManagerFunc func,
void* user_data)
NfcManagerServiceFunc func,
void* user_data) /* Since 1.1.1 */
NFCD_EXPORT;

gulong
nfc_manager_add_service_unregistered_handler(
NfcManager* manager,
NfcManagerServiceFunc func,
void* user_data) /* Since 1.1.1 */
NFCD_EXPORT;

void
Expand Down
6 changes: 6 additions & 0 deletions core/include/nfc_types.h
Expand Up @@ -123,6 +123,12 @@ typedef enum nfc_peer_connect_result {
NFC_PEER_CONNECT_FAILED /* I/O or protocol error */
} NFC_PEER_CONNECT_RESULT;

typedef enum nfc_llcp_version {
NFC_LLCP_VERSION_1_0 = 0x10,
NFC_LLCP_VERSION_1_1 = 0x11,
NFC_LLCP_VERSION_1_2 = 0x12
} NFC_LLCP_VERSION; /* Since 1.1.1 */

/* RF technology specific parameters */

typedef struct nfc_param_poll_a {
Expand Down
7 changes: 2 additions & 5 deletions core/src/nfc_llc_param.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020-2021 Jolla Ltd.
* Copyright (C) 2020-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -42,9 +42,6 @@
#define NFC_LLC_RW_DEFAULT (1)
#define NFC_LLC_RW_MAX (0xf)

#define NFC_LLCP_VERSION_1_0 (0x10) /* LLCP 1.0 */
#define NFC_LLCP_VERSION_1_1 (0x11) /* LLCP 1.1 */

typedef enum nfc_llc_param_type {
NFC_LLC_PARAM_VERSION = 1,
NFC_LLC_PARAM_MIUX = 2,
Expand Down
66 changes: 55 additions & 11 deletions core/src/nfc_manager.c
Expand Up @@ -35,6 +35,7 @@
#include "nfc_manager_p.h"
#include "internal/nfc_manager_i.h"
#include "nfc_adapter_p.h"
#include "nfc_peer_service.h"
#include "nfc_peer_services.h"
#include "nfc_plugins.h"
#include "nfc_log.h"
Expand Down Expand Up @@ -72,17 +73,21 @@ G_DEFINE_TYPE(NfcManager, nfc_manager, G_TYPE_OBJECT)
enum nfc_manager_signal {
SIGNAL_ADAPTER_ADDED,
SIGNAL_ADAPTER_REMOVED,
SIGNAL_SERVICE_REGISTERED,
SIGNAL_SERVICE_UNREGISTERED,
SIGNAL_ENABLED_CHANGED,
SIGNAL_MODE_CHANGED,
SIGNAL_STOPPED,
SIGNAL_COUNT
};

#define SIGNAL_ADAPTER_ADDED_NAME "nfc-manager-adapter-added"
#define SIGNAL_ADAPTER_REMOVED_NAME "nfc-manager-adapter-removed"
#define SIGNAL_ENABLED_CHANGED_NAME "nfc-manager-enabled-changed"
#define SIGNAL_MODE_CHANGED_NAME "nfc-manager-mode-changed"
#define SIGNAL_STOPPED_NAME "nfc-manager-stopped"
#define SIGNAL_ADAPTER_ADDED_NAME "nfc-manager-adapter-added"
#define SIGNAL_ADAPTER_REMOVED_NAME "nfc-manager-adapter-removed"
#define SIGNAL_SERVICE_REGISTERED_NAME "nfc-manager-service-registered"
#define SIGNAL_SERVICE_UNREGISTERED_NAME "nfc-manager-service-unregistered"
#define SIGNAL_ENABLED_CHANGED_NAME "nfc-manager-enabled-changed"
#define SIGNAL_MODE_CHANGED_NAME "nfc-manager-mode-changed"
#define SIGNAL_STOPPED_NAME "nfc-manager-stopped"

static guint nfc_manager_signals[SIGNAL_COUNT] = { 0 };

Expand Down Expand Up @@ -468,10 +473,15 @@ nfc_manager_register_service(
NfcManagerPriv* priv = self->priv;

if (nfc_peer_services_add(priv->services, service)) {
nfc_peer_service_ref(service);
self->services = priv->services->list;
if (!priv->p2p_request) {
priv->p2p_request = nfc_manager_mode_request_new_internal(self,
TRUE, NFC_MODES_P2P, NFC_MODE_NONE);
}
g_signal_emit(self, nfc_manager_signals
[SIGNAL_SERVICE_REGISTERED], 0, service);
nfc_peer_service_unref(service);
return TRUE;
}
}
Expand All @@ -486,10 +496,16 @@ nfc_manager_unregister_service(
if (G_LIKELY(self)) {
NfcManagerPriv* priv = self->priv;

nfc_peer_services_remove(priv->services, service);
if (!priv->services->list[0]) {
nfc_manager_release_p2p_mode_request(self);
nfc_peer_service_ref(service);
if (nfc_peer_services_remove(priv->services, service)) {
self->services = priv->services->list;
if (!priv->services->list[0]) {
nfc_manager_release_p2p_mode_request(self);
}
g_signal_emit(self, nfc_manager_signals
[SIGNAL_SERVICE_UNREGISTERED], 0, service);
}
nfc_peer_service_unref(service);
}
}

Expand Down Expand Up @@ -533,6 +549,26 @@ nfc_manager_add_mode_changed_handler(
SIGNAL_MODE_CHANGED_NAME, G_CALLBACK(func), user_data) : 0;
}

gulong
nfc_manager_add_service_registered_handler(
NfcManager* self,
NfcManagerServiceFunc func,
void* user_data) /* Since 1.1.1 */
{
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_SERVICE_REGISTERED_NAME, G_CALLBACK(func), user_data) : 0;
}

gulong
nfc_manager_add_service_unregistered_handler(
NfcManager* self,
NfcManagerServiceFunc func,
void* user_data) /* Since 1.1.1 */
{
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_SERVICE_UNREGISTERED_NAME, G_CALLBACK(func), user_data) : 0;
}

gulong
nfc_manager_add_stopped_handler(
NfcManager* self,
Expand Down Expand Up @@ -621,13 +657,15 @@ nfc_manager_init(
NfcManagerPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NFC_TYPE_MANAGER,
NfcManagerPriv);

priv->services = nfc_peer_services_new();
priv->adapters = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_object_unref);
self->priv = priv;
self->adapters = g_new0(NfcAdapter*, 1);
self->enabled = TRUE;
self->mode = priv->default_mode = NFC_MODE_READER_WRITER;
priv->services = nfc_peer_services_new();
priv->adapters = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_object_unref);
self->llcp_version = NFC_LLCP_VERSION_1_1;
self->services = priv->services->list;
}

static
Expand Down Expand Up @@ -663,6 +701,12 @@ nfc_manager_class_init(
nfc_manager_signals[SIGNAL_ADAPTER_REMOVED] =
g_signal_new(SIGNAL_ADAPTER_REMOVED_NAME, type, G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT);
nfc_manager_signals[SIGNAL_SERVICE_REGISTERED] =
g_signal_new(SIGNAL_SERVICE_REGISTERED_NAME, type, G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT);
nfc_manager_signals[SIGNAL_SERVICE_UNREGISTERED] =
g_signal_new(SIGNAL_SERVICE_UNREGISTERED_NAME, type, G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT);
nfc_manager_signals[SIGNAL_ENABLED_CHANGED] =
g_signal_new(SIGNAL_ENABLED_CHANGED_NAME, type, G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL, G_TYPE_NONE, 0);
Expand Down
95 changes: 95 additions & 0 deletions unit/common/test_service.c
@@ -0,0 +1,95 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "test_service.h"

#include "nfc_peer_service_impl.h"

typedef NfcPeerServiceClass TestServiceClass;

G_DEFINE_TYPE(TestService, test_service, NFC_TYPE_PEER_SERVICE)

static
void
test_service_peer_arrived(
NfcPeerService* service,
NfcPeer* peer)
{
TEST_SERVICE(service)->peer_arrived++;
NFC_PEER_SERVICE_CLASS(test_service_parent_class)->
peer_arrived(service, peer);
}

static
void
test_service_peer_left(
NfcPeerService* service,
NfcPeer* peer)
{
TEST_SERVICE(service)->peer_left++;
NFC_PEER_SERVICE_CLASS(test_service_parent_class)->
peer_left(service, peer);
}

static
void
test_service_init(
TestService* self)
{
}

static
void
test_service_class_init(
TestServiceClass* klass)
{
klass->peer_arrived = test_service_peer_arrived;
klass->peer_left = test_service_peer_left;
}

TestService*
test_service_new(
const char* name)
{
TestService* test = g_object_new(TEST_TYPE_SERVICE, NULL);

nfc_peer_service_init_base(&test->service, name);
return test;
}

/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
62 changes: 62 additions & 0 deletions unit/common/test_service.h
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef TEST_SERVICE_H
#define TEST_SERVICE_H

#include <nfc_types_p.h>
#include <nfc_peer_service_impl.h>

typedef struct test_service {
NfcPeerService service;
int peer_arrived;
int peer_left;
} TestService;

GType test_service_get_type(void);
#define TEST_TYPE_SERVICE (test_service_get_type())
#define TEST_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, \
TEST_TYPE_SERVICE, TestService))

TestService*
test_service_new(
const char* name);

#endif /* TEST_SERVICE_H */

/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
2 changes: 2 additions & 0 deletions unit/core_manager/Makefile
Expand Up @@ -2,4 +2,6 @@

EXE = test_core_manager

COMMON_SRC = test_main.c test_service.c

include ../common/Makefile

0 comments on commit 5b702eb

Please sign in to comment.