41 attr = PJ_POOL_ALLOC_T(pool, pj_xml_attr);
43 pj_strdup2(pool, &attr->name,
name);
44 pj_strdup2(pool, &attr->value,
value);
46 pj_xml_add_attr(
node, attr);
55 node = PJ_POOL_ZALLOC_T(pool, pj_xml_node);
57 pj_list_init(&
node->attr_head);
58 pj_list_init(&
node->node_head);
63 pj_xml_add_node(parent,
node);
72 pj_strdup2(pool, &
node->content, content);
78 const size_t amount_max_size = 16;
81 amount_str = pj_pool_alloc(pool, amount_max_size);
85 pj_ansi_snprintf(amount_str, amount_max_size,
"%.3f", amount*0.001f);
88 pj_ansi_snprintf(amount_str, amount_max_size,
"%.2f", amount*0.01f);
91 pj_ansi_snprintf(amount_str, amount_max_size,
"%.1f", amount*0.1f);
94 pj_ansi_snprintf(amount_str, amount_max_size,
"%d", amount);
97 pj_ansi_snprintf(amount_str, amount_max_size,
"%d", amount*10);
100 pj_ansi_snprintf(amount_str, amount_max_size,
"%d", amount*100);
103 pj_ansi_snprintf(amount_str, amount_max_size,
"%d", amount*1000);
106 pj_ansi_snprintf(amount_str, amount_max_size,
"%d", amount);
119 str =
"one-hundredth-second";
122 str =
"one-tenth-second";
137 str =
"twenty-four-hours";
172 pj_pool_t *pool = data;
191 pj_xml_node *aoc_type;
192 pj_xml_node *charging_info =
NULL;
193 pj_xml_node *charges;
197 const size_t xml_max_size = 512;
201 "http://uri.etsi.org/ngn/params/xml/simservs/aoc");
221 const char *currency;
227 pj_xml_node *currency_id;
238 pj_xml_node *currency_id;
256 xml = pj_pool_alloc(pool, xml_max_size);
257 size = pj_xml_print(aoc, xml, xml_max_size - 1, PJ_TRUE);
258 if (size >= xml_max_size) {
268 struct pjsip_tx_data *tdata;
270 .
type =
"application",
271 .subtype =
"vnd.etsi.aoc+xml",
276 adata->session->endpoint,
NULL,
NULL, &tdata)) {
282 pjsip_tx_data_dec_ref(tdata);
293 datastore->data =
NULL;
303 size = pj_xml_print(aoc, xml, xml_max_size - 1, PJ_TRUE);
316 datastore->data =
NULL;
328 pj_xml_node *aoc_type;
329 pj_xml_node *charged_items;
334 const size_t xml_max_size = 1024;
338 "http://uri.etsi.org/ngn/params/xml/simservs/aoc");
354 "communication-attempt");
357 "communication-setup");
375 const char *currency;
382 entry->rate.duration.currency_name :
383 entry->rate.flat.currency_name);
385 pj_xml_node *currency_id;
393 entry->rate.duration.amount :
entry->rate.flat.amount);
395 entry->rate.duration.multiplier :
entry->rate.flat.multiplier);
401 pj_xml_node *length_time_unit;
402 pj_xml_node *time_unit;
405 pj_xml_node *charging_type;
417 entry->rate.duration.charging_type ?
"step-function" :
422 xml = pj_pool_alloc(pool, xml_max_size);
423 size = pj_xml_print(aoc, xml, xml_max_size - 1, PJ_TRUE);
424 if (size >= xml_max_size) {
432 struct pjsip_tx_data *tdata;
434 .
type =
"application",
435 .subtype =
"vnd.etsi.aoc+xml",
440 adata->session->endpoint,
NULL,
NULL, &tdata)) {
446 pjsip_tx_data_dec_ref(tdata);
538 if (framehook_id < 0) {
539 ast_log(
LOG_WARNING,
"Could not attach AOC Frame hook, AOC will be unavailable on '%s'\n",
547 struct pjsip_rx_data *rdata)
554 struct pjsip_tx_data *tdata)
560 struct pjsip_tx_data *tdata)
563 .
type =
"application",
564 .subtype =
"vnd.etsi.aoc+xml",
573 }
else if (datastore_d) {
586 struct pjsip_tx_data *tdata)
589 .
type =
"application",
590 .subtype =
"vnd.etsi.aoc+xml",
599 }
else if (datastore_d) {
612 struct pjsip_tx_data *tdata)
614 pjsip_msg_body *multipart_body;
615 pjsip_multipart_part *part;
622 if (tdata->msg->line.status.code != 180 && tdata->msg->line.status.code != 183 &&
623 tdata->msg->line.status.code != 200) {
631 if (tdata->msg->body && pjsip_media_type_cmp(&tdata->msg->body->content_type,
633 multipart_body = tdata->msg->body;
635 pjsip_sdp_info *tdata_sdp_info;
637 tdata_sdp_info = pjsip_tdata_get_sdp_info(tdata);
638 if (tdata_sdp_info->sdp) {
641 rc = pjsip_create_multipart_sdp_body(tdata->pool, tdata_sdp_info->sdp,
643 if (rc != PJ_SUCCESS) {
648 multipart_body = pjsip_multipart_create(tdata->pool,
653 part = pjsip_multipart_create_part(tdata->pool);
654 pj_strdup2(tdata->pool, &
body_text, datastore->data);
655 pj_cstr(&
type,
"application");
656 pj_cstr(&
subtype,
"vnd.etsi.aoc+xml");
658 pjsip_multipart_add_part(tdata->pool, multipart_body, part);
660 tdata->msg->body = multipart_body;
697 .
requires =
"res_pjsip",
Generic Advice of Charge encode and decode routines.
enum ast_aoc_total_type ast_aoc_get_total_type(struct ast_aoc_decoded *decoded)
get the type of total for a AOC-D message
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
@ AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION
@ AST_AOC_CHARGED_ITEM_CALL_SETUP
@ AST_AOC_CHARGED_ITEM_CALL_ATTEMPT
@ AST_AOC_CHARGE_CURRENCY
@ AST_AOC_TIME_SCALE_TEN_SECOND
@ AST_AOC_TIME_SCALE_TENTH_SECOND
@ AST_AOC_TIME_SCALE_MINUTE
@ AST_AOC_TIME_SCALE_SECOND
@ AST_AOC_TIME_SCALE_HOUR
@ AST_AOC_TIME_SCALE_HUNDREDTH_SECOND
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
@ AST_AOC_MULT_ONEHUNDREDTH
@ AST_AOC_MULT_ONETHOUSANDTH
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
const struct ast_aoc_unit_entry * ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific unit entry.
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
enum ast_aoc_currency_multiplier ast_aoc_get_currency_multiplier(struct ast_aoc_decoded *decoded)
get the currency multiplier for AOC-D and AOC-E messages
const struct ast_aoc_s_entry * ast_aoc_s_get_rate_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific AOC-S rate entry.
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded)
get the charging type for an AOC-D or AOC-E message
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
@ AST_AOC_RATE_TYPE_DURATION
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_strdup(str)
A wrapper for strdup()
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
#define ao2_alloc(data_size, destructor_fn)
const char * ast_channel_name(const struct ast_channel *chan)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
#define ast_channel_unlock(chan)
ast_channel_state
ast_channel states
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
@ AST_FRAMEHOOK_EVENT_WRITE
#define AST_FRAMEHOOK_INTERFACE_VERSION
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
ast_frame_type
Frame types.
struct ast_frame ast_null_frame
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
Core PBX routines and definitions.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
@ AST_SIP_SUPPLEMENT_PRIORITY_LAST
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
pjsip_media_type pjsip_media_type_multipart_mixed
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
static const char * aoc_time_scale_str(enum ast_aoc_time_scale value)
static int aoc_consume(void *data, enum ast_frame_type type)
static void aoc_outgoing_invite_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static struct ast_frame * aoc_framehook(struct ast_channel *ast, struct ast_frame *f, enum ast_framehook_event event, void *data)
static const struct ast_datastore_info aoc_s_datastore
static const struct ast_datastore_info aoc_e_datastore
static void aoc_attach_framehook(struct ast_sip_session *session)
static void aoc_invite_outgoing_response(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static void aoc_xml_set_node_content(pj_pool_t *pool, pj_xml_node *node, const char *content)
static void aoc_release_pool(void *data)
static pj_xml_attr * aoc_xml_create_attr(pj_pool_t *pool, pj_xml_node *node, const char *name, const char *value)
static void aoc_data_destroy(void *data)
static struct ast_sip_session_supplement aoc_bye_supplement
static const struct ast_datastore_info aoc_d_datastore
static void aoc_bye_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static int load_module(void)
static void aoc_bye_outgoing_response(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
static int unload_module(void)
static struct ast_sip_session_supplement aoc_invite_supplement
static pj_xml_node * aoc_xml_create_node(pj_pool_t *pool, pj_xml_node *parent, const char *name)
static void aoc_datastore_destroy(void *obj)
static int aoc_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static char * aoc_format_amount(pj_pool_t *pool, unsigned int amount, enum ast_aoc_currency_multiplier multiplier)
static int aoc_send_as_xml(void *data)
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
#define ast_sip_session_register_supplement(supplement)
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
@ AST_SIP_SESSION_OUTGOING_CALL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
struct ast_sip_session * session
enum ast_channel_state channel_state
struct ast_aoc_decoded * decoded
Main Channel structure associated with a channel.
Structure for a data store type.
Structure for a data store object.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
A supplement to SIP message processing.
A structure describing a SIP session.
struct ast_taskprocessor * serializer
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.