1 /*
2  * Copyright 2024 Trackunit Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/gnss.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys/atomic.h>
10 #include <zephyr/ztest.h>
11 
12 #define TEST_SEARCH_PERIOD K_SECONDS(CONFIG_TEST_SEARCH_PERIOD)
13 
14 static const struct device *dev = DEVICE_DT_GET(DT_ALIAS(gnss));
15 static const gnss_systems_t enabled_systems_array[] = {
16 	CONFIG_TEST_ENABLED_SYSTEMS_0,
17 	CONFIG_TEST_ENABLED_SYSTEMS_1,
18 	CONFIG_TEST_ENABLED_SYSTEMS_2,
19 	CONFIG_TEST_ENABLED_SYSTEMS_3,
20 };
21 
test_reported_are_expected(gnss_systems_t reported,gnss_systems_t expected)22 static bool test_reported_are_expected(gnss_systems_t reported, gnss_systems_t expected)
23 {
24 	return ((~expected) & reported) == 0;
25 }
26 
test_set_enabled_systems(gnss_systems_t enabled_systems)27 static void test_set_enabled_systems(gnss_systems_t enabled_systems)
28 {
29 	int ret;
30 
31 	ret = gnss_set_enabled_systems(dev, enabled_systems);
32 	zassert_ok(ret, "failed to set enabled systems (%i)", ret);
33 }
34 
test_get_system_enabled(gnss_systems_t expected_systems)35 static void test_get_system_enabled(gnss_systems_t expected_systems)
36 {
37 	int ret;
38 	gnss_systems_t enabled_systems;
39 
40 	ret = gnss_get_enabled_systems(dev, &enabled_systems);
41 	if (ret == -ENOSYS) {
42 		return;
43 	}
44 	zassert_ok(ret, "failed to get enabled systems (%i)", ret);
45 
46 	zassert_equal(enabled_systems, expected_systems,
47 		      "invalid enabled systems (%u != %u)",
48 		      enabled_systems, expected_systems);
49 }
50 
51 #ifdef CONFIG_GNSS_SATELLITES
52 static atomic_t reported_systems_atom = ATOMIC_INIT(0);
53 
gnss_satellites_cb(const struct device * dev,const struct gnss_satellite * satellites,uint16_t size)54 static void gnss_satellites_cb(const struct device *dev,
55 			       const struct gnss_satellite *satellites,
56 			       uint16_t size)
57 {
58 	for (uint16_t i = 0; i < size; i++) {
59 		atomic_or(&reported_systems_atom, satellites[i].system);
60 	}
61 }
62 
63 GNSS_SATELLITES_CALLBACK_DEFINE(DEVICE_DT_GET(DT_ALIAS(gnss)), gnss_satellites_cb);
64 
test_validate_satellites(gnss_systems_t expected_systems)65 static void test_validate_satellites(gnss_systems_t expected_systems)
66 {
67 	gnss_systems_t reported_systems;
68 	bool expected;
69 
70 	atomic_set(&reported_systems_atom, 0);
71 	PRINT("searching with enabled system %u\n", expected_systems);
72 	k_sleep(TEST_SEARCH_PERIOD);
73 
74 	reported_systems = atomic_get(&reported_systems_atom);
75 	if (reported_systems == 0) {
76 		PRINT("found no satellites\n");
77 	} else {
78 		PRINT("found satellites\n");
79 	}
80 
81 	expected = test_reported_are_expected(reported_systems, expected_systems);
82 	zassert_true(expected, "unexpected systems reported (%u != %u)",
83 		     reported_systems, expected_systems);
84 }
85 #endif
86 
test_validate_enabled_systems(void)87 static void test_validate_enabled_systems(void)
88 {
89 	gnss_systems_t enabled_systems;
90 
91 	for (uint8_t i = 0; i < ARRAY_SIZE(enabled_systems_array); i++) {
92 		enabled_systems = enabled_systems_array[i];
93 		if (enabled_systems == 0) {
94 			continue;
95 		}
96 
97 		test_set_enabled_systems(enabled_systems);
98 		test_get_system_enabled(enabled_systems);
99 #ifdef CONFIG_GNSS_SATELLITES
100 		test_validate_satellites(enabled_systems);
101 #endif
102 	}
103 }
104 
test_all_enabled_systems_are_disabled(void)105 static bool test_all_enabled_systems_are_disabled(void)
106 {
107 	gnss_systems_t enabled_systems;
108 
109 	for (uint8_t i = 0; i < ARRAY_SIZE(enabled_systems_array); i++) {
110 		enabled_systems = enabled_systems_array[i];
111 		if (enabled_systems != 0) {
112 			return false;
113 		}
114 	}
115 
116 	return true;
117 }
118 
test_validate_supported_systems(void)119 static void test_validate_supported_systems(void)
120 {
121 	gnss_systems_t supported_systems;
122 	int ret;
123 	gnss_systems_t enabled_systems;
124 	bool supported;
125 
126 	ret = gnss_get_supported_systems(dev, &supported_systems);
127 	if (ret == -ENOSYS) {
128 		return;
129 	}
130 	zassert_ok(ret, "failed to get supported systems (%i)", ret);
131 
132 	for (uint8_t i = 0; i < ARRAY_SIZE(enabled_systems_array); i++) {
133 		enabled_systems = enabled_systems_array[0];
134 		supported = test_reported_are_expected(enabled_systems, supported_systems);
135 		zassert_true(supported, "enabled systems %u is not supported", i);
136 	}
137 }
138 
ZTEST(gnss_api,test_enabled_systems)139 ZTEST(gnss_api, test_enabled_systems)
140 {
141 	if (test_all_enabled_systems_are_disabled()) {
142 		ztest_test_skip();
143 	}
144 
145 	test_validate_supported_systems();
146 	test_validate_enabled_systems();
147 }
148