channel locking: Add locking for channel snapshot creation
[asterisk/asterisk.git] / include / asterisk / aoc.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * David Vossel <dvossel@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Generic Advice of Charge encode and decode routines
22  *
23  * \author David Vossel <dvossel@digium.com>
24  */
25
26 #ifndef _AST_AOC_H_
27 #define _AST_AOC_H_
28
29 #include "asterisk/channel.h"
30
31 #define AOC_CURRENCY_NAME_SIZE (10 + 1)
32
33 /*! \brief Defines the currency multiplier for an aoc message. */
34 enum ast_aoc_currency_multiplier {
35         AST_AOC_MULT_ONETHOUSANDTH = 1,
36         AST_AOC_MULT_ONEHUNDREDTH,
37         AST_AOC_MULT_ONETENTH,
38         AST_AOC_MULT_ONE,
39         AST_AOC_MULT_TEN,
40         AST_AOC_MULT_HUNDRED,
41         AST_AOC_MULT_THOUSAND,
42         AST_AOC_MULT_NUM_ENTRIES, /* must remain the last item in enum, this is not a valid type */
43 };
44
45 /*!
46  * \brief Defines the billing id options for an aoc message.
47  * \note  AOC-D is limited to NORMAL, REVERSE_CHARGE, and CREDIT_CARD.
48  */
49 enum ast_aoc_billing_id {
50         AST_AOC_BILLING_NA = 0,
51         AST_AOC_BILLING_NORMAL,
52         AST_AOC_BILLING_REVERSE_CHARGE,
53         AST_AOC_BILLING_CREDIT_CARD,
54         AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL,
55         AST_AOC_BILLING_CALL_FWD_BUSY,
56         AST_AOC_BILLING_CALL_FWD_NO_REPLY,
57         AST_AOC_BILLING_CALL_DEFLECTION,
58         AST_AOC_BILLING_CALL_TRANSFER,
59         AST_AOC_BILLING_NUM_ENTRIES /* must remain the last item in enum, not a valid billing id */
60 };
61
62 enum ast_aoc_type {
63         AST_AOC_REQUEST = 0,
64         AST_AOC_S,
65         AST_AOC_D,
66         AST_AOC_E, /* aoc-e must remain the last item in this enum */
67 };
68
69 enum ast_aoc_charge_type {
70         AST_AOC_CHARGE_NA = 0,
71         AST_AOC_CHARGE_FREE,
72         AST_AOC_CHARGE_CURRENCY,
73         AST_AOC_CHARGE_UNIT, /* unit must remain the last item in enum */
74 };
75
76 enum ast_aoc_request {
77         AST_AOC_REQUEST_S = (1 << 0),
78         AST_AOC_REQUEST_D = (1 << 1),
79         AST_AOC_REQUEST_E = (1 << 2),
80 };
81
82 enum ast_aoc_total_type {
83         AST_AOC_TOTAL = 0,
84         AST_AOC_SUBTOTAL = 1,
85 };
86
87 enum ast_aoc_time_scale {
88         AST_AOC_TIME_SCALE_HUNDREDTH_SECOND,
89         AST_AOC_TIME_SCALE_TENTH_SECOND,
90         AST_AOC_TIME_SCALE_SECOND,
91         AST_AOC_TIME_SCALE_TEN_SECOND,
92         AST_AOC_TIME_SCALE_MINUTE,
93         AST_AOC_TIME_SCALE_HOUR,
94         AST_AOC_TIME_SCALE_DAY,
95 };
96
97 struct ast_aoc_time {
98         /*! LengthOfTimeUnit (Not valid if length is zero.) */
99         uint32_t length;
100         uint16_t scale;
101 };
102
103 struct ast_aoc_duration_rate {
104         uint32_t amount;
105         uint32_t time;
106         /*! Not present if the granularity time is zero. */
107         uint32_t granularity_time;
108
109         uint16_t multiplier;
110         uint16_t time_scale;
111         uint16_t granularity_time_scale;
112
113         /*! Name of currency involved.  Null terminated. */
114         char currency_name[AOC_CURRENCY_NAME_SIZE];
115
116         /*!
117          * \brief Charging interval type
118          * \details
119          * continuousCharging(0),
120          * stepFunction(1)
121          */
122         uint8_t charging_type;
123 };
124
125 enum ast_aoc_volume_unit {
126         AST_AOC_VOLUME_UNIT_OCTET,
127         AST_AOC_VOLUME_UNIT_SEGMENT,
128         AST_AOC_VOLUME_UNIT_MESSAGE,
129 };
130
131 struct ast_aoc_volume_rate {
132         uint32_t amount;
133         uint16_t multiplier;
134         uint16_t volume_unit;
135         char currency_name[AOC_CURRENCY_NAME_SIZE];
136 };
137
138 struct ast_aoc_flat_rate {
139         uint32_t amount;
140         uint16_t multiplier;
141         /*! Name of currency involved.  Null terminated. */
142         char currency_name[AOC_CURRENCY_NAME_SIZE];
143 };
144
145 enum ast_aoc_s_charged_item {
146         AST_AOC_CHARGED_ITEM_NA,
147         AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT,
148         AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION,
149         AST_AOC_CHARGED_ITEM_CALL_ATTEMPT,
150         AST_AOC_CHARGED_ITEM_CALL_SETUP,
151         AST_AOC_CHARGED_ITEM_USER_USER_INFO,
152         AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE,
153 };
154
155 enum ast_aoc_s_rate_type {
156         AST_AOC_RATE_TYPE_NA,
157         AST_AOC_RATE_TYPE_FREE,
158         AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING,
159         AST_AOC_RATE_TYPE_DURATION,
160         AST_AOC_RATE_TYPE_FLAT,
161         AST_AOC_RATE_TYPE_VOLUME,
162         AST_AOC_RATE_TYPE_SPECIAL_CODE,
163 };
164
165 struct ast_aoc_s_entry {
166         uint16_t charged_item;
167         uint16_t rate_type;
168
169         /*! \brief Charge rate being applied. */
170         union {
171                 struct ast_aoc_duration_rate duration;
172                 struct ast_aoc_flat_rate flat;
173                 struct ast_aoc_volume_rate volume;
174                 uint16_t special_code; /* 1...10 */
175         } rate;
176 } __attribute__((packed));
177
178 struct ast_aoc_unit_entry {
179         char valid_amount;
180         unsigned int amount;
181         char valid_type;
182         unsigned int type; /* 1 - 16 by ETSI standard */
183 };
184
185 enum AST_AOC_CHARGING_ASSOCIATION {
186         AST_AOC_CHARGING_ASSOCIATION_NA,
187         AST_AOC_CHARGING_ASSOCIATION_NUMBER,
188         AST_AOC_CHARGING_ASSOCIATION_ID,
189 };
190 struct ast_aoc_charging_association_number {
191         uint8_t plan;
192         char number[32];
193 } __attribute__((packed));
194 struct ast_aoc_charging_association {
195         union {
196                 int32_t id;
197                 struct ast_aoc_charging_association_number number;
198         } charge;
199         /*! \see enum AST_AOC_CHARGING_ASSOCIATION */
200         uint8_t charging_type;
201 } __attribute__((packed));
202
203 /*! \brief AOC Payload Header. Holds all the encoded AOC data to pass on the wire */
204 struct ast_aoc_encoded;
205
206 /*! \brief Decoded AOC data. This value is used to set all the values in an AOC message before encoding.*/
207 struct ast_aoc_decoded;
208
209 /*!
210  * \brief creates a ast_aoc_decode object of a specific message type
211  * \since 1.8
212  *
213  * \param msg_type AOC-D, AOC-E, or AOC Request
214  * \param charge_type this is ignored if message type is not AOC-D or AOC-E.
215  * \param requests flags.  This defines the types of AOC requested. This
216  *        field should only be set when the message type is AOC Request,
217  *        the value is ignored otherwise.
218  *
219  * \retval heap allocated ast_aoc_decoded object ptr on success
220  * \retval NULL failure
221  */
222 struct ast_aoc_decoded *ast_aoc_create(const enum ast_aoc_type msg_type,
223                 const enum ast_aoc_charge_type charge_type,
224                 const enum ast_aoc_request requests);
225
226
227 /*! \brief free an ast_aoc_decoded object */
228 void *ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded);
229
230 /*! \brief free an ast_aoc_encoded object */
231 void *ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded);
232
233 /*!
234  * \brief decodes an encoded aoc payload.
235  * \since 1.8
236  *
237  * \param encoded the encoded payload to decode.
238  * \param size total size of encoded payload
239  * \param chan ast channel, Optional for DEBUG output purposes
240  *
241  * \retval heap allocated ast_aoc_decoded object ptr on success
242  * \retval NULL failure
243  */
244 struct ast_aoc_decoded *ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan);
245
246 /*!
247  * \brief encodes a decoded aoc structure so it can be passed on the wire
248  * \since 1.8
249  *
250  * \param decoded the decoded struct to be encoded
251  * \param out_size output parameter representing size of encoded data
252  * \param chan ast channel, Optional for DEBUG output purposes
253  *
254  * \retval pointer to encoded data
255  * \retval NULL failure
256  */
257 struct ast_aoc_encoded *ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan);
258
259 /*!
260  * \brief Sets the type of total for a AOC-D message
261  * \since 1.8
262  *
263  * \param decoded ast_aoc_decoded struct to set values on
264  * \param type total type: TOTAL or SUBTOTAL
265  *
266  * \note If this value is not set, the default for the message is TOTAL
267  *
268  * \retval 0 success
269  */
270 int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type);
271
272 /*!
273  * \brief Sets the currency values for a AOC-D or AOC-E message
274  * \since 1.8
275  *
276  * \param decoded ast_aoc_decoded struct to set values on
277  * \param amount currency amount REQUIRED
278  * \param multiplier currency multiplier REQUIRED, 0 or undefined value defaults to AST_AOC_MULT_ONE.
279  * \param name currency name OPTIONAL
280  *
281  * \retval 0 success
282  */
283 int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded,
284                 const unsigned int amount,
285                 const enum ast_aoc_currency_multiplier multiplier,
286                 const char *name);
287
288 /*!
289  * \brief Adds a unit entry into the list of units
290  * \since 1.8
291  *
292  * \param decoded ast_aoc_decoded struct to set values on
293  * \param amount_is_present set this if the number of units is actually present.
294  * \param amount number of units
295  * \param type_is_present set this if the type value is present
296  * \param type unit type
297  *
298  * \note If neither the amount nor the type is present, the entry will
299  * not be added.
300  *
301  * \retval 0 success
302  */
303 int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded,
304                 const unsigned int amount_is_present,
305                 const unsigned int amount,
306                 const unsigned int type_is_present,
307                 const unsigned int type);
308
309 /*!
310  * \brief set the billing id for a AOC-D or AST_AOC_E message
311  * \since 1.8
312  *
313  * \param decoded ast_aoc_decoded struct to set values on
314  * \param id billing id
315  *
316  * \retval 0 success
317  */
318 int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id);
319
320 /*!
321  * \brief set the charging association id for an AST_AOC_E message
322  * \since 1.8
323  *
324  * \param decoded ast_aoc_decoded struct to set values on
325  * \param id charging association identifier
326  *
327  * \note If the association number was set, this will override that value. Only the id OR the
328  *       number can be set at a time, not both.
329  *
330  * \retval 0 success
331  */
332 int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id);
333
334 /*!
335  * \brief set the charging accociation number for an AOC-E message
336  * \since 1.8
337  *
338  * \param decoded ast_aoc_decoded struct to set values on
339  * \param num charging association number
340  * \param plan charging association number plan and type-of-number fields
341  *
342  * \note If the association id was set, this will override that value. Only the id OR the
343  *       number can be set at a time, not both.
344  *
345  * \retval 0 success
346  */
347 int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan);
348
349 /*!
350  * \brief Mark the AST_AOC_REQUEST message as a termination request.
351  * \since 1.8
352  *
353  * \param decoded ast_aoc_decoded struct to set values on
354  *
355  * \note A termination request indicates that the call has terminated,
356  * but that the other side is waiting for a short period of time before
357  * hanging up so it can get the final AOC-E message.
358  *
359  * \retval 0 success
360  * \retval -1 failure
361  */
362 int ast_aoc_set_termination_request(struct ast_aoc_decoded *decoded);
363
364 /*!
365  * \brief Add AOC-S duration rate entry
366  * \since 1.8
367  *
368  * \param decoded aoc decoded object to add entry to
369  * \param charged_item ast_aoc_s_charged_item
370  * \param amount currency amount
371  * \param multiplier currency multiplier
372  * \param currency_name truncated after 10 characters
373  * \param time
374  * \param time_scale from ast_aoc_time_scale enum
375  * \param granularity_time (optional, set to 0 if not present);
376  * \param granularity_time_scale (optional, set to 0 if not present);
377  * \param step_function  set to 1 if this is to use a step function, 0 if continuious
378  *
379  * \retval 0 success
380  * \retval -1 failure
381  */
382 int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded,
383         enum ast_aoc_s_charged_item charged_item,
384         unsigned int amount,
385         enum ast_aoc_currency_multiplier multiplier,
386         const char *currency_name,
387         unsigned long time,
388         enum ast_aoc_time_scale time_scale,
389         unsigned long granularity_time,
390         enum ast_aoc_time_scale granularity_time_scale,
391         int step_function);
392
393 /*!
394  * \brief Add AOC-S flat rate entry
395  * \since 1.8
396  *
397  * \param decoded aoc decoded object to add entry to
398  * \param charged_item ast_aoc_s_charged_item
399  * \param amount currency amount
400  * \param multiplier currency multiplier
401  * \param currency_name truncated after 10 characters
402  *
403  * \retval 0 success
404  * \retval -1 failure
405  */
406 int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded,
407         enum ast_aoc_s_charged_item charged_item,
408         unsigned int amount,
409         enum ast_aoc_currency_multiplier multiplier,
410         const char *currency_name);
411
412 /*!
413  * \brief Add AOC-S volume rate entry
414  * \since 1.8
415  *
416  * \param decoded aoc decoded object to add entry to
417  * \param charged_item ast_aoc_s_charged_item
418  * \param volume_unit from ast_aoc_volume_unit enum
419  * \param amount currency amount
420  * \param multiplier currency multiplier
421  * \param currency_name truncated after 10 characters
422  *
423  * \retval 0 success
424  * \retval -1 failure
425  */
426 int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded,
427         enum ast_aoc_s_charged_item charged_item,
428         enum ast_aoc_volume_unit volume_unit,
429         unsigned int amount,
430         enum ast_aoc_currency_multiplier multiplier,
431         const char *currency_name);
432
433 /*!
434  * \brief Add AOC-S special rate entry
435  * \since 1.8
436  *
437  * \param decoded aoc decoded object to add entry to
438  * \param charged_item ast_aoc_s_charged_item
439  * \param code special charging code
440  *
441  * \retval 0 success
442  * \retval -1 failure
443  */
444 int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded,
445         enum ast_aoc_s_charged_item charged_item,
446         unsigned int code);
447
448 /*!
449  * \brief Add AOC-S indicating charge item is free
450  * \since 1.8
451  *
452  * \param decoded aoc decoded object to add entry to
453  * \param charged_item ast_aoc_s_charged_item
454  * \param from_beginning TRUE if the rate is free from beginning.
455  *
456  * \retval 0 success
457  * \retval -1 failure
458  */
459 int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded,
460         enum ast_aoc_s_charged_item charged_item, int from_beginning);
461
462 /*!
463  * \brief Add AOC-S entry indicating charge item is not available
464  * \since 1.8
465  *
466  * \param decoded aoc decoded object to add entry to
467  * \param charged_item ast_aoc_s_charged_item
468  *
469  * \retval 0 success
470  * \retval -1 failure
471  */
472 int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded,
473         enum ast_aoc_s_charged_item charged_item);
474
475 /*!
476  * \brief Add AOC-S special arrangement entry
477  * \since 1.8
478  *
479  * \param decoded aoc decoded object to add entry to
480  * \param code special arrangement code
481  *
482  * \retval 0 success
483  * \retval -1 failure
484  */
485 int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded,
486         unsigned int code);
487
488 /*!
489  * \brief Convert decoded aoc msg to string representation
490  * \since 1.8
491  *
492  * \param decoded ast_aoc_decoded struct to convert to string
493  * \param msg dynamic heap allocated ast_str object to store string representation in
494  *
495  * \retval 0 success
496  * \retval -1 failure
497  */
498 int ast_aoc_decoded2str(const struct ast_aoc_decoded *decoded, struct ast_str **msg);
499
500 /*!
501  * \brief generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg
502  * \pre chan is locked
503  */
504 int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan);
505
506 /*! \brief get the message type, AOC-D, AOC-E, or AOC Request */
507 enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded);
508
509 /*! \brief get the charging type for an AOC-D or AOC-E message */
510 enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded);
511
512 /*! \brief get the types of AOC requested for when message type is AOC Request */
513 enum ast_aoc_request ast_aoc_get_request(struct ast_aoc_decoded *decoded);
514
515 /*! \brief get the type of total for a AOC-D message */
516 enum ast_aoc_total_type ast_aoc_get_total_type(struct ast_aoc_decoded *decoded);
517
518 /*! \brief get the currency amount for AOC-D and AOC-E messages*/
519 unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded);
520
521 /*! \brief get the number rates associated with an AOC-S message */
522 unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded);
523
524 /*!
525  * \brief get a specific AOC-S rate entry.
526  * \since 1.8
527  *
528  * \note This can be used in conjunction with ast_aoc_s_get_count to create
529  *       a unit entry iterator.
530  */
531 const struct ast_aoc_s_entry *ast_aoc_s_get_rate_info(struct ast_aoc_decoded *decoded, unsigned int entry_number);
532
533 /*! \brief get the number of unit entries for AOC-D and AOC-E messages*/
534 unsigned int ast_aoc_get_unit_count(struct ast_aoc_decoded *decoded);
535
536 /*!
537  * \brief get a specific unit entry.
538  * \since 1.8
539  *
540  * \note This can be used in conjunction with ast_aoc_get_unit_count to create
541  *       a unit entry iterator.
542  */
543 const struct ast_aoc_unit_entry *ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number);
544
545 /*! \brief get the currency multiplier for AOC-D and AOC-E messages */
546 enum ast_aoc_currency_multiplier ast_aoc_get_currency_multiplier(struct ast_aoc_decoded *decoded);
547
548 /*! \brief get the currency multiplier for AOC-D and AOC-E messages in decimal format */
549 const char *ast_aoc_get_currency_multiplier_decimal(struct ast_aoc_decoded *decoded);
550
551 /*! \brief get the currency name for AOC-D and AOC-E messages*/
552 const char *ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded);
553
554 /*! \brief get the billing id for AOC-D and AOC-E messages*/
555 enum ast_aoc_billing_id ast_aoc_get_billing_id(struct ast_aoc_decoded *decoded);
556
557 /*! \brief get the charging association info for AOC-E messages*/
558 const struct ast_aoc_charging_association *ast_aoc_get_association_info(struct ast_aoc_decoded *decoded);
559
560 /*!
561  * \brief get whether or not the AST_AOC_REQUEST message as a termination request.
562  * \since 1.8
563  *
564  * \note a termination request indicates that the call has terminated,
565  *       but that the other side is waiting for a short period of time
566  *       before hanging up so it can get the final AOC-E message.
567  *
568  * \param decoded ast_aoc_decoded struct to get values on
569  *
570  * \retval 0 not a termination request
571  * \retval 1 is a termination request
572  */
573 int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded);
574
575 /*!
576  * \brief test aoc encode decode routines.
577  * \since 1.8
578  *
579  * \note  This function verifies that a decoded message matches itself after
580  *        the encode decode routine.
581  */
582 int ast_aoc_test_encode_decode_match(struct ast_aoc_decoded *decoded);
583
584 /*! \brief enable aoc cli options */
585 int ast_aoc_cli_init(void);
586
587 #endif  /* _AST_AOC_H_ */