2 * Copyright (C) 2006 Mike McCauley
3 * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "tnc_imc_manager.h"
18 #include <tnc/imc/imc_manager.h>
19 #include <tnc/tncifimc.h>
23 #include <utils/linked_list.h>
25 typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t
;
28 * Private data of an imc_manager_t object.
30 struct private_tnc_imc_manager_t
{
33 * Public members of imc_manager_t.
43 * Next IMC ID to be assigned
45 TNC_IMCID next_imc_id
;
50 char *preferred_language
;
53 METHOD(imc_manager_t
, add
, bool,
54 private_tnc_imc_manager_t
*this, imc_t
*imc
)
58 /* Initialize the module */
59 imc
->set_id(imc
, this->next_imc_id
);
60 if (imc
->initialize(imc
->get_id(imc
), TNC_IFIMC_VERSION_1
,
61 TNC_IFIMC_VERSION_1
, &version
) != TNC_RESULT_SUCCESS
)
63 DBG1(DBG_TNC
, "IMC \"%s\" failed to initialize", imc
->get_name(imc
));
66 this->imcs
->insert_last(this->imcs
, imc
);
69 if (imc
->provide_bind_function(imc
->get_id(imc
), TNC_TNCC_BindFunction
)
70 != TNC_RESULT_SUCCESS
)
72 DBG1(DBG_TNC
, "IMC \"%s\" failed to obtain bind function",
74 this->imcs
->remove_last(this->imcs
, (void**)&imc
);
81 METHOD(imc_manager_t
, remove_
, imc_t
*,
82 private_tnc_imc_manager_t
*this, TNC_IMCID id
)
84 enumerator_t
*enumerator
;
87 enumerator
= this->imcs
->create_enumerator(this->imcs
);
88 while (enumerator
->enumerate(enumerator
, &imc
))
90 if (id
== imc
->get_id(imc
))
92 this->imcs
->remove_at(this->imcs
, enumerator
);
96 enumerator
->destroy(enumerator
);
100 METHOD(imc_manager_t
, get_preferred_language
, char*,
101 private_tnc_imc_manager_t
*this)
103 return this->preferred_language
;
106 METHOD(imc_manager_t
, notify_connection_change
, void,
107 private_tnc_imc_manager_t
*this, TNC_ConnectionID id
,
108 TNC_ConnectionState state
)
110 enumerator_t
*enumerator
;
113 enumerator
= this->imcs
->create_enumerator(this->imcs
);
114 while (enumerator
->enumerate(enumerator
, &imc
))
116 if (imc
->notify_connection_change
)
118 imc
->notify_connection_change(imc
->get_id(imc
), id
, state
);
121 enumerator
->destroy(enumerator
);
124 METHOD(imc_manager_t
, begin_handshake
, void,
125 private_tnc_imc_manager_t
*this, TNC_ConnectionID id
)
127 enumerator_t
*enumerator
;
130 enumerator
= this->imcs
->create_enumerator(this->imcs
);
131 while (enumerator
->enumerate(enumerator
, &imc
))
133 imc
->begin_handshake(imc
->get_id(imc
), id
);
135 enumerator
->destroy(enumerator
);
138 METHOD(imc_manager_t
, set_message_types
, TNC_Result
,
139 private_tnc_imc_manager_t
*this, TNC_IMCID id
,
140 TNC_MessageTypeList supported_types
,
141 TNC_UInt32 type_count
)
143 enumerator_t
*enumerator
;
145 TNC_Result result
= TNC_RESULT_FATAL
;
147 enumerator
= this->imcs
->create_enumerator(this->imcs
);
148 while (enumerator
->enumerate(enumerator
, &imc
))
150 if (id
== imc
->get_id(imc
))
152 imc
->set_message_types(imc
, supported_types
, type_count
);
153 result
= TNC_RESULT_SUCCESS
;
157 enumerator
->destroy(enumerator
);
161 METHOD(imc_manager_t
, receive_message
, void,
162 private_tnc_imc_manager_t
*this, TNC_ConnectionID connection_id
,
163 TNC_BufferReference message
,
164 TNC_UInt32 message_len
,
165 TNC_MessageType message_type
)
167 enumerator_t
*enumerator
;
170 enumerator
= this->imcs
->create_enumerator(this->imcs
);
171 while (enumerator
->enumerate(enumerator
, &imc
))
173 if (imc
->receive_message
&& imc
->type_supported(imc
, message_type
))
175 imc
->receive_message(imc
->get_id(imc
), connection_id
,
176 message
, message_len
, message_type
);
179 enumerator
->destroy(enumerator
);
182 METHOD(imc_manager_t
, batch_ending
, void,
183 private_tnc_imc_manager_t
*this, TNC_ConnectionID id
)
185 enumerator_t
*enumerator
;
188 enumerator
= this->imcs
->create_enumerator(this->imcs
);
189 while (enumerator
->enumerate(enumerator
, &imc
))
191 if (imc
->batch_ending
)
193 imc
->batch_ending(imc
->get_id(imc
), id
);
196 enumerator
->destroy(enumerator
);
199 METHOD(imc_manager_t
, destroy
, void,
200 private_tnc_imc_manager_t
*this)
204 while (this->imcs
->remove_last(this->imcs
, (void**)&imc
) == SUCCESS
)
206 if (imc
->terminate
&&
207 imc
->terminate(imc
->get_id(imc
)) != TNC_RESULT_SUCCESS
)
209 DBG1(DBG_TNC
, "IMC \"%s\" not terminated successfully",
214 this->imcs
->destroy(this->imcs
);
215 free(this->preferred_language
);
220 * Described in header.
222 imc_manager_t
* tnc_imc_manager_create(void)
224 private_tnc_imc_manager_t
*this;
229 .remove
= _remove_
, /* avoid name conflict with stdio.h */
230 .get_preferred_language
= _get_preferred_language
,
231 .notify_connection_change
= _notify_connection_change
,
232 .begin_handshake
= _begin_handshake
,
233 .set_message_types
= _set_message_types
,
234 .receive_message
= _receive_message
,
235 .batch_ending
= _batch_ending
,
238 .imcs
= linked_list_create(),
240 .preferred_language
= lib
->settings
->alloc_str(lib
->settings
,
241 "charon.plugins.tnc-imc.preferred_language", "en");
244 return &this->public;