support multiple language preferences
[strongswan.git] / src / libimcv / plugins / imv_test / imv_test_state.c
1 /*
2 * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include "imv_test_state.h"
16
17 #include <utils/lexparser.h>
18 #include <debug.h>
19
20 typedef struct private_imv_test_state_t private_imv_test_state_t;
21
22 /**
23 * Private data of an imv_test_state_t object.
24 */
25 struct private_imv_test_state_t {
26
27 /**
28 * Public members of imv_test_state_t
29 */
30 imv_test_state_t public;
31
32 /**
33 * TNCCS connection ID
34 */
35 TNC_ConnectionID connection_id;
36
37 /**
38 * TNCCS connection state
39 */
40 TNC_ConnectionState state;
41
42 /**
43 * IMV action recommendation
44 */
45 TNC_IMV_Action_Recommendation rec;
46
47 /**
48 * IMV evaluation result
49 */
50 TNC_IMV_Evaluation_Result eval;
51
52 /**
53 * IMC-IMV round-trip count
54 */
55 int rounds;
56
57 };
58
59 typedef struct entry_t entry_t;
60
61 /**
62 * Define an internal reason string entry
63 */
64 struct entry_t {
65 char *lang;
66 char *string;
67 };
68
69 /**
70 * Table of multi-lingual reason string entries
71 */
72 static entry_t reasons[] = {
73 { "en", "IMC Test was not configured with \"command = allow\"" },
74 { "de", "IMC Test wurde nicht mit \"command = allow\" konfiguriert" },
75 { "fr", "IMC Test n'etait pas configuré avec \"command = allow\"" },
76 { "pl", "IMC Test nie zostało skonfigurowany z \"command = allow\"" }
77 };
78
79 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
80 private_imv_test_state_t *this)
81 {
82 return this->connection_id;
83 }
84
85 METHOD(imv_state_t, change_state, void,
86 private_imv_test_state_t *this, TNC_ConnectionState new_state)
87 {
88 this->state = new_state;
89 }
90
91 METHOD(imv_state_t, get_recommendation, void,
92 private_imv_test_state_t *this, TNC_IMV_Action_Recommendation *rec,
93 TNC_IMV_Evaluation_Result *eval)
94 {
95 *rec = this->rec;
96 *eval = this->eval;
97 }
98
99 METHOD(imv_state_t, set_recommendation, void,
100 private_imv_test_state_t *this, TNC_IMV_Action_Recommendation rec,
101 TNC_IMV_Evaluation_Result eval)
102 {
103 this->rec = rec;
104 this->eval = eval;
105 }
106
107 METHOD(imv_state_t, get_reason_string, bool,
108 private_imv_test_state_t *this, chunk_t preferred_language,
109 chunk_t *reason_string, chunk_t *reason_language)
110 {
111 chunk_t pref_lang, lang;
112 int i;
113
114 while (eat_whitespace(&preferred_language))
115 {
116 if (!extract_token(&pref_lang, ',', &preferred_language))
117 {
118 /* last entry in a comma-separated list or single entry */
119 pref_lang = preferred_language;
120 }
121
122 for (i = 0 ; i < countof(reasons); i++)
123 {
124 lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
125 if (chunk_equals(lang, pref_lang))
126 {
127 *reason_language = lang;
128 *reason_string = chunk_create(reasons[i].string,
129 strlen(reasons[i].string));
130 return TRUE;
131 }
132 }
133 }
134
135 /* no preferred language match found - use the default language */
136 *reason_string = chunk_create(reasons[0].string,
137 strlen(reasons[0].string));
138 *reason_language = chunk_create(reasons[0].lang,
139 strlen(reasons[0].lang));
140 return TRUE;
141 }
142
143 METHOD(imv_state_t, destroy, void,
144 private_imv_test_state_t *this)
145 {
146 free(this);
147 }
148
149 METHOD(imv_test_state_t, set_rounds, void,
150 private_imv_test_state_t *this, int rounds)
151 {
152 this->rounds = rounds;
153 }
154
155 METHOD(imv_test_state_t, another_round, bool,
156 private_imv_test_state_t *this)
157 {
158 return (this->rounds-- > 0);
159 }
160
161 /**
162 * Described in header.
163 */
164 imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
165 {
166 private_imv_test_state_t *this;
167
168 INIT(this,
169 .public = {
170 .interface = {
171 .get_connection_id = _get_connection_id,
172 .change_state = _change_state,
173 .get_recommendation = _get_recommendation,
174 .set_recommendation = _set_recommendation,
175 .get_reason_string = _get_reason_string,
176 .destroy = _destroy,
177 },
178 .set_rounds = _set_rounds,
179 .another_round = _another_round,
180 },
181 .state = TNC_CONNECTION_STATE_CREATE,
182 .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
183 .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
184 .connection_id = connection_id,
185 );
186
187 return &this->public.interface;
188 }
189
190