aboutsummaryrefslogtreecommitdiffstats
path: root/include/asterisk/aoc.h
blob: 727362c1fb88370fd5b249977695607f503f9980 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
/*
 * Asterisk -- An open source telephony toolkit.
 *
 * Copyright (C) 2010, Digium, Inc.
 *
 * David Vossel <dvossel@digium.com>
 *
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2. See the LICENSE file
 * at the top of the source tree.
 */

/*!
 * \file
 * \brief Generic Advice of Charge encode and decode routines
 *
 * \author David Vossel <dvossel@digium.com>
 */

#ifndef _AST_AOC_H_
#define _AST_AOC_H_

#include "asterisk/channel.h"

#define AOC_CURRENCY_NAME_SIZE (10 + 1)

/*! \brief Defines the currency multiplier for an aoc message. */
enum ast_aoc_currency_multiplier {
	AST_AOC_MULT_ONETHOUSANDTH = 1,
	AST_AOC_MULT_ONEHUNDREDTH,
	AST_AOC_MULT_ONETENTH,
	AST_AOC_MULT_ONE,
	AST_AOC_MULT_TEN,
	AST_AOC_MULT_HUNDRED,
	AST_AOC_MULT_THOUSAND,
	AST_AOC_MULT_NUM_ENTRIES, /* must remain the last item in enum, this is not a valid type */
};

/*!
 * \brief Defines the billing id options for an aoc message.
 * \note  AOC-D is limited to NORMAL, REVERSE_CHARGE, and CREDIT_CARD.
 */
enum ast_aoc_billing_id {
	AST_AOC_BILLING_NA = 0,
	AST_AOC_BILLING_NORMAL,
	AST_AOC_BILLING_REVERSE_CHARGE,
	AST_AOC_BILLING_CREDIT_CARD,
	AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL,
	AST_AOC_BILLING_CALL_FWD_BUSY,
	AST_AOC_BILLING_CALL_FWD_NO_REPLY,
	AST_AOC_BILLING_CALL_DEFLECTION,
	AST_AOC_BILLING_CALL_TRANSFER,
	AST_AOC_BILLING_NUM_ENTRIES /* must remain the last item in enum, not a valid billing id */
};

enum ast_aoc_type {
	AST_AOC_REQUEST = 0,
	AST_AOC_S,
	AST_AOC_D,
	AST_AOC_E, /* aoc-e must remain the last item in this enum */
};

enum ast_aoc_charge_type {
	AST_AOC_CHARGE_NA = 0,
	AST_AOC_CHARGE_FREE,
	AST_AOC_CHARGE_CURRENCY,
	AST_AOC_CHARGE_UNIT, /* unit must remain the last item in enum */
};

enum ast_aoc_request {
	AST_AOC_REQUEST_S = (1 << 0),
	AST_AOC_REQUEST_D = (1 << 1),
	AST_AOC_REQUEST_E = (1 << 2),
};

enum ast_aoc_total_type {
	AST_AOC_TOTAL = 0,
	AST_AOC_SUBTOTAL = 1,
};

enum ast_aoc_time_scale {
	AST_AOC_TIME_SCALE_HUNDREDTH_SECOND,
	AST_AOC_TIME_SCALE_TENTH_SECOND,
	AST_AOC_TIME_SCALE_SECOND,
	AST_AOC_TIME_SCALE_TEN_SECOND,
	AST_AOC_TIME_SCALE_MINUTE,
	AST_AOC_TIME_SCALE_HOUR,
	AST_AOC_TIME_SCALE_DAY,
};

struct ast_aoc_time {
	/*! LengthOfTimeUnit (Not valid if length is zero.) */
	uint32_t length;
	uint16_t scale;
};

struct ast_aoc_duration_rate {
	uint32_t amount;
	uint32_t time;
	/*! Not present if the granularity time is zero. */
	uint32_t granularity_time;

	uint16_t multiplier;
	uint16_t time_scale;
	uint16_t granularity_time_scale;

	/*! Name of currency involved.  Null terminated. */
	char currency_name[AOC_CURRENCY_NAME_SIZE];

	/*!
	 * \brief Charging interval type
	 * \details
	 * continuousCharging(0),
	 * stepFunction(1)
	 */
	uint8_t charging_type;
};

enum ast_aoc_volume_unit {
	AST_AOC_VOLUME_UNIT_OCTET,
	AST_AOC_VOLUME_UNIT_SEGMENT,
	AST_AOC_VOLUME_UNIT_MESSAGE,
};

struct ast_aoc_volume_rate {
	uint32_t amount;
	uint16_t multiplier;
	uint16_t volume_unit;
	char currency_name[AOC_CURRENCY_NAME_SIZE];
};

struct ast_aoc_flat_rate {
	uint32_t amount;
	uint16_t multiplier;
	/*! Name of currency involved.  Null terminated. */
	char currency_name[AOC_CURRENCY_NAME_SIZE];
};

enum ast_aoc_s_charged_item {
	AST_AOC_CHARGED_ITEM_NA,
	AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT,
	AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION,
	AST_AOC_CHARGED_ITEM_CALL_ATTEMPT,
	AST_AOC_CHARGED_ITEM_CALL_SETUP,
	AST_AOC_CHARGED_ITEM_USER_USER_INFO,
	AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE,
};

enum ast_aoc_s_rate_type {
	AST_AOC_RATE_TYPE_NA,
	AST_AOC_RATE_TYPE_FREE,
	AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING,
	AST_AOC_RATE_TYPE_DURATION,
	AST_AOC_RATE_TYPE_FLAT,
	AST_AOC_RATE_TYPE_VOLUME,
	AST_AOC_RATE_TYPE_SPECIAL_CODE,
};

struct ast_aoc_s_entry {
	uint16_t charged_item;
	uint16_t rate_type;

	/*! \brief Charge rate being applied. */
	union {
		struct ast_aoc_duration_rate duration;
		struct ast_aoc_flat_rate flat;
		struct ast_aoc_volume_rate volume;
		uint16_t special_code; /* 1...10 */
	} rate;
} __attribute__((packed));

struct ast_aoc_unit_entry {
	char valid_amount;
	unsigned int amount;
	char valid_type;
	unsigned int type; /* 1 - 16 by ETSI standard */
};

enum AST_AOC_CHARGING_ASSOCIATION {
	AST_AOC_CHARGING_ASSOCIATION_NA,
	AST_AOC_CHARGING_ASSOCIATION_NUMBER,
	AST_AOC_CHARGING_ASSOCIATION_ID,
};
struct ast_aoc_charging_association_number {
	uint8_t plan;
	char number[32];
} __attribute__((packed));
struct ast_aoc_charging_association {
	union {
		int32_t id;
		struct ast_aoc_charging_association_number number;
	} charge;
	/*! \see enum AST_AOC_CHARGING_ASSOCIATION */
	uint8_t charging_type;
} __attribute__((packed));

/*! \brief AOC Payload Header. Holds all the encoded AOC data to pass on the wire */
struct ast_aoc_encoded;

/*! \brief Decoded AOC data. This value is used to set all the values in an AOC message before encoding.*/
struct ast_aoc_decoded;

/*!
 * \brief creates a ast_aoc_decode object of a specific message type
 * \since 1.8
 *
 * \param msg_type AOC-D, AOC-E, or AOC Request
 * \param charge_type this is ignored if message type is not AOC-D or AOC-E.
 * \param requests flags.  This defines the types of AOC requested. This
 *        field should only be set when the message type is AOC Request,
 *        the value is ignored otherwise.
 *
 * \retval heap allocated ast_aoc_decoded object ptr on success
 * \retval NULL failure
 */
struct ast_aoc_decoded *ast_aoc_create(const enum ast_aoc_type msg_type,
		const enum ast_aoc_charge_type charge_type,
		const enum ast_aoc_request requests);


/*! \brief free an ast_aoc_decoded object */
void *ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded);

/*! \brief free an ast_aoc_encoded object */
void *ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded);

/*!
 * \brief decodes an encoded aoc payload.
 * \since 1.8
 *
 * \param encoded the encoded payload to decode.
 * \param size total size of encoded payload
 * \param chan ast channel, Optional for DEBUG output purposes
 *
 * \retval heap allocated ast_aoc_decoded object ptr on success
 * \retval NULL failure
 */
struct ast_aoc_decoded *ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan);

/*!
 * \brief encodes a decoded aoc structure so it can be passed on the wire
 * \since 1.8
 *
 * \param decoded the decoded struct to be encoded
 * \param out_size output parameter representing size of encoded data
 * \param chan ast channel, Optional for DEBUG output purposes
 *
 * \retval pointer to encoded data
 * \retval NULL failure
 */
struct ast_aoc_encoded *ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan);

/*!
 * \brief Sets the type of total for a AOC-D message
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 * \param type total type: TOTAL or SUBTOTAL
 *
 * \note If this value is not set, the default for the message is TOTAL
 *
 * \retval 0 success
 */
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type);

/*!
 * \brief Sets the currency values for a AOC-D or AOC-E message
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 * \param amount currency amount REQUIRED
 * \param multiplier currency multiplier REQUIRED, 0 or undefined value defaults to AST_AOC_MULT_ONE.
 * \param name currency name OPTIONAL
 *
 * \retval 0 success
 */
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded,
		const unsigned int amount,
		const enum ast_aoc_currency_multiplier multiplier,
		const char *name);

/*!
 * \brief Adds a unit entry into the list of units
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 * \param amount_is_present set this if the number of units is actually present.
 * \param amount number of units
 * \param type_is_present set this if the type value is present
 * \param type unit type
 *
 * \note If neither the amount nor the type is present, the entry will
 * not be added.
 *
 * \retval 0 success
 */
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded,
		const unsigned int amount_is_present,
		const unsigned int amount,
		const unsigned int type_is_present,
		const unsigned int type);

/*!
 * \brief set the billing id for a AOC-D or AST_AOC_E message
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 * \param id billing id
 *
 * \retval 0 success
 */
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id);

/*!
 * \brief set the charging association id for an AST_AOC_E message
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 * \param id charging association identifier
 *
 * \note If the association number was set, this will override that value. Only the id OR the
 *       number can be set at a time, not both.
 *
 * \retval 0 success
 */
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id);

/*!
 * \brief set the charging accociation number for an AOC-E message
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 * \param num charging association number
 * \param plan charging association number plan and type-of-number fields
 *
 * \note If the association id was set, this will override that value. Only the id OR the
 *       number can be set at a time, not both.
 *
 * \retval 0 success
 */
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan);

/*!
 * \brief Mark the AST_AOC_REQUEST message as a termination request.
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to set values on
 *
 * \note A termination request indicates that the call has terminated,
 * but that the other side is waiting for a short period of time before
 * hanging up so it can get the final AOC-E message.
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_set_termination_request(struct ast_aoc_decoded *decoded);

/*!
 * \brief Add AOC-S duration rate entry
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param charged_item ast_aoc_s_charged_item
 * \param amount currency amount
 * \param multiplier currency multiplier
 * \param currency_name truncated after 10 characters
 * \param time
 * \param time_scale from ast_aoc_time_scale enum
 * \param granularity_time (optional, set to 0 if not present);
 * \param granularity_time_scale (optional, set to 0 if not present);
 * \param step_function  set to 1 if this is to use a step function, 0 if continuious
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded,
	enum ast_aoc_s_charged_item charged_item,
	unsigned int amount,
	enum ast_aoc_currency_multiplier multiplier,
	const char *currency_name,
	unsigned long time,
	enum ast_aoc_time_scale time_scale,
	unsigned long granularity_time,
	enum ast_aoc_time_scale granularity_time_scale,
	int step_function);

/*!
 * \brief Add AOC-S flat rate entry
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param charged_item ast_aoc_s_charged_item
 * \param amount currency amount
 * \param multiplier currency multiplier
 * \param currency_name truncated after 10 characters
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded,
	enum ast_aoc_s_charged_item charged_item,
	unsigned int amount,
	enum ast_aoc_currency_multiplier multiplier,
	const char *currency_name);

/*!
 * \brief Add AOC-S volume rate entry
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param charged_item ast_aoc_s_charged_item
 * \param volume_unit from ast_aoc_volume_unit enum
 * \param amount currency amount
 * \param multiplier currency multiplier
 * \param currency_name truncated after 10 characters
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded,
	enum ast_aoc_s_charged_item charged_item,
	enum ast_aoc_volume_unit volume_unit,
	unsigned int amount,
	enum ast_aoc_currency_multiplier multiplier,
	const char *currency_name);

/*!
 * \brief Add AOC-S special rate entry
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param charged_item ast_aoc_s_charged_item
 * \param code special charging code
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded,
	enum ast_aoc_s_charged_item charged_item,
	unsigned int code);

/*!
 * \brief Add AOC-S indicating charge item is free
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param charged_item ast_aoc_s_charged_item
 * \param from_beginning TRUE if the rate is free from beginning.
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded,
	enum ast_aoc_s_charged_item charged_item, int from_beginning);

/*!
 * \brief Add AOC-S entry indicating charge item is not available
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param charged_item ast_aoc_s_charged_item
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded,
	enum ast_aoc_s_charged_item charged_item);

/*!
 * \brief Add AOC-S special arrangement entry
 * \since 1.8
 *
 * \param decoded aoc decoded object to add entry to
 * \param code special arrangement code
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded,
	unsigned int code);

/*!
 * \brief Convert decoded aoc msg to string representation
 * \since 1.8
 *
 * \param decoded ast_aoc_decoded struct to convert to string
 * \param msg dynamic heap allocated ast_str object to store string representation in
 *
 * \retval 0 success
 * \retval -1 failure
 */
int ast_aoc_decoded2str(const struct ast_aoc_decoded *decoded, struct ast_str **msg);

/*! \brief generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg */
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan);

/*! \brief get the message type, AOC-D, AOC-E, or AOC Request */
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded);

/*! \brief get the charging type for an AOC-D or AOC-E message */
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded);

/*! \brief get the types of AOC requested for when message type is AOC Request */
enum ast_aoc_request ast_aoc_get_request(struct ast_aoc_decoded *decoded);

/*! \brief get the type of total for a AOC-D message */
enum ast_aoc_total_type ast_aoc_get_total_type(struct ast_aoc_decoded *decoded);

/*! \brief get the currency amount for AOC-D and AOC-E messages*/
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded);

/*! \brief get the number rates associated with an AOC-S message */
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded);

/*!
 * \brief get a specific AOC-S rate entry.
 * \since 1.8
 *
 * \note This can be used in conjunction with ast_aoc_s_get_count to create
 *       a unit entry iterator.
 */
const struct ast_aoc_s_entry *ast_aoc_s_get_rate_info(struct ast_aoc_decoded *decoded, unsigned int entry_number);

/*! \brief get the number of unit entries for AOC-D and AOC-E messages*/
unsigned int ast_aoc_get_unit_count(struct ast_aoc_decoded *decoded);

/*!
 * \brief get a specific unit entry.
 * \since 1.8
 *
 * \note This can be used in conjunction with ast_aoc_get_unit_count to create
 *       a unit entry iterator.
 */
const struct ast_aoc_unit_entry *ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number);

/*! \brief get the currency multiplier for AOC-D and AOC-E messages */
enum ast_aoc_currency_multiplier ast_aoc_get_currency_multiplier(struct ast_aoc_decoded *decoded);

/*! \brief get the currency multiplier for AOC-D and AOC-E messages in decimal format */
const char *ast_aoc_get_currency_multiplier_decimal(struct ast_aoc_decoded *decoded);

/*! \brief get the currency name for AOC-D and AOC-E messages*/
const char *ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded);

/*! \brief get the billing id for AOC-D and AOC-E messages*/
enum ast_aoc_billing_id ast_aoc_get_billing_id(struct ast_aoc_decoded *decoded);

/*! \brief get the charging association info for AOC-E messages*/
const struct ast_aoc_charging_association *ast_aoc_get_association_info(struct ast_aoc_decoded *decoded);

/*!
 * \brief get whether or not the AST_AOC_REQUEST message as a termination request.
 * \since 1.8
 *
 * \note a termination request indicates that the call has terminated,
 *       but that the other side is waiting for a short period of time
 *       before hanging up so it can get the final AOC-E message.
 *
 * \param decoded ast_aoc_decoded struct to get values on
 *
 * \retval 0 not a termination request
 * \retval 1 is a termination request
 */
int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded);

/*!
 * \brief test aoc encode decode routines.
 * \since 1.8
 *
 * \note  This function verifies that a decoded message matches itself after
 *        the encode decode routine.
 */
int ast_aoc_test_encode_decode_match(struct ast_aoc_decoded *decoded);

/*! \brief enable aoc cli options */
int ast_aoc_cli_init(void);

#endif	/* _AST_AOC_H_ */