Add initial crypto functionality
[libcontrac.git] / src / match.c
1 /** \ingroup contrac
2 * @file
3 * @author David Llewellyn-Jones
4 * @version $(VERSION)
5 *
6 * @section LICENSE
7 *
8 *
9 *
10 * @brief
11 * @section DESCRIPTION
12 *
13 *
14 *
15 */
16
17 // Includes
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stddef.h>
22 #include <stdint.h>
23
24 #include <openssl/crypto.h>
25 #include <openssl/hmac.h>
26 #include <openssl/err.h>
27
28 #include "contrac/contrac.h"
29 #include "contrac/utils.h"
30 #include "contrac/log.h"
31 #include "contrac/rpi_list.h"
32 #include "contrac/dtk_list.h"
33
34 #include "contrac/match.h"
35
36 // Defines
37
38 // Structures
39
40 struct _MatchListItem {
41 uint32_t day_number;
42 uint8_t time_interval_number;
43
44 MatchListItem * next;
45 };
46
47 struct _MatchList {
48 size_t count;
49 MatchListItem * first;
50 MatchListItem * last;
51 };
52
53 // Function prototypes
54
55 MatchListItem * match_list_item_new();
56 void match_list_item_delete(MatchListItem * data);
57 void match_list_append(MatchList * data, MatchListItem * item);
58
59 // Function definitions
60
61 MatchList * match_list_new() {
62 MatchList * data;
63
64 data = calloc(sizeof(MatchList), 1);
65
66 return data;
67 }
68
69 void match_list_delete(MatchList * data) {
70 if (data) {
71 match_list_clear(data);
72
73 free(data);
74 }
75 }
76
77 MatchListItem * match_list_item_new() {
78 MatchListItem * data;
79
80 data = calloc(sizeof(MatchListItem), 1);
81
82 return data;
83 }
84
85 void match_list_item_delete(MatchListItem * data) {
86 if (data) {
87 free(data);
88 }
89 }
90
91 void match_list_clear(MatchList * data) {
92 MatchListItem * item;
93 MatchListItem * next;
94
95 item = data->first;
96 while (item) {
97 next = item->next;
98 match_list_item_delete(item);
99 item = next;
100 }
101
102 data->first = NULL;
103 data->last = NULL;
104 data->count = 0;
105 }
106
107 size_t match_list_count(MatchList * data) {
108 return data->count;
109 }
110
111 MatchListItem const * match_list_first(MatchList const * data) {
112 return data->first;
113 }
114
115 MatchListItem const * match_list_next(MatchListItem const * data) {
116 return data->next;
117 }
118
119
120 uint32_t match_list_get_day_number(MatchListItem const * data) {
121 return data->day_number;
122 }
123
124 uint8_t match_list_get_time_interval_number(MatchListItem const * data) {
125 return data->time_interval_number;
126 }
127
128 void match_list_append(MatchList * data, MatchListItem * item) {
129 if (data->last == NULL) {
130 data->first = item;
131 data->last = item;
132 }
133 else {
134 data->last->next = item;
135 data->last = item;
136 }
137 data->count++;
138 }
139
140 void match_list_find_matches(MatchList * data, RpiList * beacons, DtkList * diagnosis_keys) {
141 // For each diagnosis key, generate the RPIs and compare them against the captured RPI beacons
142 DtkListItem const * dtk_item;
143 RpiListItem const * rpi_item;
144 uint8_t interval;
145 bool result;
146 Rpi * generated;
147 MatchListItem * match;
148 Dtk const * diagnosis_key;
149 Rpi const * rpi;
150
151 dtk_item = dtk_list_first(diagnosis_keys);
152 generated = rpi_new();
153
154 while (dtk_item != NULL) {
155 diagnosis_key = dtk_list_get_dtk(dtk_item);
156 // Generate all possible RPIs for this dtk and compare agsinst the beacons
157 for (interval = 0; interval < RPI_INTERVAL_MAX; ++interval) {
158 result = rpi_generate_proximity_id(generated, diagnosis_key, interval);
159 if (result) {
160 // Check against all beacons
161 rpi_item = rpi_list_first(beacons);
162 while (rpi_item != NULL) {
163 rpi = rpi_list_get_rpi(rpi_item);
164 result = rpi_compare(rpi, generated);
165
166 if (result) {
167 if (interval != rpi_get_time_interval_number(rpi)) {
168 result = false;
169 LOG(LOG_DEBUG, "Matched beacons don't match intervals\n");
170 }
171 }
172
173 if (result) {
174 match = match_list_item_new();
175 match->day_number = dtk_get_day_number(diagnosis_key);
176 match->time_interval_number = interval;
177 match_list_append(data, match);
178 }
179
180 rpi_item = rpi_list_next(rpi_item);
181 }
182 }
183 }
184
185 dtk_item = dtk_list_next(dtk_item);
186 }
187
188 rpi_delete(generated);
189 }
190
191