Пример #1
0
/**
 *	Parse a Application Server.
 * @param doc - the XML document
 * @param node - the current node
 * @param as - structure to fill
 * @returns 1 on success, 0 on failure
 */
static int parse_application_server(xmlDocPtr doc,xmlNodePtr node,ims_application_server *as)
{
	xmlNodePtr child;
	xmlChar *x;
	as->server_name.s=NULL;as->server_name.len=0;
	as->default_handling=IFC_NO_DEFAULT_HANDLING;
	as->service_info.s=NULL;as->service_info.len=0;

	for(child=node->children ; child ; child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]) {
				case 'S':case 's':	{//ServerName / ServiceInfo
					switch (child->name[4]) {
						case 'E':case 'e':  //ServerName
							x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
                                                        space_trim_dup(&(as->server_name),(char*)x);
							xmlFree((char*)x);
							break;
						case 'I':case 'i':  //ServiceInfo
							x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
                                                        space_trim_dup(&(as->service_info),(char*)x);
							xmlFree(x);
							break;
					}
					break;
				}
				case 'D':case 'd': //DefaultHandling
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					as->default_handling=ifc_tDefaultHandling2char(x);
					xmlFree(x);
					break;
			}
	return 1;
}
Пример #2
0
/**
 *	Parse SPT for SIP Header.
 * @param doc - the XML document
 * @param node - the current node
 * @param sh - structure to fill
 * @returns 1 on success, 0 on failure
 */
static int parse_sip_header(xmlDocPtr doc,xmlNodePtr node,ims_sip_header *sh)
{
	xmlNodePtr child;
	xmlChar *x;
	char c[256];
	int len;
	struct hdr_field hf;
	sh->header.s=NULL;sh->header.len=0;
	sh->content.s=NULL;sh->content.len=0;

	for(child=node->children ; child ; child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]) {
				case 'H':case 'h':	//Header
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					len = strlen((char*)x);		
					memcpy(c,x,len);
					c[len++]=':';
					c[len]=0;
					space_trim_dup(&(sh->header),(char*)x);
					parse_hname2(c,c+(len<4?4:len),&hf);
					sh->type=(short)hf.type;
					//LOG(L_CRIT,"[%.*s(%d)]\n",sh->header.len,sh->header.s,sh->type);
					xmlFree(x);
					break;
				case 'C':case 'c':	//Content
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					space_quotes_trim_dup(&(sh->content),(char*)x);
					xmlFree(x);
					break;
			}
	return 1;
}
Пример #3
0
/**
 *	Parse a IMS Subscription.
 * @param doc - the XML document
 * @param root - the current node
 * @returns the ims_subscription* on success or NULL on error
 */
static ims_subscription* parse_ims_subscription(xmlDocPtr doc, xmlNodePtr root)
{
	xmlNodePtr child;
	xmlChar *x;
	ims_subscription *s;
	unsigned short sp_cnt=0;
	int rc;
	
	if (!root) return 0;
	while(root->type!=XML_ELEMENT_NODE || strcasecmp((char*)root->name,"IMSSubscription")!=0){
		root = root->next;
	}
	if (!root) {
		LM_ERR("No IMSSubscription node found\n");
		return 0;
	}
	s = (ims_subscription*) shm_malloc(sizeof(ims_subscription));
	if (!s) {
		LM_ERR("Out of memory allocating %lx bytes\n",sizeof(ims_subscription));
		return 0;
	}
	memset(s,0,sizeof(ims_subscription));
	for(child=root->children;child;child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]){
				case 'P':case 'p':  /* Private Identity */
					if (!s->private_identity.len){
						x = xmlNodeListGetString(doc,child->xmlChildrenNode,1);
						space_trim_dup(&(s->private_identity),(char*)x);
						xmlFree(x);
					}
					break;
				case 'S':case 's':	/* Service Profile */
					sp_cnt++;
					break;					
			}
	s->service_profiles = (ims_service_profile*) shm_malloc(sp_cnt * sizeof(ims_service_profile));
	if (!s->service_profiles) {
		LM_ERR("Out of memory allocating %lx bytes\n",sp_cnt*sizeof(ims_service_profile));
		return s;	
	}
	memset(s->service_profiles,0,sp_cnt * sizeof(ims_service_profile));
	for(child=root->children;child;child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			if (child->name[0]=='S' || child->name[0]=='s')
			{
				rc=parse_service_profile(doc,child,&(s->service_profiles[s->service_profiles_cnt]));
				if (rc==2)
					s->wpsi=1;
				if (rc)
					s->service_profiles_cnt++;
			}				
	s->lock = lock_alloc();
	s->lock = lock_init(s->lock);
	return s;
}
Пример #4
0
/**
 *	Parse SPT for Session Description.
 * @param doc - the XML document
 * @param node - the current node
 * @param sd - structure to fill
 * @returns 1 on success, 0 on failure
 */
static int parse_session_desc(xmlDocPtr doc,xmlNodePtr node,ims_session_desc *sd)
{
	xmlNodePtr child;
	xmlChar *x;
	sd->line.s=NULL;sd->line.len=0;
	sd->content.s=NULL;sd->content.len=0;

	for(child=node->children ; child ; child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]) {
				case 'L':case 'l':	//Line
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					space_trim_dup(&(sd->line),(char*)x);
					xmlFree(x);
					break;
				case 'C':case 'c':	//Content
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					space_quotes_trim_dup(&(sd->content),(char*)x);
					xmlFree(x);
					break;
			}
	return 1;
}
Пример #5
0
/**
 * Parse the Public Identity.
 * @param doc - the XML document
 * @param root - the current node
 * @param pi - structure to fill
 * @returns 1 on success, 0 on failure
 */
static int parse_public_identity(xmlDocPtr doc, xmlNodePtr root, ims_public_identity *pi)
{
	xmlNodePtr child;
	xmlChar *x;
	
	for(child=root->children;child;child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]){
				case 'I': case 'i':
					if (!pi->public_identity.len){
						x = xmlNodeListGetString(doc,child->xmlChildrenNode,1);
						space_trim_dup(&(pi->public_identity),x);
						xmlFree(x);
					}					
					break;
				case 'B': case 'b':
					x = xmlNodeListGetString(doc,child->xmlChildrenNode,1);
					pi->barring = ifc_tBool2char(x);
					xmlFree(x);
					break;				
			}
	return 1;
}
Пример #6
0
/**
 * Parses a notification and creates the r_notification object
 * @param xml - the XML data
 * @returns the new r_notification* or NULL on error
 */
r_notification* r_notification_parse(str xml)
{
	r_notification *n;
	r_registration *r;
	r_regcontact *rc;
	xmlDocPtr doc=0;
	xmlNodePtr root=0,child=0,nephew=0,node=0;
	xmlChar *reginfo_state=0,*x;
	char c=0;
	
	n = pkg_malloc(sizeof(r_notification));
	if (!n) {
		LOG(L_ERR,"ERR:"M_NAME":r_notification_parse: Error allocating %d bytes\n",
			sizeof(r_notification));
		goto error;
	}
	memset(n,0,sizeof(r_notification));

	if (!dtd) parser_init(pcscf_reginfo_dtd);
	doc=0;
	c = xml.s[xml.len];
	xml.s[xml.len]=0;
	doc = xmlParseDoc((unsigned char *)xml.s);
	if (!doc){
		LOG(L_ERR,"ERR:"M_NAME":r_notification_parse:  This is not a valid XML <%.*s>\n",
			xml.len,xml.s);
		goto error;
	}
	if (xmlValidateDtd(&cvp,doc,dtd)!=1){
		LOG(L_ERR,"ERR:"M_NAME":r_notification_parse:  Verification of XML against DTD failed <%.*s>\n",
			xml.len,xml.s);
		goto error;
	}
	root = xmlDocGetRootElement(doc);
	if (!root){
		LOG(L_ERR,"ERR:"M_NAME":r_notification_parse:  Empty XML <%.*s>\n",
			xml.len,xml.s);
		goto error;
	}

	reginfo_state = xmlGetProp(root,(xmlChar*)"state");
	LOG(L_DBG,"DBG:"M_NAME":r_notification_parse: reginfo_state <%s>\n",
			reginfo_state);
	if (reginfo_state[0]=='f'||reginfo_state[0]=='F')
		n->state = IMS_REGINFO_FULL;
	else 
		n->state = IMS_REGINFO_PARTIAL;
	
	for(child = root->children; child; child = child->next)
		if (child->type == XML_ELEMENT_NODE)
	{
		r = pkg_malloc(sizeof(r_registration));
		if (!r){
			LOG(L_ERR,"ERR:"M_NAME":r_notification_parse: Error allocating %d bytes\n",
				sizeof(r_registration));
			goto error;
		}
		memset(r,0,sizeof(r_registration));
		
		x = xmlGetProp(child,(xmlChar*)"id");
		space_trim_dup(&(r->id),(char*)x);
		xmlFree(x);

		x = xmlGetProp(child,(xmlChar*)"aor");
		space_trim_dup(&(r->aor),(char*)x);
		xmlFree(x);
		
		x = xmlGetProp(child,(xmlChar*)"state");
		
		if (x[0]=='a'||x[0]=='A') 
			r->state = IMS_REGINFO_ACTIVE;
		else 
			r->state = IMS_REGINFO_TERMINATED;
		xmlFree(x);

		for(nephew = child->children; nephew; nephew = nephew->next)
				if (nephew->type == XML_ELEMENT_NODE)
		{
			rc = pkg_malloc(sizeof(r_regcontact));
			if (!rc){
				LOG(L_ERR,"ERR:"M_NAME":r_notification_parse: Error allocating %d bytes\n",
					sizeof(r_regcontact));
				goto error;
			}
			memset(rc,0,sizeof(r_regcontact));
			
			x = xmlGetProp(nephew,(xmlChar*)"id");
			space_trim_dup(&(rc->id),(char*)x);
			xmlFree(x);
				
			x = xmlGetProp(nephew,(xmlChar*)"state");
			if (x[0]=='a'||x[0]=='A') 
				rc->state = IMS_REGINFO_ACTIVE;
			else 
				rc->state = IMS_REGINFO_TERMINATED;
			xmlFree(x);
			
			x = xmlGetProp(nephew,(xmlChar*)"event");
			switch(x[0]){
				case 'r':case 'R':
					switch (x[2]){
						case 'g': case 'G':
							rc->event = IMS_REGINFO_CONTACT_REGISTERED;
							break;
						case 'f': case 'F':
							rc->event = IMS_REGINFO_CONTACT_REFRESHED;
							break;						
						case 'j': case 'J':
							rc->event = IMS_REGINFO_CONTACT_REJECTED;
							break;						
						default:
							rc->event = IMS_REGINFO_NONE;
					}
					break;
				case 'c':case 'C':
					rc->event = IMS_REGINFO_CONTACT_CREATED;	
					break;
				case 's':case 'S':
					rc->event = IMS_REGINFO_CONTACT_SHORTENED;	
					break;
				case 'e':case 'E':
					rc->event = IMS_REGINFO_CONTACT_EXPIRED;	
					break;
				case 'd':case 'D':
					rc->event = IMS_REGINFO_CONTACT_DEACTIVATED;	
					break;
				case 'p':case 'P':
					rc->event = IMS_REGINFO_CONTACT_PROBATION;	
					break;
				case 'u':case 'U':
					rc->event = IMS_REGINFO_CONTACT_UNREGISTERED;	
					break;
				default:
					rc->event = IMS_REGINFO_NONE;	
			}
			xmlFree(x);

			x = xmlGetProp(nephew,(xmlChar*)"expires");			
			if (x) {
				rc->expires = atoi((char*)x);
				xmlFree(x);
			}
			
			node = nephew->children;
			while(node && node->type!=XML_ELEMENT_NODE)
				node =node->next;
			if (node) {
				x = xmlNodeGetContent(node);
				space_trim_dup(&(rc->uri),(char*)x);
				xmlFree(x);
			}
			
			rc->next = r->contact;
			r->contact = rc;
		}
		
		r->next = n->registration;
		n->registration = r;
					
	}
			
	if (reginfo_state) xmlFree(reginfo_state);		
	
	if (doc) xmlFreeDoc(doc);
	xml.s[xml.len]=c;
	return n;
error:	
	if (reginfo_state) xmlFree(reginfo_state);		

	if (doc) xmlFreeDoc(doc);
	xml.s[xml.len]=c;
	if (n) r_notification_free(n);
	return 0;
}
Пример #7
0
/**
 * Parse the Public Identity.
 * @param doc - the XML document
 * @param root - the current node
 * @param pi - structure to fill
 * @returns 1 on success, 0 on failure , 2 if its a wildcardpsi
 */
static int parse_public_identity(xmlDocPtr doc, xmlNodePtr root, ims_public_identity *pi)
{
	xmlNodePtr child;
	xmlNodePtr grandson;
	xmlChar *x;
	int return_code=1;
	
	for(child=root->children;child;child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]){
				case 'I': case 'i':
					if (!pi->public_identity.len){
						x = xmlNodeListGetString(doc,child->xmlChildrenNode,1);
						space_trim_dup(&(pi->public_identity),(char*)x);
						xmlFree(x);
					}					
					break;
				case 'B': case 'b':
					x = xmlNodeListGetString(doc,child->xmlChildrenNode,1);
					pi->barring = ifc_tBool2char(x);
					xmlFree(x);
					break;
				//lets add something 
				case 'E' : case 'e':
					// that would be Extension
					// here i need to parse Identity Type 
					// if its two then  wildcardedpsi
					// and then extension!!!
					// I have to check how you parse this shit

					for(grandson=child->children;grandson;grandson=grandson->next)
					{
												
						if (grandson->type==XML_ELEMENT_NODE)
						{
							switch (grandson->name[0]) {
								case 'I' : case 'i':
									//identity type 0 public identity 1 distinct psi 2 wildcard psi
									//x = xmlNodeListGetString(doc,grandson->xmlChildrenNode,1);
									// i need to compare x with 2, but i have to trim leading 
									// space characters or tabs			
									//xmlFree(x);
									break;
								case 'W' : case 'w':
									//wildcardpsi
									if(!scscf_support_wildcardPSI) {
										LOG(L_ERR,"Configured without support for Wildcard PSI and got one from HSS\n");
										LOG(L_ERR,"the identity will be stored but never be matched, please include the parameter to support wildcard PSI in the config file\n");
									}
									
									x = xmlNodeListGetString(doc,grandson->xmlChildrenNode,1);
									space_trim_dup(&(pi->wildcarded_psi),(char*)x);
									
									xmlFree(x);
									return_code=2;
									break;
								default :
									break;
							}
						}
					}
										
					break;				
			}

	return return_code;
}
Пример #8
0
/**
 *	Parse a Service Point Trigger.
 * @param doc - the XML document
 * @param node - the current node
 * @param spt_to - structure to fill
 * @param spt_cnt - structure to fill with the spt count
 * @returns 1 on success, 0 on failure
 */
static int parse_spt(xmlDocPtr doc,xmlNodePtr node,ims_spt *spt_to,unsigned short *spt_cnt)
{
	xmlNodePtr child,saved=0;
	xmlChar *x;

	ims_spt *spt,*spt2;
	int group;
	
	spt = spt_to + *spt_cnt;
	
	spt->condition_negated=0;
	spt->group=0;
	spt->type=IFC_UNKNOWN;
	spt->registration_type=0;

	for(child=node->children ; child ; child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]) {
				case 'C':case 'c': //ConditionNegated
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					spt->condition_negated=ifc_tBool2char(x);
					xmlFree(x);
					break;
				case 'G':case 'g': //Group
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					spt->group=atoi((char*)x);
					xmlFree(x);
					break;
				case 'R':case 'r': //RequestUri
					spt->type=IFC_REQUEST_URI;
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					space_trim_dup(&(spt->request_uri),(char*)x);
					xmlFree(x);
					break;
				case 'E':case 'e': //Extension
				    parse_spt_extension(doc,child,spt);
					break;
				case 'M':case 'm': //method
					spt->type=IFC_METHOD;
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					space_trim_dup(&(spt->method),(char*)x);
					xmlFree(x);
					break;
				case 'S':case 's': {//SIPHeader/SessionCase/SessionDescription
					switch(child->name[7]) {
						case 'E':case 'e'://SIP_HEADER
							spt->type=IFC_SIP_HEADER;
							parse_sip_header(doc,child,&(spt->sip_header));
							saved = child;
							break;
						case 'C':case 'c'://Session Case
							spt->type=IFC_SESSION_CASE;
							x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
							spt->session_case=ifc_tDirectionOfRequest2char(x);
							xmlFree(x);
							break;
						case 'D':case 'd'://Session Description
							spt->type=IFC_SESSION_DESC;
							parse_session_desc(doc,child,&(spt->session_desc));
							saved = child;
							break;
					}

				}
					break;
			}
	*spt_cnt=*spt_cnt+1;

	/* adding the other nodes for multiple groups */			
	for(child=node->children ; child ; child=child->next)
		if (child->type==XML_ELEMENT_NODE)
			switch (child->name[0]) {
				case 'G':case 'g': //Group
					x = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
					group=atoi((char*)x);
					xmlFree(x);
					if (group != spt->group){
						spt2 = spt_to + *spt_cnt;
						spt2->condition_negated = spt->condition_negated;
						spt2->group = group;
						spt2->type = spt->type;
						switch(spt2->type){
							case IFC_REQUEST_URI:
								spt2->request_uri.len = spt->request_uri.len;
								spt2->request_uri.s = shm_malloc(spt2->request_uri.len);
								if (!spt2->request_uri.s){
									LM_ERR("Out of memory allocating %d bytes\n",spt->request_uri.len);
									break;
								}
								memcpy(spt2->request_uri.s,spt->request_uri.s,spt->request_uri.len);
								break;
							case IFC_METHOD:
								spt2->method.len = spt->method.len;
								spt2->method.s = shm_malloc(spt2->method.len);
								if (!spt2->method.s){
									LM_ERR("Out of memory allocating %d bytes\n",spt->method.len);
									break;
								}
								memcpy(spt2->method.s,spt->method.s,spt->method.len);
								break;
							case IFC_SIP_HEADER:
								parse_sip_header(doc,saved,&(spt2->sip_header));
								break;
							case IFC_SESSION_CASE:
								spt2->session_case = spt->session_case;
								break;
							case IFC_SESSION_DESC:
								parse_session_desc(doc,saved,&(spt2->session_desc));
								break;								
						}
						spt2->registration_type = spt->registration_type;
						*spt_cnt = *spt_cnt+1;						
					}
					break;
			}
	return 1;			
}