/* Status */ PJ_DEF(void) pjpidf_status_construct(pj_pool_t *pool, pjpidf_status *st) { pj_xml_node *node; xml_init_node(pool, st, &STATUS, NULL); node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &BASIC, &CLOSED); pj_xml_add_node(st, node); }
/* Local */ PJ_DECL(void) pjdialog_info_local_construct(pj_pool_t *pool, pjdialog_info_local *local) { pj_xml_node *node; xml_init_node(pool, local, &LOCAL, NULL); node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, NULL, NULL); pj_xml_add_node(local, node); }
/* Remote */ PJ_DEF(void) pjdialog_info_remote_construct(pj_pool_t *pool, pjdialog_info_remote *remote) { pj_xml_node *node; xml_init_node(pool, remote, &REMOTE, NULL); node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, NULL, NULL); pj_xml_add_node(remote, node); }
PJ_DECL(pjdialog_info_remote*) pjdialog_info_dialog_add_remote(pj_pool_t *pool, pjdialog_info_dialog *dialog) { pjdialog_info_remote *remote = PJ_POOL_ALLOC_T(pool, pjdialog_info_remote); xml_init_node(pool, remote, &REMOTE, NULL); pj_xml_add_node(dialog, remote); return remote; }
PJ_DECL(pjdialog_info_local*) pjdialog_info_dialog_add_local(pj_pool_t *pool, pjdialog_info_dialog *dialog) { pjdialog_info_local *local = PJ_POOL_ALLOC_T(pool, pjdialog_info_local); xml_init_node(pool, local, &LOCAL, NULL); pj_xml_add_node(dialog, local); return local; }
PJ_DEF(pjpidf_note*) pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *text) { pjpidf_note *note = PJ_POOL_ALLOC_T(pool, pjpidf_note); xml_init_node(pool, note, &NOTE, text); pj_xml_add_node(t, note); return note; }
PJ_DEF(void) pjpidf_tuple_set_timestamp_np(pj_pool_t *pool, pjpidf_tuple *t, pj_str_t *ts) { pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP); if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &TIMESTAMP, ts); } else { node->content = *ts; } }
/* Presence */ PJ_DEF(void) pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres, const pj_str_t *entity) { pj_xml_attr *attr; xml_init_node(pool, pres, &PRESENCE, NULL); attr = xml_create_attr(pool, &ENTITY, entity); pj_xml_add_attr(pres, attr); attr = xml_create_attr(pool, &XMLNS, &PIDF_XMLNS); pj_xml_add_attr(pres, attr); }
PJ_DEF(void) pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *contact) { pj_xml_node *node = pj_xml_find_node(t, &CONTACT); if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &CONTACT, contact); pj_xml_add_node(t, node); } else { pj_strdup(pool, &node->content, contact); } }
/* Tuple */ PJ_DEF(void) pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *id) { pj_xml_attr *attr; pjpidf_status *st; xml_init_node(pool, t, &TUPLE, NULL); attr = xml_create_attr(pool, &ID, id); pj_xml_add_attr(t, attr); st = PJ_POOL_ALLOC_T(pool, pjpidf_status); pjpidf_status_construct(pool, st); pj_xml_add_node(t, st); }
PJ_DECL(void) pjdialog_info_local_add_identity(pj_pool_t *pool, pjdialog_info_local *local, const pj_str_t *identity) { pj_xml_node *node = pj_xml_find_node((pj_xml_node*)local, &IDENTITY); if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &IDENTITY, identity); pj_xml_add_node(local, node); } else { pj_strdup(pool, &node->content, identity); } }
PJ_DECL(void) pjdialog_info_dialog_set_duration(pj_pool_t *pool, pjdialog_info_dialog *dialog, const pj_str_t *duration) { pj_xml_node *node = pj_xml_find_node((pj_xml_node*)dialog, &DURATION); if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &DURATION, duration); pj_xml_add_node(dialog, node); } else { pj_strdup(pool, &node->content, duration); } }
PJ_DECL(void) pjdialog_info_dialog_set_state(pj_pool_t *pool, pjdialog_info_dialog *dialog, const pj_str_t *state) { pj_xml_node *node = pj_xml_find_node((pj_xml_node*)dialog, &STATE); if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &STATE, state); pj_xml_add_node(dialog, node); } else { pj_strdup(pool, &node->content, state); } }
PJ_DEF(void) pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *prio) { pj_xml_node *node = pj_xml_find_node(t, &CONTACT); pj_xml_attr *attr; if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &CONTACT, NULL); pj_xml_add_node(t, node); } attr = pj_xml_find_attr(node, &PRIORITY, NULL); if (!attr) { attr = xml_create_attr(pool, &PRIORITY, prio); pj_xml_add_attr(node, attr); } else { pj_strdup(pool, &attr->value, prio); } }
/* Dialog */ PJ_DECL(void) pjdialog_info_dialog_construct(pj_pool_t *pool, pjdialog_info_dialog *dialog, const pj_str_t *id) { pj_xml_attr *attr; pjdialog_info_local *local; pjdialog_info_remote *remote; xml_init_node(pool, dialog, &DIALOG, NULL); attr = xml_create_attr(pool, &ID, id); pj_xml_add_attr(dialog, attr); local = PJ_POOL_ALLOC_T(pool, pjdialog_info_local); pjdialog_info_local_construct(pool, local); pj_xml_add_node(dialog, local); remote = PJ_POOL_ALLOC_T(pool, pjdialog_info_remote); pjdialog_info_remote_construct(pool, remote); pj_xml_add_node(dialog, remote); }
PJ_DECL(void) pjdialog_info_local_set_identity_display(pj_pool_t *pool, pjdialog_info_local *local, const pj_str_t *identity_display) { pj_xml_node *node = pj_xml_find_node((pj_xml_node*)local, &IDENTITY); pj_xml_attr *attr; if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &IDENTITY, NULL); pj_xml_add_node(local, node); } attr = pj_xml_find_attr(node, &DISPLAY, NULL); if (!attr) { attr = xml_create_attr(pool, &DISPLAY, identity_display); pj_xml_add_attr(node, attr); } else { pj_strdup(pool, &attr->value, identity_display); } }
PJ_DECL(void) pjdialog_info_local_set_target_uri(pj_pool_t *pool, pjdialog_info_local *local, const pj_str_t * target_uri) { pj_xml_node *node = pj_xml_find_node((pj_xml_node*)local, &TARGET); pj_xml_attr *attr; if (!node) { node = PJ_POOL_ALLOC_T(pool, pj_xml_node); xml_init_node(pool, node, &TARGET, NULL); pj_xml_add_node(local, node); } attr = pj_xml_find_attr(node, &URI, NULL); if (!attr) { attr = xml_create_attr(pool, &URI, target_uri); pj_xml_add_attr(node, attr); } else { pj_strdup(pool, &attr->value, target_uri); } }
/******************************************************************** * FUNCTION xml_rd_open_file * * Read the value for the specified obj from an open FILE in XML format * * INPUTS: * fp == open FILE control block * obj == object template for the output value * val == address of value for output * * RETURNS: * status *********************************************************************/ status_t xml_rd_open_file (FILE *fp, obj_template_t *obj, val_value_t **val) { xml_node_t top; status_t res; /* get a dummy session control block */ ses_cb_t *scb = ses_new_dummy_scb(); if (!scb) { return ERR_INTERNAL_MEM; } scb->fp = fp; res = xml_get_reader_for_session(my_ses_read_cb, NULL, scb/*context*/, &scb->reader); if(res != NO_ERR) { return res; } /* parse */ *val = val_new_value(); if(*val == NULL) { return ERR_INTERNAL_MEM; } xml_init_node(&top); res = xml_consume_node(scb->reader, &top, TRUE, TRUE); if (res != NO_ERR) { return res; } res = val_parse(scb, obj, &top, *val); scb->fp = NULL; /* skip fclose inside ses_free_scb */ ses_free_scb(scb); xml_clean_node(&top); return res; } /* xml_rd_open_file */
/* Dialog-Info */ PJ_DECL(void) pjdialog_info_dialog_info_construct(pj_pool_t *pool, pjdialog_info_dialog_info *dialog_info, const pj_str_t *version, const pj_str_t *state, const pj_str_t* entity) { pj_xml_attr *attr; pjdialog_info_dialog *dialog; xml_init_node(pool, dialog_info, &DIALOG_INFO, NULL); attr = xml_create_attr(pool, &VERSION, version); pj_xml_add_attr(dialog_info, attr); attr = xml_create_attr(pool, &STATE, state); pj_xml_add_attr(dialog_info, attr); attr = xml_create_attr(pool, &ENTITY, entity); pj_xml_add_attr(dialog_info, attr); dialog = PJ_POOL_ALLOC_T(pool, pjdialog_info_dialog); pjdialog_info_local_construct(pool, dialog); pj_xml_add_node(dialog_info, dialog); }
/******************************************************************** * FUNCTION mgr_xml_skip_subtree * * Already encountered an error, so advance nodes until the * matching start-node is reached or a terminating error occurs * - end of input * - start depth level reached * * INPUTS: * reader == XmlReader already initialized from File, Memory, * or whatever * startnode == xml_node_t of the start node of the sub-tree to skip * RETURNS: * status of the operation * SIDE EFFECTS: * the xmlreader state is advanced until the current node is the * end node of the specified start node or a fatal error occurs *********************************************************************/ status_t mgr_xml_skip_subtree (xmlTextReaderPtr reader, const xml_node_t *startnode) { xml_node_t node; const xmlChar *qname, *badns; uint32 len; int ret, depth, nodetyp; xmlns_id_t nsid; boolean done, justone; status_t res; #ifdef DEBUG if (!reader || !startnode) { return SET_ERROR(ERR_INTERNAL_PTR); } #endif justone = FALSE; switch (startnode->nodetyp) { case XML_NT_START: break; case XML_NT_EMPTY: return NO_ERR; case XML_NT_STRING: justone = TRUE; break; case XML_NT_END: return NO_ERR; default: return SET_ERROR(ERR_INTERNAL_VAL); } xml_init_node(&node); res = mgr_xml_consume_node_noadv(reader, &node); if (res == NO_ERR) { res = xml_endnode_match(startnode, &node); if (res == NO_ERR) { xml_clean_node(&node); return NO_ERR; } } xml_clean_node(&node); if (justone) { return NO_ERR; } done = FALSE; while (!done) { /* advance the node pointer */ ret = xmlTextReaderRead(reader); if (ret != 1) { /* fatal error */ return ERR_XML_READER_EOF; } /* get the node depth to match the end node correctly */ depth = xmlTextReaderDepth(reader); if (depth == -1) { /* not sure if this can happen, treat as fatal error */ return ERR_XML_READER_INTERNAL; } else if (depth <= startnode->depth) { /* this depth override will cause errors to be ignored * - wrong namespace in matching end node * - unknown namespace in matching end node * - wrong name in 'matching' end node */ done = TRUE; } /* get the internal nodetype, check it and convert it */ nodetyp = xmlTextReaderNodeType(reader); /* get the element QName */ qname = xmlTextReaderConstName(reader); if (qname) { /* check for namespace prefix in the name * only error is 'unregistered namespace ID' * which doesn't matter in this case */ nsid = 0; (void)xml_check_ns(reader, qname, &nsid, &len, &badns); } else { qname = (const xmlChar *)""; } /* check the normal case to see if the search is done */ if (depth == startnode->depth && !xml_strcmp(qname, startnode->qname) && nodetyp == XML_ELEMENT_DECL) { done = TRUE; } #ifdef XML_UTIL_DEBUG log_debug3("\nxml_skip: %s L:%d T:%s", qname, depth, xml_get_node_name(nodetyp)); #endif } return NO_ERR; } /* mgr_xml_skip_subtree */
/******************************************************************** * FUNCTION agt_top_dispatch_msg * * Find the appropriate top node handler and call it * called by the transport manager (through the session manager) * when a new message is detected * * INPUTS: * scb == session control block containing the xmlreader * set at the start of an incoming message. * * RETURNS: * none *********************************************************************/ void agt_top_dispatch_msg (ses_cb_t **ppscb) { ses_total_stats_t *myagttotals; agt_profile_t *profile; xml_node_t top; status_t res; top_handler_t handler; ses_cb_t *scb = *ppscb; #ifdef DEBUG if (!scb) { SET_ERROR(ERR_INTERNAL_PTR); return; } #endif myagttotals = ses_get_total_stats(); profile = agt_get_profile(); xml_init_node(&top); /* get the first node */ res = agt_xml_consume_node(scb, &top, NCX_LAYER_TRANSPORT, NULL); if (res != NO_ERR) { scb->stats.inBadRpcs++; myagttotals->stats.inBadRpcs++; myagttotals->droppedSessions++; if (LOGINFO) { log_info("\nagt_top: bad msg for session %d (%s)", scb->sid, get_error_string(res)); } xml_clean_node(&top); agt_ses_free_session(scb); /* set the supplied ptr to ptr to scb to NULL so that the * caller of this function knows that it was deallotcated */ *ppscb=NULL; return; } log_debug3("\nagt_top: got node"); if (LOGDEBUG4 && scb->state != SES_ST_INIT) { xml_dump_node(&top); } /* check node type and if handler exists, then call it */ if (top.nodetyp==XML_NT_START || top.nodetyp==XML_NT_EMPTY) { /* find the owner, elname tuple in the topQ */ handler = top_find_handler(top.module, top.elname); if (handler) { /* call the handler */ (*handler)(scb, &top); } else { res = ERR_NCX_DEF_NOT_FOUND; } } else { res = ERR_NCX_WRONG_NODETYP; } /* check any error trying to invoke the top handler */ if (res != NO_ERR) { scb->stats.inBadRpcs++; myagttotals->stats.inBadRpcs++; myagttotals->droppedSessions++; if (LOGINFO) { log_info("\nagt_top: bad msg for session %d (%s)", scb->sid, get_error_string(res)); } agt_ses_free_session(scb); /* set the supplied ptr to ptr to scb to NULL so that the * caller of this function knows that it was deallotcated */ *ppscb=NULL; } else if (profile->agt_stream_output && scb->state == SES_ST_SHUTDOWN_REQ) { /* session was closed */ agt_ses_kill_session(scb, scb->killedbysid, scb->termreason); /* set the supplied ptr to ptr to scb to NULL so that the * caller of this function knows that it was deallotcated */ *ppscb=NULL; } xml_clean_node(&top); } /* agt_top_dispatch_msg */