File: config-server.c

package info (click to toggle)
bluez 5.83-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 25,664 kB
  • sloc: ansic: 471,418; python: 4,751; sh: 4,580; makefile: 1,042; xml: 126
file content (161 lines) | stat: -rw-r--r-- 3,283 bytes parent folder | download | duplicates (3)
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2017  Intel Corporation. All rights reserved.
 *
 *
 */

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

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/uio.h>
#include <wordexp.h>

#include <glib.h>
#include "tools/mesh/config-model.h"

#include "src/shared/util.h"
#include "src/shared/shell.h"
#include "tools/mesh-gatt/mesh-net.h"
#include "tools/mesh-gatt/keys.h"
#include "tools/mesh-gatt/net.h"
#include "tools/mesh-gatt/node.h"
#include "tools/mesh-gatt/prov-db.h"
#include "tools/mesh-gatt/util.h"

static bool server_msg_recvd(uint16_t src, uint8_t *data,
				uint16_t len, void *user_data)
{
	uint32_t opcode;
	uint8_t msg[32];
	struct mesh_node *node;
	uint16_t primary;
	uint32_t mod_id;
	uint16_t ele_addr;
	uint8_t ele_idx;
	struct mesh_publication pub;
	int m, n;

	if (mesh_opcode_get(data, len, &opcode, &n)) {
		len -= n;
		data += n;
	} else
		return false;

	node = node_get_local_node();

	if (!node)
		return true;

	n = 0;

	switch (opcode) {
	default:
		return false;

	case OP_CONFIG_DEFAULT_TTL_SET:
		if (len != 1 || data[0] > TTL_MASK || data[0] == 1)
			return true;

		if (data[0] <= TTL_MASK) {
			node_set_default_ttl(node, data[0]);
			prov_db_node_set_ttl(node, data[0]);
		}

		/* Fall Through */

	case OP_CONFIG_DEFAULT_TTL_GET:
		n = mesh_opcode_set(OP_CONFIG_DEFAULT_TTL_STATUS, msg);
		msg[n++] = node_get_default_ttl(node);
		break;

	case OP_CONFIG_MODEL_PUB_SET:

		if (len != 11 && len != 13)
			return true;

		bt_shell_printf("Set publication\n");

		ele_addr = get_le16(data);
		mod_id = get_le16(data + 9);
		if (len == 14)
			mod_id = (mod_id << 16)  | get_le16(data + 11);
		else
			mod_id |= 0xffff0000;

		pub.u.addr16 = get_le16(data + 2);
		pub.app_idx = get_le16(data + 4);
		pub.ttl = data[6];
		pub.period = data[7];
		m = (data[7] & 0x3f);
		switch (data[7] >> 6) {
		case 0:
			bt_shell_printf("Period: %d ms\n", m * 100);
			break;
		case 2:
			m *= 10;
			/* fall through */
		case 1:
			bt_shell_printf("Period: %d sec\n", m);
			break;
		case 3:
			bt_shell_printf("Period: %d min\n", m * 10);
			break;
		}

		pub.retransmit = data[8];
		bt_shell_printf("Retransmit count: %d\n", data[8] >> 5);
		bt_shell_printf("Retransmit Interval Steps: %d\n",
				data[8] & 0x1f);

		ele_idx = ele_addr - node_get_primary(node);

		if (node_model_pub_set(node, ele_idx, mod_id, &pub)) {
			prov_db_node_set_model_pub(node, ele_idx, mod_id,
				     node_model_pub_get(node, ele_idx, mod_id));
		}
		break;
	}

	if (!n)
		return true;

	primary = node_get_primary(node);
	if (src != primary)
		net_access_layer_send(node_get_default_ttl(node), primary,
					src, APP_IDX_DEV, msg, n);
	else
		node_local_data_handler(primary, src, node_get_iv_index(node),
					node_get_sequence_number(node),
					APP_IDX_DEV, msg, n);
	return true;
}


static struct mesh_model_ops server_cbs = {
	server_msg_recvd,
		NULL,
		NULL,
		NULL
};

bool config_server_init(void)
{
	if (!node_local_model_register(PRIMARY_ELEMENT_IDX,
						CONFIG_SERVER_MODEL_ID,
						&server_cbs, NULL))
		return false;

	return true;
}