4 * @brief Implementation of ts_payload_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #include "ts_payload.h"
27 #include <encoding/payloads/encodings.h>
28 #include <utils/linked_list.h>
30 typedef struct private_ts_payload_t private_ts_payload_t
;
33 * Private data of an ts_payload_t object.
36 struct private_ts_payload_t
{
38 * Public ts_payload_t interface.
43 * TRUE if this TS payload is of type TSi, FALSE for TSr.
50 u_int8_t next_payload
;
58 * Length of this payload.
60 u_int16_t payload_length
;
63 * Number of traffic selectors
65 u_int8_t number_of_traffic_selectors
;
68 * Contains the traffic selectors of type traffic_selector_substructure_t.
70 linked_list_t
*traffic_selectors
;
73 * @brief Computes the length of this payload.
75 * @param this calling private_ts_payload_t object
77 void (*compute_length
) (private_ts_payload_t
*this);
81 * Encoding rules to parse or generate a TS payload
83 * The defined offsets are the positions in a object of type
84 * private_ts_payload_t.
87 encoding_rule_t ts_payload_encodings
[] = {
88 /* 1 Byte next payload type, stored in the field next_payload */
89 { U_INT_8
, offsetof(private_ts_payload_t
, next_payload
) },
90 /* the critical bit */
91 { FLAG
, offsetof(private_ts_payload_t
, critical
) },
92 /* 7 Bit reserved bits, nowhere stored */
100 /* Length of the whole payload*/
101 { PAYLOAD_LENGTH
, offsetof(private_ts_payload_t
, payload_length
)},
103 { U_INT_8
, offsetof(private_ts_payload_t
, number_of_traffic_selectors
) },
104 /* 3 reserved bytes */
105 { RESERVED_BYTE
, 0 },
106 { RESERVED_BYTE
, 0 },
107 { RESERVED_BYTE
, 0 },
108 /* some ts data bytes, length is defined in PAYLOAD_LENGTH */
109 { TRAFFIC_SELECTORS
, offsetof(private_ts_payload_t
, traffic_selectors
) }
114 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
115 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116 ! Next Payload !C! RESERVED ! Payload Length !
117 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118 ! Number of TSs ! RESERVED !
119 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
121 ~ <Traffic Selectors> ~
123 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127 * Implementation of payload_t.verify.
129 static status_t
verify(private_ts_payload_t
*this)
131 iterator_t
*iterator
;
132 status_t status
= SUCCESS
;
134 if (this->number_of_traffic_selectors
!= (this->traffic_selectors
->get_count(this->traffic_selectors
)))
136 /* must be the same */
140 iterator
= this->traffic_selectors
->create_iterator(this->traffic_selectors
,TRUE
);
141 while(iterator
->has_next(iterator
))
143 payload_t
*current_traffic_selector
;
144 iterator
->current(iterator
,(void **)¤t_traffic_selector
);
146 status
= current_traffic_selector
->verify(current_traffic_selector
);
147 if (status
!= SUCCESS
)
152 iterator
->destroy(iterator
);
158 * Implementation of ts_payload_t.get_encoding_rules.
160 static void get_encoding_rules(private_ts_payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
162 *rules
= ts_payload_encodings
;
163 *rule_count
= sizeof(ts_payload_encodings
) / sizeof(encoding_rule_t
);
167 * Implementation of payload_t.get_type.
169 static payload_type_t
get_payload_type(private_ts_payload_t
*this)
171 if (this->is_initiator
)
173 return TRAFFIC_SELECTOR_INITIATOR
;
177 return TRAFFIC_SELECTOR_RESPONDER
;
182 * Implementation of payload_t.get_next_type.
184 static payload_type_t
get_next_type(private_ts_payload_t
*this)
186 return (this->next_payload
);
190 * Implementation of payload_t.set_next_type.
192 static void set_next_type(private_ts_payload_t
*this,payload_type_t type
)
194 this->next_payload
= type
;
198 * Implementation of payload_t.get_length.
200 static size_t get_length(private_ts_payload_t
*this)
202 this->compute_length(this);
203 return this->payload_length
;
207 * Implementation of ts_payload_t.get_initiator.
209 static bool get_initiator (private_ts_payload_t
*this)
211 return (this->is_initiator
);
215 * Implementation of ts_payload_t.set_initiator.
217 static void set_initiator (private_ts_payload_t
*this,bool is_initiator
)
219 this->is_initiator
= is_initiator
;
223 * Implementation of ts_payload_t.add_traffic_selector_substructure.
225 static void add_traffic_selector_substructure (private_ts_payload_t
*this,traffic_selector_substructure_t
*traffic_selector
)
227 this->traffic_selectors
->insert_last(this->traffic_selectors
,traffic_selector
);
228 this->number_of_traffic_selectors
= this->traffic_selectors
->get_count(this->traffic_selectors
);
232 * Implementation of ts_payload_t.create_traffic_selector_substructure_iterator.
234 static iterator_t
* create_traffic_selector_substructure_iterator (private_ts_payload_t
*this, bool forward
)
236 return this->traffic_selectors
->create_iterator(this->traffic_selectors
,forward
);
240 * Implementation of ts_payload_t.get_traffic_selectors.
242 static linked_list_t
*get_traffic_selectors(private_ts_payload_t
*this)
244 traffic_selector_t
*ts
;
245 iterator_t
*iterator
;
246 linked_list_t
*ts_list
= linked_list_create();
248 iterator
= this->traffic_selectors
->create_iterator(this->traffic_selectors
, TRUE
);
249 while (iterator
->has_next(iterator
))
251 traffic_selector_substructure_t
*ts_substructure
;
252 iterator
->current(iterator
, (void**)&ts_substructure
);
253 ts
= ts_substructure
->get_traffic_selector(ts_substructure
);
254 ts_list
->insert_last(ts_list
, (void*)ts
);
256 iterator
->destroy(iterator
);
262 * Implementation of private_ts_payload_t.compute_length.
264 static void compute_length (private_ts_payload_t
*this)
266 iterator_t
*iterator
;
268 size_t length
= TS_PAYLOAD_HEADER_LENGTH
;
269 iterator
= this->traffic_selectors
->create_iterator(this->traffic_selectors
,TRUE
);
270 while (iterator
->has_next(iterator
))
272 payload_t
* current_traffic_selector
;
273 iterator
->current(iterator
,(void **) ¤t_traffic_selector
);
274 length
+= current_traffic_selector
->get_length(current_traffic_selector
);
277 iterator
->destroy(iterator
);
279 this->number_of_traffic_selectors
= ts_count
;
280 this->payload_length
= length
;
286 * Implementation of payload_t.destroy and ts_payload_t.destroy.
288 static void destroy(private_ts_payload_t
*this)
290 while (this->traffic_selectors
->get_count(this->traffic_selectors
) > 0)
292 payload_t
*current_traffic_selector
;
294 this->traffic_selectors
->remove_last(this->traffic_selectors
,(void **) ¤t_traffic_selector
);
296 current_traffic_selector
->destroy(current_traffic_selector
);
299 this->traffic_selectors
->destroy(this->traffic_selectors
);
305 * Described in header
307 ts_payload_t
*ts_payload_create(bool is_initiator
)
309 private_ts_payload_t
*this = malloc_thing(private_ts_payload_t
);
311 /* interface functions */
312 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
313 this->public.payload_interface
.get_encoding_rules
= (void (*) (payload_t
*, encoding_rule_t
**, size_t *) ) get_encoding_rules
;
314 this->public.payload_interface
.get_length
= (size_t (*) (payload_t
*)) get_length
;
315 this->public.payload_interface
.get_next_type
= (payload_type_t (*) (payload_t
*)) get_next_type
;
316 this->public.payload_interface
.set_next_type
= (void (*) (payload_t
*,payload_type_t
)) set_next_type
;
317 this->public.payload_interface
.get_type
= (payload_type_t (*) (payload_t
*)) get_payload_type
;
318 this->public.payload_interface
.destroy
= (void (*) (payload_t
*))destroy
;
320 /* public functions */
321 this->public.destroy
= (void (*) (ts_payload_t
*)) destroy
;
322 this->public.get_initiator
= (bool (*) (ts_payload_t
*)) get_initiator
;
323 this->public.set_initiator
= (void (*) (ts_payload_t
*,bool)) set_initiator
;
324 this->public.add_traffic_selector_substructure
= (void (*) (ts_payload_t
*,traffic_selector_substructure_t
*)) add_traffic_selector_substructure
;
325 this->public.create_traffic_selector_substructure_iterator
= (iterator_t
* (*) (ts_payload_t
*,bool)) create_traffic_selector_substructure_iterator
;
326 this->public.get_traffic_selectors
= (linked_list_t
*(*) (ts_payload_t
*)) get_traffic_selectors
;
328 /* private functions */
329 this->compute_length
= compute_length
;
331 /* private variables */
332 this->critical
= FALSE
;
333 this->next_payload
= NO_PAYLOAD
;
334 this->payload_length
=TS_PAYLOAD_HEADER_LENGTH
;
335 this->is_initiator
= is_initiator
;
336 this->number_of_traffic_selectors
= 0;
337 this->traffic_selectors
= linked_list_create();
339 return &(this->public);
343 * Described in header
345 ts_payload_t
*ts_payload_create_from_traffic_selectors(bool is_initiator
, linked_list_t
*traffic_selectors
)
347 iterator_t
*iterator
;
348 traffic_selector_t
*ts
;
349 traffic_selector_substructure_t
*ts_substructure
;
350 private_ts_payload_t
*this;
352 this = (private_ts_payload_t
*)ts_payload_create(is_initiator
);
354 iterator
= traffic_selectors
->create_iterator(traffic_selectors
, TRUE
);
355 while (iterator
->has_next(iterator
))
357 iterator
->current(iterator
, (void**)&ts
);
358 ts_substructure
= traffic_selector_substructure_create_from_traffic_selector(ts
);
359 this->public.add_traffic_selector_substructure(&(this->public), ts_substructure
);
361 iterator
->destroy(iterator
);
363 return &(this->public);