/usr/include/asterisk/cdr.h is in asterisk-dev 1:13.18.3~dfsg-1ubuntu4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | /*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 1999 - 2005, Digium, Inc.
*
* Mark Spencer <markster@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 Call Detail Record API
*
* \author Mark Spencer <markster@digium.com>
*/
#ifndef _ASTERISK_CDR_H
#define _ASTERISK_CDR_H
#include "asterisk/channel.h"
/*! \file
*
* \since 12
*
* \brief Call Detail Record Engine.
*
* \page CDR Call Detail Record Engine
*
* \par Intro
*
* The Call Detail Record (CDR) engine uses the \ref stasis Stasis Message Bus
* to build records for the channels in Asterisk. As the state of a channel and
* the bridges it participates in changes, notifications are sent over the
* Stasis Message Bus. The CDR engine consumes these notifications and builds
* records that reflect that state. Over the lifetime of a channel, many CDRs
* may be generated for that channel or that involve that channel.
*
* CDRs have a lifecycle that is a subset of the channel that they reflect. A
* single CDR for a channel represents a path of communication between the
* endpoint behind a channel and Asterisk, or between two endpoints. When a
* channel establishes a new path of communication, a new CDR is created for the
* channel. Likewise, when a path of communication is terminated, a CDR is
* finalized. Finally, when a channel is no longer present in Asterisk, all CDRs
* for that channel are dispatched for recording.
*
* Dispatching of CDRs occurs to registered CDR backends. CDR backends register
* through \ref ast_cdr_register and are responsible for taking the produced
* CDRs and storing them in permanent storage.
*
* \par CDR attributes
*
* While a CDR can have many attributes, all CDRs have two parties: a Party A
* and a Party B. The Party A is \em always the channel that owns the CDR. A CDR
* may or may not have a Party B, depending on its state.
*
* For the most part, attributes on a CDR are reflective of those same
* attributes on the channel at the time when the CDR was finalized. Specific
* CDR attributes include:
* \li \c start The time when the CDR was created
* \li \c answer The time when the Party A was answered, or when the path of
* communication between Party A and Party B was established
* \li \c end The time when the CDR was finalized
* \li \c duration \c end - \c start. If \c end is not known, the current time
* is used
* \li \c billsec \c end - \c answer. If \c end is not known, the current time
* is used
* \li \c userfield User set data on some party in the CDR
*
* Note that \c accountcode and \c amaflags are actually properties of a
* channel, not the CDR.
*
* \par CDR States
*
* CDRs go through various states during their lifetime. State transitions occur
* due to messages received over the \ref stasis Stasis Message Bus. The
* following describes the possible states a CDR can be in, and how it
* transitions through the states.
*
* \par Single
*
* When a CDR is created, it is put into the Single state. The Single state
* represents a CDR for a channel that has no Party B. CDRs can be unanswered
* or answered while in the Single state.
*
* The following transitions can occur while in the Single state:
* \li If a \ref ast_channel_dial_type indicating a Dial Begin is received, the
* state transitions to Dial
* \li If a \ref ast_channel_snapshot is received indicating that the channel
* has hung up, the state transitions to Finalized
* \li If a \ref ast_bridge_blob_type is received indicating a Bridge Enter, the
* state transitions to Bridge
* \li If a \ref ast_bridge_blob_type message indicating an entrance to a
* holding bridge with a subclass type of "parking" is received, the CDR is
* transitioned to the Parked state.
*
* \par Dial
*
* This state represents a dial that is occurring within Asterisk. The Party A
* can either be the caller for a two party dial, or it can be the dialed party
* if the calling party is Asterisk (that is, an Originated channel). In the
* first case, the Party B is \em always the dialed channel; in the second case,
* the channel is not considered to be a "dialed" channel as it is alone in the
* dialed operation.
*
* While in the Dial state, multiple CDRs can be created for the Party A if a
* parallel dial occurs. Each dialed party receives its own CDR with Party A.
*
* The following transitions can occur while in the Dial state:
* \li If a \ref ast_channel_dial_type indicating a Dial End is received where
* the \ref dial_status is not ANSWER, the state transitions to Finalized
* \li If a \ref ast_channel_snapshot is received indicating that the channel
* has hung up, the state transitions to Finalized
* \li If a \ref ast_channel_dial_type indicating a Dial End is received where
* the \ref dial_status is ANSWER, the state transitions to DialedPending
* \li If a \ref ast_bridge_blob_type is received indicating a Bridge Enter, the
* state transitions to Bridge
*
* \par DialedPending
*
* Technically, after being dialed, a CDR does not have to transition to the
* Bridge state. If the channel being dialed was originated, the channel may
* being executing dialplan. Strangely enough, it is also valid to have both
* Party A and Party B - after a dial - to not be bridged and instead execute
* dialplan. DialedPending handles the state where we figure out if the CDR
* showing the dial needs to move to the Bridge state; if the CDR should show
* that we started executing dialplan; of if we need a new CDR.
*
* The following transition can occur while in the DialedPending state:
* \li If a \ref ast_channel_snapshot is received that indicates that the
* channel has begun executing dialplan, we transition to the Finalized state
* if we have a Party B. Otherwise, we transition to the Single state.
* \li If a \ref ast_bridge_blob_type is received indicating a Bridge Enter, the
* state transitions to Bridge (through the Dial state)
* \li If a \ref ast_bridge_blob_type message indicating an entrance to a
* holding bridge with a subclass type of "parking" is received, the CDR is
* transitioned to the Parked state.
*
* \par Bridge
*
* The Bridge state represents a path of communication between Party A and one
* or more other parties. When a CDR enters into the Bridge state, the following
* occurs:
* \li The CDR attempts to find a Party B. If the CDR has a Party B, it looks
* for that channel in the bridge and updates itself accordingly. If the CDR
* does not yet have a Party B, it attempts to find a channel that can be its
* Party B. If it finds one, it updates itself; otherwise, the CDR is
* temporarily finalized.
* \li Once the CDR has a Party B or it is determined that it cannot have a
* Party B, new CDRs are created for each pairing of channels with the CDR's
* Party A.
*
* As an example, consider the following:
* \li A Dials B - both answer
* \li B joins a bridge. Since no one is in the bridge and it was a dialed
* channel, it cannot have a Party B.
* \li A joins the bridge. Since A's Party B is B, A updates itself with B.
* \li Now say an Originated channel, C, joins the bridge. The bridge becomes
* a multi-party bridge.
* \li C attempts to get a Party B. A cannot be C's Party B, as it was created
* before it. B is a dialed channel and can thus be C's Party B, so C's CDR
* updates its Party B to B.
* \li New CDRs are now generated. A gets a new CDR for A -> C. B is dialed, and
* hence cannot get any CDR.
* \li Now say another Originated channel, D, joins the bridge. Say D has the
* \ref party_a flag set on it, such that it is always the preferred Party A.
* As such, it takes A as its Party B.
* \li New CDRs are generated. D gets new CDRs for D -> B and D -> C.
*
* The following transitions can occur while in the Bridge state:
* \li If a \ref ast_bridge_blob_type message indicating a leave is received,
* the state transitions to the Finalized state.
*
* \par Parked
*
* Parking is technically just another bridge in the Asterisk bridging
* framework. Unlike other bridges, however there are several key distinctions:
* \li With normal bridges, you want to show paths of communication between
* the participants. In parking, however, each participant is independent.
* From the perspective of a CDR, a call in parking should look like a dialplan
* application just executed.
* \li Holding bridges are typically items using in more complex applications,
* and so we usually don't want to show them. However, with Park, there is no
* application execution - often, a channel will be put directly into the
* holding bridge, bypassing the dialplan. This occurs when a call is blind
* transferred to a parking extension.
*
* As such, if a channel enters a bridge and that happens to be a holding bridge
* with a subclass type of "parking", we transition the CDR into the Parked
* state. The parking Stasis message updates the application name and data to
* reflect that the channel is in parking. When this occurs, a special flag is
* set on the CDR that prevents the application name from being updates by
* subsequent channel snapshot updates.
*
* The following transitions can occur while in the Parked state:
* \li If a \ref ast_bridge_blob_type message indicating a leave is received,
* the state transitions to the Finalized state
*
* \par Finalized
*
* Once a CDR enters the finalized state, it is finished. No further updates
* can be made to the party information, and the CDR cannot be changed.
*
* One exception to this occurs during linkedid propagation, in which the CDRs
* linkedids are updated based on who the channel is bridged with. In general,
* however, a finalized CDR is waiting for dispatch to the CDR backends.
*/
/*! \brief CDR engine settings */
enum ast_cdr_settings {
CDR_ENABLED = 1 << 0, /*!< Enable CDRs */
CDR_BATCHMODE = 1 << 1, /*!< Whether or not we should dispatch CDRs in batches */
CDR_UNANSWERED = 1 << 2, /*!< Log unanswered CDRs */
CDR_CONGESTION = 1 << 3, /*!< Treat congestion as if it were a failed call */
CDR_END_BEFORE_H_EXTEN = 1 << 4, /*!< End the CDR before the 'h' extension runs */
CDR_INITIATED_SECONDS = 1 << 5, /*!< Include microseconds into the billing time */
CDR_DEBUG = 1 << 6, /*!< Enables extra debug statements */
};
/*! \brief CDR Batch Mode settings */
enum ast_cdr_batch_mode_settings {
BATCH_MODE_SCHEDULER_ONLY = 1 << 0, /*!< Don't spawn a thread to handle the batches - do it on the scheduler */
BATCH_MODE_SAFE_SHUTDOWN = 1 << 1, /*!< During safe shutdown, submit the batched CDRs */
};
/*!
* \brief CDR manipulation options. Certain function calls will manipulate the
* state of a CDR object based on these flags.
*/
enum ast_cdr_options {
AST_CDR_FLAG_KEEP_VARS = (1 << 0), /*!< Copy variables during the operation */
AST_CDR_FLAG_DISABLE = (1 << 1), /*!< Disable the current CDR */
AST_CDR_FLAG_DISABLE_ALL = (3 << 1), /*!< Disable the CDR and all future CDRs */
AST_CDR_FLAG_PARTY_A = (1 << 3), /*!< Set the channel as party A */
AST_CDR_FLAG_FINALIZE = (1 << 4), /*!< Finalize the current CDRs */
AST_CDR_FLAG_SET_ANSWER = (1 << 5), /*!< If the channel is answered, set the answer time to now */
AST_CDR_FLAG_RESET = (1 << 6), /*!< If set, set the start and answer time to now */
AST_CDR_LOCK_APP = (1 << 7), /*!< Prevent any further changes to the application field/data field for this CDR */
};
/*!
* \brief CDR Flags - Disposition
*/
enum ast_cdr_disposition {
AST_CDR_NOANSWER = 0,
AST_CDR_NULL = (1 << 0),
AST_CDR_FAILED = (1 << 1),
AST_CDR_BUSY = (1 << 2),
AST_CDR_ANSWERED = (1 << 3),
AST_CDR_CONGESTION = (1 << 4),
};
/*! \brief The global options available for CDRs */
struct ast_cdr_config {
struct ast_flags settings; /*!< CDR settings */
struct batch_settings {
unsigned int time; /*!< Time between batches */
unsigned int size; /*!< Size to trigger a batch */
struct ast_flags settings; /*!< Settings for batches */
} batch_settings;
};
/*!
* \brief Responsible for call detail data
*/
struct ast_cdr {
/*! Caller*ID with text */
char clid[AST_MAX_EXTENSION];
/*! Caller*ID number */
char src[AST_MAX_EXTENSION];
/*! Destination extension */
char dst[AST_MAX_EXTENSION];
/*! Destination context */
char dcontext[AST_MAX_EXTENSION];
char channel[AST_MAX_EXTENSION];
/*! Destination channel if appropriate */
char dstchannel[AST_MAX_EXTENSION];
/*! Last application if appropriate */
char lastapp[AST_MAX_EXTENSION];
/*! Last application data */
char lastdata[AST_MAX_EXTENSION];
struct timeval start;
struct timeval answer;
struct timeval end;
/*! Total time in system, in seconds */
long int duration;
/*! Total time call is up, in seconds */
long int billsec;
/*! What happened to the call */
long int disposition;
/*! What flags to use */
long int amaflags;
/*! What account number to use */
char accountcode[AST_MAX_ACCOUNT_CODE];
/*! Account number of the last person we talked to */
char peeraccount[AST_MAX_ACCOUNT_CODE];
/*! flags */
unsigned int flags;
/*! Unique Channel Identifier */
char uniqueid[AST_MAX_UNIQUEID];
/*! Linked group Identifier */
char linkedid[AST_MAX_UNIQUEID];
/*! User field */
char userfield[AST_MAX_USER_FIELD];
/*! Sequence field */
int sequence;
/*! A linked list for variables */
struct varshead varshead;
struct ast_cdr *next;
};
/*!
* \since 12
* \brief Obtain the current CDR configuration
*
* The configuration is a ref counted object. The caller of this function must
* decrement the ref count when finished with the configuration.
*
* \retval NULL on error
* \retval The current CDR configuration
*/
struct ast_cdr_config *ast_cdr_get_config(void);
/*!
* \since 12
* \brief Set the current CDR configuration
*
* \param config The new CDR configuration
*/
void ast_cdr_set_config(struct ast_cdr_config *config);
/*!
* \since 12
* \brief Format a CDR variable from an already posted CDR
*
* \param cdr The dispatched CDR to process
* \param name The name of the variable
* \param ret Pointer to the formatted buffer
* \param workspace A pointer to the buffer to use to format the variable
* \param workspacelen The size of \ref workspace
* \param raw If non-zero and a date/time is extraced, provide epoch seconds. Otherwise format as a date/time stamp
*/
void ast_cdr_format_var(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int raw);
/*!
* \since 12
* \brief Retrieve a CDR variable from a channel's current CDR
*
* \param channel_name The name of the party A channel that the CDR is associated with
* \param name The name of the variable to retrieve
* \param value Buffer to hold the value
* \param length The size of the buffer
*
* \retval 0 on success
* \retval non-zero on failure
*/
int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length);
/*!
* \since 12
* \brief Set a variable on a CDR
*
* \param channel_name The channel to set the variable on
* \param name The name of the variable to set
* \param value The value of the variable to set
*
* \retval 0 on success
* \retval non-zero on failure
*/
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value);
/*!
* \since 12
* \brief Fork a CDR
*
* \param channel_name The name of the channel whose CDR should be forked
* \param options Options to control how the fork occurs.
*
* \retval 0 on success
* \retval -1 on failure
*/
int ast_cdr_fork(const char *channel_name, struct ast_flags *options);
/*!
* \since 12
* \brief Set a property on a CDR for a channel
*
* This function sets specific administrative properties on a CDR for a channel.
* This includes properties like preventing a CDR from being dispatched, to
* setting the channel as the preferred Party A in future CDRs. See
* \ref enum ast_cdr_options for more information.
*
* \param channel_name The CDR's channel
* \param option Option to apply to the CDR
*
* \retval 0 on success
* \retval 1 on error
*/
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option);
/*!
* \since 12
* \brief Clear a property on a CDR for a channel
*
* Clears a flag previously set by \ref ast_cdr_set_property
*
* \param channel_name The CDR's channel
* \param option Option to clear from the CDR
*
* \retval 0 on success
* \retval 1 on error
*/
int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option);
/*!
* \brief Reset the detail record
* \param channel_name The channel that the CDR is associated with
* \param keep_variables Keep the variables during the reset. If zero,
* variables are discarded during the reset.
*
* \retval 0 on success
* \retval -1 on failure
*/
int ast_cdr_reset(const char *channel_name, int keep_variables);
/*!
* \brief Serializes all the data and variables for a current CDR record
* \param channel_name The channel to get the CDR for
* \param buf A buffer to use for formatting the data
* \param delim A delimeter to use to separate variable keys/values
* \param sep A separator to use between nestings
* \retval the total number of serialized variables
*/
int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep);
/*!
* \brief CDR backend callback
* \warning CDR backends should NOT attempt to access the channel associated
* with a CDR record. This channel is not guaranteed to exist when the CDR
* backend is invoked.
*/
typedef int (*ast_cdrbe)(struct ast_cdr *cdr);
/*! \brief Return TRUE if CDR subsystem is enabled */
int ast_cdr_is_enabled(void);
/*!
* \brief Allocate a CDR record
* \retval a malloc'd ast_cdr structure
* \retval NULL on error (malloc failure)
*/
struct ast_cdr *ast_cdr_alloc(void);
struct stasis_message_router;
/*!
* \brief Return the message router for the CDR engine
*
* This returns the \ref stasis_message_router that the CDR engine
* uses for dispatching \ref stasis messages. The reference on the
* message router is bumped and must be released by the caller of
* this function.
*
* \retval NULL if the CDR engine is disabled or unavailable
* \retval the \ref stasis_message_router otherwise
*/
struct stasis_message_router *ast_cdr_message_router(void);
/*!
* \brief Duplicate a public CDR
* \param cdr the record to duplicate
*
* \retval a malloc'd ast_cdr structure,
* \retval NULL on error (malloc failure)
*/
struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr);
/*!
* \brief Free a CDR record
* \param cdr ast_cdr structure to free
* Returns nothing
*/
void ast_cdr_free(struct ast_cdr *cdr);
/*!
* \brief Register a CDR handling engine
* \param name name associated with the particular CDR handler
* \param desc description of the CDR handler
* \param be function pointer to a CDR handler
* Used to register a Call Detail Record handler.
* \retval 0 on success.
* \retval -1 on error
*/
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be);
/*!
* \brief Unregister a CDR handling engine
* \param name name of CDR handler to unregister
* Unregisters a CDR by it's name
*
* \retval 0 The backend unregistered successfully
* \retval -1 The backend could not be unregistered at this time
*/
int ast_cdr_unregister(const char *name);
/*!
* \brief Suspend a CDR backend temporarily
*
* \retval 0 The backend is suspdended
* \retval -1 The backend could not be suspended
*/
int ast_cdr_backend_suspend(const char *name);
/*!
* \brief Unsuspend a CDR backend
*
* \retval 0 The backend was unsuspended
* \retval -1 The back could not be unsuspended
*/
int ast_cdr_backend_unsuspend(const char *name);
/*!
* \brief Disposition to a string
* \param disposition input binary form
* Converts the binary form of a disposition to string form.
* \return a pointer to the string form
*/
const char *ast_cdr_disp2str(int disposition);
/*!
* \brief Set CDR user field for channel (stored in CDR)
*
* \param channel_name The name of the channel that owns the CDR
* \param userfield The user field to set
*/
void ast_cdr_setuserfield(const char *channel_name, const char *userfield);
/*! \brief Reload the configuration file cdr.conf and start/stop CDR scheduling thread */
int ast_cdr_engine_reload(void);
/*! \brief Load the configuration file cdr.conf and possibly start the CDR scheduling thread */
int ast_cdr_engine_init(void);
/*! Submit any remaining CDRs and prepare for shutdown */
void ast_cdr_engine_term(void);
#endif /* _ASTERISK_CDR_H */
|