Example #1
0
/*
 * Dump all destination information
 */
void ospDumpAllDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int count = 0;

    for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0);
        destavp != NULL;
        destavp = search_next_avp(destavp, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....originate '%d'....\n", count++);

        ospDumpDestination(dest);
    }
    if (count == 0) {
        LM_DBG("there is not originate destination AVP\n");
    }

    if (search_first_avp(AVP_VAL_STR, _osp_termdest_avpid, &destval, 0) != NULL) {
        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....terminate....\n");

        ospDumpDestination(dest);
    } else {
        LM_DBG("there is not terminate destination AVP\n");
    }
}
Example #2
0
/*
 * Retrieved the last used originate destination from an AVP
 *    name - OSP_ORIGDEST_NAME
 *    value - osp_dest wrapped in a string
 *    There can be 0, 1 or more destinations. 
 *    Find the last used destination (used==1) & supported (support==1),
 *    and return it.
 *    In normal condition, this one is the current destination. But it may
 *    be wrong for loop condition.
 *  return NULL on failure
 */
osp_dest* ospGetLastOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    osp_dest* lastdest = NULL;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            if (dest->supported == 1) {
                lastdest = dest;
                LM_DBG("curent destination '%s'\n", lastdest->host);
            }
        } else {
            break;
        }
    }

    return lastdest;
}
Example #3
0
static void dump_domain(rpc_t* rpc, void* ctx, domain_t* d)
{
	avp_t* a;
	void* st;
	int i;
	str* name;
	int_str val;

	if (rpc->add(ctx, "{", &st) < 0) return;
	if (rpc->struct_add(st, "S", "did", &d->did) < 0) return;

	for(i = 0; i < d->n; i++) {
		if (rpc->struct_add(st, "S", "domain", &d->domain[i]) < 0) return;
		if (rpc->struct_add(st, "d", "flags", d->flags[i]) < 0) return;
	}

	a = d->attrs;
	while(a) {
		name = get_avp_name(a);
		get_avp_val(a, &val);
		if (a->flags & AVP_VAL_STR) {
			if (rpc->struct_printf(st, "attr", "%.*s=%.*s",
								   STR_FMT(name), STR_FMT(&val.s)) < 0) return;
		} else {
			if (rpc->struct_printf(st, "attr", "%.*s=%d",
								   STR_FMT(name), val.n) < 0) return;
		}
		a = a->next;
	}
}
Example #4
0
int ops_print_avp(void)
{
	struct usr_avp **avp_list;
	struct usr_avp *avp;
	int_str         val;
	str            *name;

	/* go through all list */
	avp_list = get_avp_list();
	avp = *avp_list;

	for ( ; avp ; avp=avp->next)
	{
		LM_INFO("p=%p, flags=0x%04X\n",avp, avp->flags);
		name = get_avp_name(avp);
		LM_INFO("\t\t\tname=<%.*s>\n",name->len,name->s);
		LM_INFO("\t\t\tid=<%d>\n",avp->id);
		get_avp_val( avp, &val);
		if (avp->flags&AVP_VAL_STR)
		{
			LM_INFO("\t\t\tval_str=<%.*s / %d>\n",val.s.len,val.s.s,
					val.s.len);
		} else {
			LM_INFO("\t\t\tval_int=<%d>\n",val.n);
		}
	}


	return 1;
}
Example #5
0
/**
 * search first avp begining with 'start->next'
 * if start==NULL, beging from head of avp list
 */
struct usr_avp *search_first_avp( unsigned short flags,
					int id, int_str *val,  struct usr_avp *start)
{
	struct usr_avp *head;
	struct usr_avp *avp;

	if (id < 0) {
		LM_ERR("invalid avp id %d\n", id);
		return 0;
	}

	if(start==0)
	{
		assert( crt_avps!=0 );
	
		if (*crt_avps==0)
			return 0;
		head = *crt_avps;
	} else {
		if(start->next==0)
			return 0;
		head = start->next;
	}

	/* search for the AVP by ID (&name) */
	avp = internal_search_ID_avp(head, id, flags&AVP_SCRIPT_MASK);

	/* get the value - if required */
	if (avp && val)
		get_avp_val(avp, val);

	return avp;
}
Example #6
0
/*
 * Report originate call setup usage
 */
void ospReportOrigSetupUsage(void)
{
    osp_dest* dest = NULL;
    osp_dest* lastused = NULL;
    struct usr_avp* destavp = NULL;
    int_str destval;
    OSPTTRANHANDLE transaction = -1;
    int lastcode = 0;
    int errorcode;
	struct search_state st;

    errorcode = OSPPTransactionNew(_osp_provider, &transaction);

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, 0))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            if (dest->reported == 1) {
                LM_DBG("orig setup already reported\n");
                break;
            } else {
                dest->reported = 1;
            }

            LM_DBG("iterating through used destination\n");

            ospDumpDestination(dest);

            lastused = dest;

            errorcode = ospBuildUsageFromDestination(transaction, dest, lastcode);

            lastcode = dest->lastcode;
        } else {
            LM_DBG("destination has not been used, breaking out\n");
            break;
        }
    }

    if (lastused) {
        LM_INFO("report orig setup for call_id '%.*s' transaction_id '%llu'\n",
            lastused->callidsize,
            lastused->callid,
            lastused->transid);
        errorcode = ospReportUsageFromDestination(transaction, lastused);
    } else {
        /* If a Toolkit transaction handle was created, but we did not find
         * any destinations to report, we need to release the handle. Otherwise,
         * the ospReportUsageFromDestination will release it.
         */
        OSPPTransactionDelete(transaction);
    }
}
Example #7
0
struct usr_avp *search_next_avp( struct usr_avp *avp,  int_str *val )
{
	if (avp==0 || avp->next==0)
		return 0;

	avp = internal_search_ID_avp( avp->next, avp->id,
			avp->flags&AVP_SCRIPT_MASK );

	if (avp && val)
		get_avp_val(avp, val);

	return avp;
}
Example #8
0
struct usr_avp *clone_avp_list(struct usr_avp *old)
{
	struct usr_avp *a;
	int_str val;

	if (!old) return NULL;

	/* create a copy of the old AVP */
	get_avp_val( old, &val );
	a = new_avp( old->flags, old->id, val);
	if (a==NULL) {
		LM_ERR("cloning failed, trunking the list\n");
		return NULL;
	}

	a->next = clone_avp_list(old->next);
	return a;
}
Example #9
0
/**
 * search first avp begining with 'start->next'
 * if start==NULL, beging from head of avp list
 */
struct usr_avp *search_first_avp( unsigned short flags,
					int_str name, int_str *val,  struct usr_avp *start)
{
	struct usr_avp *head;
	struct usr_avp *avp;

	if(start==0)
	{
		assert( crt_avps!=0 );
	
		if (*crt_avps==0)
			return 0;
		head = *crt_avps;
	} else {
		if(start->next==0)
			return 0;
		head = start->next;
	}

	if ( name.n==0) {
		LM_ERR("0 ID or NULL NAME AVP!\n");
		return 0;
	}

	/* search for the AVP by ID (&name) */
	if (flags&AVP_NAME_STR) {
		if ( name.s.s==0 || name.s.len==0) {
			LM_ERR("empty avp name!\n");
			return 0;
		}
		avp = internal_search_name_avp(head,compute_ID(&name.s),&name.s,
				flags&AVP_SCRIPT_MASK);
	} else {
		avp = internal_search_ID_avp(head, name.n,
				flags&AVP_SCRIPT_MASK);
	}

	/* get the value - if required */
	if (avp && val)
		get_avp_val(avp, val);

	return avp;
}
Example #10
0
/* 
 * Retrieved an unused and supported originate destination from an AVP
 *     name - OSP_ORIGDEST_NAME
 *     value - osp_dest wrapped in a string
 *     There can be 0, 1 or more originate destinations. 
 *     Find the 1st unused destination (used==0) & supported (support==1),
 *     return it, and mark it as used (used==1).
 * return NULL on failure
 */
osp_dest* ospGetNextOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    osp_dest* result = NULL;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destintaion is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 0) {
            if (dest->supported == 1) {
                LM_DBG("orig dest found\n");
                dest->used = 1;
                result = dest;
                break;
            } else {
                /* Make it looks like used */
                dest->used = 1;
                /* 111 means wrong protocol */
                dest->lastcode = 111;
                LM_DBG("destination does not been supported\n");
            }
        } else {
            LM_DBG("destination has already been used\n");
        }
    }

    if (result == NULL) {
        LM_DBG("there is not unused destination\n");
    }

    return result;
}
Example #11
0
static inline avp_t *avp_dup(avp_t *avp)
{
	avp_value_t val;
	avp_name_t name;
	str *s;
	
	if (avp) {
		get_avp_val(avp, &val);
		if (avp->flags & AVP_NAME_STR) {
			s = get_avp_name(avp);
			if (s) name.s = *s;
			else {
				name.s.s = NULL;
				name.s.len = 0;
			}
		}
		else name.n = avp->id;
		return create_avp(avp->flags, name, val);
	}
	return NULL;
}
Example #12
0
/*
 * Check if there is an unused and supported originate destination from an AVP
 *     avpid - osp_origdest_avpid
 *     value - osp_dest wrapped in a string
 *     search unused (used==0) & supported (support==1)
 * return 0 success, -1 failure
 */
int ospCheckOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int result = -1;

    for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0);
        destavp != NULL;
        destavp = search_next_avp(destavp, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destintaion is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 0) {
            if (dest->supported == 1) {
                LM_DBG("orig dest exist\n");
                result = 0;
                break;
            } else {
                /* Make it looks like used */
                dest->used = 1;
                /* 111 means wrong protocol */
                dest->lastcode = 111;
                LM_DBG("destination does not been supported\n");
            }
        } else {
            LM_DBG("destination has already been used\n");
        }
    }

    if (result == -1) {
        LM_DBG("there is not unused destination\n");
        ospReportOrigSetupUsage();
    }

    return result;
}
Example #13
0
static int restore_reg_avps(struct ucontact *info)
{
	avp_t *avp;
	avp_value_t val;
	avp_name_t name;
	str *s;	
	
	/* remove all these AVPs ? */
	avp = info->avps;
	while (avp) {
		remove_avps(avp);
		avp = avp->next;
	}

	/* add stored AVPs */
	avp = info->avps;
	while (avp) {
		get_avp_val(avp, &val);
		if (avp->flags & AVP_NAME_STR) {
			s = get_avp_name(avp);
			if (s) name.s = *s;
			else {
				name.s.s = NULL;
				name.s.len = 0;
			}
		}
		else name.n = avp->id;
		
		/* trace_avp("restoring avp", avp); */
		
		/* modify flags here? */
		add_avp(avp->flags, name, val);
		
		avp = avp->next;
	}
	
	return 0;
}
Example #14
0
static int xl_get_avp(struct sip_msg *msg, str *res, str *hp, int hi, int hf)
{
	int_str name, val;
	struct usr_avp *avp, *lavp;
	struct search_state st;

	if(msg==NULL || res==NULL || hp==NULL)
	return -1;

	name.s=*hp;
if (0){
	lavp=NULL;
	for(avp=search_first_avp(AVP_NAME_STR, name, NULL, &st); avp; avp=search_next_avp(&st, NULL)) {
		lavp=avp;
		if (hi>0)
			hi--;
		else if (hi==0)
			break;
	}

	if (lavp && (hi<=0)) {
		get_avp_val(lavp, &val);
		*res=val.s;
		return 0;
	}
}
	if ((avp=search_avp_by_index(hf, name, &val, hi))) {
		if (avp->flags & AVP_VAL_STR) {
			*res=val.s;
		} else {
			res->s=int2str(val.n, &res->len);
		}
		return 0;
	}

	return xl_get_null(msg, res, hp, hi, hf);
}
Example #15
0
/*
 * Dump all destination information
 */
void ospDumpAllDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int count = 0;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....originate '%d'....\n", count++);

        ospDumpDestination(dest);
    }
    if (count == 0) {
        LM_DBG("there is not originate destination AVP\n");
    }

    if (search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_TERMDEST_NAME, &destval, 0) != NULL) {
        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....terminate....\n");

        ospDumpDestination(dest);
    } else {
        LM_DBG("there is not terminate destination AVP\n");
    }
}
Example #16
0
File: avp.c Project: 2pac/kamailio
/*
 * sends avp list to log in readable form
 *
 */
static void dump_avp_reverse(avp_t* avp)
{
    str* name;
    int_str val;
    
    if (avp) {
	     /* AVPs are added to front of the list, reverse by recursion */
	dump_avp_reverse(avp->next);
	
	name=get_avp_name(avp);
	get_avp_val(avp, &val);
	switch(avp->flags&(AVP_NAME_STR|AVP_VAL_STR)) {
	case 0:
		 /* avp type ID, int value */
	    LOG(L_INFO,"AVP[%d]=%d\n", avp->id, val.n);
	    break;

	case AVP_NAME_STR:
		 /* avp type str, int value */
	    name=get_avp_name(avp);
	    LOG(L_INFO,"AVP[\"%.*s\"]=%d\n", name->len, name->s, val.n);
	    break;

	case AVP_VAL_STR:
		 /* avp type ID, str value */
	    LOG(L_INFO,"AVP[%d]=\"%.*s\"\n", avp->id, val.s.len, val.s.s);
	    break;

	case AVP_NAME_STR|AVP_VAL_STR:
		 /* avp type str, str value */
	    name=get_avp_name(avp);
	    LOG(L_INFO,"AVP[\"%.*s\"]=\"%.*s\"\n", name->len, name->s, val.s.len, val.s.s);
	    break;
	}
    }
}
Example #17
0
/* 
 * Check if there is an unused and supported originate destination from an AVP
 *     name - OSP_ORIGDEST_NAME
 *     value - osp_dest wrapped in a string
 *     search unused (used==0) & supported (support==1)
 * return 0 success, -1 failure
 */
int ospCheckOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int result = -1;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destintaion is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 0) {
            if (dest->supported == 1) {
                LM_DBG("orig dest exist\n");
                result = 0;
                break;
            } else {
                LM_DBG("destination does not been supported\n");
            }
        } else {
            LM_DBG("destination has already been used\n");
        }
    }

    if (result == -1) {
        LM_DBG("there is not unused destination\n");
    }

    return result;
}
Example #18
0
int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp,
									struct db_param *dbp, int use_domain)
{
	struct sip_uri   uri;
	struct usr_avp   **avp_list;
	struct usr_avp   *avp;
	unsigned short   name_type;
	int_str          i_s;
	str              uuid;
	int              keys_off;
	int              keys_nr;
	int              n;
	

	if (sp->flags&AVPOPS_VAL_NONE)
	{
		/* get and parse uri */
		if (parse_source_uri( msg, sp->flags, &uri)<0 )
		{
			LOG(L_ERR,"ERROR:avpops:store_avps: failed to get uri\n");
			goto error;
		}
		/* set values for keys  */
		keys_off = 1;
		store_vals[4].val.str_val =
			(sp->flags&AVPOPS_FLAG_DOMAIN)?empty:uri.user;
		if (use_domain || sp->flags&AVPOPS_FLAG_DOMAIN)
		{
			store_vals[5].val.str_val = uri.host;
			keys_nr = 5;
		} else {
			keys_nr = 4;
		}
	} else if (sp->flags&AVPOPS_VAL_AVP) {
		/* get uuid from avp */
		if (get_avp_as_str(sp, &uuid)<0)
		{
			LOG(L_ERR,"ERROR:avpops:store_avps: failed to get uuid\n");
			goto error;
		}
		/* set values for keys  */
		keys_off = 0;
		keys_nr = 4;
		store_vals[0].val.str_val = uuid;
	} else if (sp->flags&AVPOPS_VAL_STR) {
		/* use the STR value as uuid */
		/* set values for keys  */
		keys_off = 0;
		keys_nr = 4;
		store_vals[0].val.str_val = *sp->val.s;
	} else {
		LOG(L_CRIT,"BUG:avpops:store_avps: invalid flag combination (%d)\n",
			sp->flags);
		goto error;
	}

	/* set uuid/(username and domain) fields */
	n =0 ;

	if ((dbp->a.flags&AVPOPS_VAL_NONE)==0)
	{
		/* avp name is known ->set it and its type */
		name_type = (((dbp->a.flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR);
		store_vals[1].val.str_val = dbp->sa; /*attr name*/
		avp = search_first_avp( name_type, dbp->a.val, &i_s);
		for( ; avp; avp=search_next_avp(avp,&i_s))
		{
			/* don't insert avps which were loaded */
			if (avp->flags&AVP_IS_IN_DB)
				continue;
			/* set type */
			store_vals[3].val.int_val =
				(avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)|
				(avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT);
			/* set value */
			int_str2db_val( i_s, &store_vals[2].val.str_val,
				avp->flags&AVP_VAL_STR);
			/* save avp */
			if (db_store_avp( store_keys+keys_off, store_vals+keys_off,
					keys_nr, dbp->table)==0 )
			{
				avp->flags |= AVP_IS_IN_DB;
				n++;
			}
		}
	} else {
		/* avp name is unknown -> go through all list */
		avp_list = get_avp_list();
		avp = *avp_list;

		for ( ; avp ; avp=avp->next )
		{
			/* don't insert avps which were loaded */
			if (avp->flags&AVP_IS_IN_DB)
				continue;
			/* check if type match */
			if ( !( (dbp->a.flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 ||
				((dbp->a.flags&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0)
				||((dbp->a.flags&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR))))
				continue;

			/* set attribute name and type */
			if ( (i_s.s=get_avp_name(avp))==0 )
				i_s.n = avp->id;
			int_str2db_val( i_s, &store_vals[1].val.str_val,
				avp->flags&AVP_NAME_STR);
			store_vals[3].val.int_val =
				(avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)|
				(avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT);
			/* set avp value */
			get_avp_val( avp, &i_s);
			int_str2db_val( i_s, &store_vals[2].val.str_val,
				avp->flags&AVP_VAL_STR);
			/* save avp */
			if (db_store_avp( store_keys+keys_off, store_vals+keys_off,
			keys_nr, dbp->table)==0)
			{
				avp->flags |= AVP_IS_IN_DB;
				n++;
			}
		}
	}

	DBG("DEBUG:avpops:store_avps: %d avps were stored\n",n);

	return n==0?-1:1;
error:
	return -1;
}
Example #19
0
/*
 * Report originate call setup usage
 */
void ospReportOrigSetupUsage(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    osp_dest* lastused = NULL;
    OSPTTRANHANDLE trans = -1;
    int lastcode = 0;
    OSPE_ROLE_STATE rstate;
    int errcode;

    errcode = OSPPTransactionNew(_osp_provider, &trans);
    if (errcode != OSPC_ERR_NO_ERROR) {
        return;
    }

    for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0);
        destavp != NULL;
        destavp = search_next_avp(destavp, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            LM_DBG("iterating through used destination\n");

            if (dest->reported == 1) {
                LM_DBG("orig setup already reported\n");
                break;
            } else {
                dest->reported = 1;
                ospDumpDestination(dest);
                lastused = dest;
                if (dest->lastcode == 200) {
                    rstate = OSPC_RSTATE_START;
                } else if (dest->lastcode == 300) {
                    rstate = OSPC_RSTATE_REDIRECT;
                } else {
                    rstate = OSPC_RSTATE_STOP;
                }
                /* RoleInfo must be set before BuildUsageFromScratch */
                OSPPTransactionSetRoleInfo(trans, rstate, OSPC_RFORMAT_OSP, OSPC_RVENDOR_OPENSIPS);
                ospBuildUsageFromDestination(trans, dest, lastcode);
                OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);
                OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_DESTINATION, dest->protocol);
                lastcode = dest->lastcode;
            }
        } else {
            LM_DBG("destination has not been used, breaking out\n");
            break;
        }
    }

    if (lastused) {
        LM_INFO("report orig setup for call_id '%.*s' transaction_id '%llu'\n",
            lastused->callidsize,
            lastused->callid,
            lastused->transid);
        ospReportUsageFromDestination(trans, lastused);
    } else {
        /* If a Toolkit transaction handle was created, but we did not find
         * any destinations to report, we need to release the handle. Otherwise,
         * the ospReportUsageFromDestination will release it.
         */
        OSPPTransactionDelete(trans);
    }
}
Example #20
0
File: avp.c Project: 2pac/kamailio
static int request_hf_helper(struct sip_msg* msg, str* hf, avp_ident_t* ident, struct lump* anchor, struct search_state* st, int front, int reverse, int reply)
{
    struct lump* new_anchor;
    static struct search_state state;
    avp_t* avp;
    char* s;
    str fin_val;
    int len, ret;
    int_str val;
    struct hdr_field* pos, *found = NULL;
    
    if (!anchor && !reply) {
	
	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
	    LOG(L_ERR, "ERROR: request_hf_helper: Error while parsing message\n");
	    return -1;
	}
	
	pos = msg->headers;
	while (pos && (pos->type != HDR_EOH_T)) {
	    if ((hf->len == pos->name.len)
		&& (!strncasecmp(hf->s, pos->name.s, pos->name.len))) {
		found = pos;
		if (front) {
		    break;
		}
	    }
	    pos = pos->next;
	}
	
	if (found) {
	    if (front) {
		len = found->name.s - msg->buf;
	    } else {
		len = found->name.s + found->len - msg->buf;
	    }
	} else {
	    len = msg->unparsed - msg->buf;
	}
	
	new_anchor = anchor_lump(msg, len, 0, 0);
	if (new_anchor == 0) {
	    LOG(L_ERR, "ERROR: request_hf_helper: Can't get anchor\n");
	    return -1;
	}
    } else {
	new_anchor = anchor;
    }
    
    if (!st) {
	st = &state;
	avp = search_avp(*ident, NULL, st);
	ret = -1;
    } else {
	avp = search_next_avp(st, NULL);
	ret = 1;
    }
    
    if (avp) {
	if (reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) {
	    return -1;
	}
	
	get_avp_val(avp, &val);
	if (avp->flags & AVP_VAL_STR) {
	    fin_val = val.s;
	} else {
	    fin_val.s = int2str(val.n, &fin_val.len);
	}
	
	len = hf->len + 2 + fin_val.len + 2;
	s = (char*)pkg_malloc(len);
	if (!s) {
	    LOG(L_ERR, "ERROR: request_hf_helper: No memory left for data lump\n");
	    return -1;
	}
	
	memcpy(s, hf->s, hf->len);
	memcpy(s + hf->len, ": ", 2 );
	memcpy(s + hf->len+2, fin_val.s, fin_val.len );
	memcpy(s + hf->len + 2 + fin_val.len, CRLF, CRLF_LEN);
	
	if (reply) {
	    if (add_lump_rpl( msg, s, len, LUMP_RPL_HDR | LUMP_RPL_NODUP) == 0) {
		LOG(L_ERR, "ERROR: request_hf_helper: Can't insert RPL lump\n");
		pkg_free(s);
		return -1;
	    }
	} else {
	    if ((front && (insert_new_lump_before(new_anchor, s, len, 0) == 0))
		|| (!front && (insert_new_lump_after(new_anchor, s, len, 0) == 0))) {
		LOG(L_ERR, "ERROR: request_hf_helper: Can't insert lump\n");
		pkg_free(s);
		return -1;
	    }
	}
	if (!reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) {
	    return -1;
	}
	return 1;
    };
    
	 /* in case of topmost call (st==NULL) return error */
	 /* otherwise it's OK, no more AVPs found */
    return ret; 
}
Example #21
0
int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp,
					struct db_param *dbp, struct db_url *url, int use_domain)
{
	struct sip_uri   uri;
	struct usr_avp   **avp_list;
	struct usr_avp   *avp;
	unsigned short   name_type;
	int              avp_name;
	int_str          i_s;
	str              uuid;
	int              keys_nr;
	int              n;
	pv_value_t xvalue;
	str *s0, *s1, *s2;
	str *sn;

	s0 = s1 = s2 = NULL;
	name_type = 0;
	if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) {
		LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops);
		goto error;
	}

	keys_nr = 6; /* uuid, avp name, avp val, avp type, user, domain */

	/* get uuid from avp */
	if (sp->opd&AVPOPS_VAL_PVAR)
	{
		if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0)
		{
			LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops);
			goto error;
		}
		if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
		{
			LM_ERR("no value for first param\n");
			goto error;
		}
		uuid = xvalue.rs;
	} else {
		uuid.s   = sp->u.s.s;
		uuid.len = sp->u.s.len;
	}

	if(sp->opd&AVPOPS_FLAG_UUID0)
	{
		s0 = &uuid;
	} else {
		/* parse uri */
		if (parse_uri(uuid.s, uuid.len, &uri)<0)
		{
			LM_ERR("failed to parse uri\n");
			goto error;
		}

		/* check uri */
		if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s)
		{
			LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s);
			goto error;
		}
		if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0))
			s1 = &uri.user;
		if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0))
			s2 = &uri.host;
	}

	/* set values for keys  */
	store_vals[0].val.str_val = (s0)?*s0:empty;
	store_vals[4].val.str_val = (s1)?*s1:empty;
	if (use_domain || sp->opd&AVPOPS_FLAG_DOMAIN0)
		store_vals[5].val.str_val = (s2)?*s2:empty;
	avp_name = -1;

	/* is dynamic avp name ? */
	if(dbp->a.type==AVPOPS_VAL_PVAR)
	{
		if(pv_has_dname(&dbp->a.u.sval))
		{
			/* TODO change here to be aware of the int name */
			if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0)
			{
				LM_CRIT("failed to get value for P2\n");
				goto error;
			}
			if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY))
			{
				LM_INFO("no value for P2\n");
				goto error;
			}
			if(xvalue.flags&PV_TYPE_INT)
			{
				name_type = 0;
				avp_name = xvalue.ri;
			} else {
				name_type = AVP_NAME_STR;
				avp_name = -1;
			}
			if(xvalue.flags&PV_VAL_STR)
			{
				if(xvalue.rs.len>=AVPOPS_ATTR_LEN)
				{
					LM_ERR("name too long [%d/%.*s...]\n",
						xvalue.rs.len, 16, xvalue.rs.s);
					goto error;
				}
				dbp->sa.s = avpops_attr_buf;
				memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len);
				dbp->sa.len = xvalue.rs.len;
				dbp->sa.s[dbp->sa.len] = '\0';
				avp_name = get_avp_id(&dbp->sa);
				/* search for the id only once */
				if (avp_name < 0) {
					LM_ERR("cannot find avp\n");
					goto error;
				}
			} else {
				LM_INFO("no string value for p2\n");
				goto error;
			}
		} else {
			name_type = dbp->a.u.sval.pvp.pvn.u.isname.type;
			avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name.n;
		}
	} else {
		LM_WARN("TODO: avp is not a dynamic name <%.*s> name is %d\n", dbp->sa.len, dbp->sa.s, avp_name);
		avp_name = -1;
	}

	/* set the script flags */
	if(dbp->a.type==AVPOPS_VAL_PVAR)
		name_type |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00;

	/* set uuid/(username and domain) fields */

	n =0 ;
	if ((dbp->a.opd&AVPOPS_VAL_NONE)==0)
	{
		/* if avp wasn't found yet */
		if (avp_name < 0) {
			avp_name = get_avp_id(&dbp->sa);
			/* search for the id only once */
			if (avp_name < 0) {
				LM_ERR("cannot find avp\n");
				goto error;
			}
		}
		/* avp name is known ->set it and its type */
		store_vals[1].val.str_val = dbp->sa; /*attr name*/
		avp = search_first_avp( 0, avp_name, &i_s, 0);
		for( ; avp; avp=search_first_avp( 0, avp_name, &i_s, avp))
		{
			/* don't insert avps which were loaded */
			if (avp->flags&AVP_IS_IN_DB)
				continue;
			/* set type */
			store_vals[3].val.int_val =
				(avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)|
				(avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT);
			/* set value */
			int_str2db_val( i_s, &store_vals[2].val.str_val,
				avp->flags&AVP_VAL_STR);
			/* save avp */
			if (db_store_avp( url, store_keys, store_vals,
					keys_nr, &dbp->table)==0 )
			{
				avp->flags |= AVP_IS_IN_DB;
				n++;
			}
		}
	} else {
		/* avp name is unknown -> go through all list */
		avp_list = get_avp_list();
		avp = *avp_list;

		for ( ; avp ; avp=avp->next )
		{
			/* don't insert avps which were loaded */
			if (avp->flags&AVP_IS_IN_DB)
				continue;

			/* set attribute name and type */
			if ( (sn=get_avp_name(avp))==0 )
				i_s.n = avp->id;
			else
				i_s.s = *sn;
			int_str2db_val( i_s, &store_vals[1].val.str_val, AVP_NAME_STR);
			store_vals[3].val.int_val =
				(avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)|
				(avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT);
			/* set avp value */
			get_avp_val( avp, &i_s);
			int_str2db_val( i_s, &store_vals[2].val.str_val,
				avp->flags&AVP_VAL_STR);
			/* save avp */
			if (db_store_avp( url, store_keys, store_vals,
			keys_nr, &dbp->table)==0)
			{
				avp->flags |= AVP_IS_IN_DB;
				n++;
			}
		}
	}

	LM_DBG(" %d avps were stored\n",n);

	return n==0?-1:1;
error:
	return -1;
}
Example #22
0
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure, others error
 */
int ospRequestRouting(
    struct sip_msg* msg,
    char* ignore1,
    char* ignore2)
{
    int i, errcode;
    char rn[OSP_STRBUF_SIZE];
    char cic[OSP_STRBUF_SIZE];
    int npdi;
    OSPE_OPERATOR_NAME type;
    char opname[OSPC_OPNAME_NUMBER][OSP_STRBUF_SIZE];
    osp_inbound inbound;
    char sourcebuf[OSP_STRBUF_SIZE];
    char srcdevbuf[OSP_STRBUF_SIZE];
    char divhostbuf[OSP_STRBUF_SIZE];
    char useragent[OSP_STRBUF_SIZE];
    struct usr_avp* avp = NULL;
    int_str avpval;
    unsigned int cinfonum = 0;
    char cinfo[OSP_DEF_CINFONUM][OSP_STRBUF_SIZE];
    char cinfostr[OSP_STRBUF_SIZE];
    unsigned int callidnumber = 1;
    OSPT_CALL_ID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    char tohost[OSP_STRBUF_SIZE];
    char tohostbuf[OSP_STRBUF_SIZE];
    const char* preferred[2] = { NULL };
    unsigned int destcount;
    struct timeval ts, te, td;
    char datebuf[OSP_STRBUF_SIZE];
    unsigned int sdpfpnum = 0;
    char sdpfp[OSP_DEF_SDPFPNUM][OSP_STRBUF_SIZE];
    char* sdpfpstr[OSP_DEF_SDPFPNUM];
    OSPTTRANHANDLE trans = -1;
    int result = MODULE_RETURNCODE_FALSE;

    ospInitInboundInfo(&inbound);

    if ((errcode = OSPPTransactionNew(_osp_provider, &trans)) != OSPC_ERR_NO_ERROR) {
        LM_ERR("failed to create new OSP transaction (%d)\n", errcode);
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LM_ERR("failed to extract call id\n");
    } else if (ospGetFromUser(msg, inbound.calling, sizeof(inbound.calling)) != 0) {
        LM_ERR("failed to extract calling number\n");
    } else if ((ospGetUriUser(msg, inbound.called, sizeof(inbound.called)) != 0) && (ospGetToUser(msg, inbound.called, sizeof(inbound.called)) != 0)) {
        LM_ERR("failed to extract called number\n");
    } else if (ospGetSource(msg, inbound.source, sizeof(inbound.source)) != 0) {
        LM_ERR("failed to extract source address\n");
    } else if (ospGetSrcDev(msg, inbound.srcdev, sizeof(inbound.srcdev)) != 0) {
        LM_ERR("failed to extract source deivce address\n");
    } else {
        inbound.authtime = time(NULL);

        if(msg->rcv.bind_address && msg->rcv.bind_address->address_str.s) {
            ospCopyStrToBuffer(&msg->rcv.bind_address->address_str, inbound.ingressaddr, sizeof(inbound.ingressaddr));
        }

        ospConvertToOutAddress(inbound.source, sourcebuf, sizeof(sourcebuf));
        ospConvertToOutAddress(inbound.srcdev, srcdevbuf, sizeof(srcdevbuf));

        switch (_osp_service_type) {
        case 1:
        case 2:
            OSPPTransactionSetServiceType(trans, (_osp_service_type == 1) ? OSPC_SERVICE_NPQUERY : OSPC_SERVICE_CNAMQUERY);

            ospGetToHost(msg, tohost, sizeof(tohost));
            ospConvertToOutAddress(tohost, tohostbuf, sizeof(tohostbuf));
            preferred[0] = tohostbuf;

            destcount = 1;
            break;
        case 0:
        default:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_VOICE);

            destcount = _osp_max_dests;
            break;
        }

        if (ospGetNpParam(msg, rn, sizeof(rn), cic, sizeof(cic), &npdi) == 0) {
            OSPPTransactionSetNumberPortability(trans, rn, cic, npdi);
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            if (ospGetOperatorName(msg, type, opname[type], sizeof(opname[type])) == 0) {
                OSPPTransactionSetOperatorName(trans, type, opname[type]);
            }
        }

        if (ospGetFromDisplay(msg, inbound.fromdisplay, sizeof(inbound.fromdisplay)) == 0) {
            OSPPTransactionSetFrom(trans, OSPC_NFORMAT_DISPLAYNAME, inbound.fromdisplay);
        }

        if (ospGetFromUri(msg, inbound.fromuri, sizeof(inbound.fromuri)) == 0) {
            OSPPTransactionSetFrom(trans, OSPC_NFORMAT_URL, inbound.fromuri);
        }

        if (ospGetToUri(msg, inbound.touri, sizeof(inbound.touri)) == 0) {
            OSPPTransactionSetTo(trans, OSPC_NFORMAT_URL, inbound.touri);
        }

        if (ospGetPaiUser(msg, inbound.paiuser, sizeof(inbound.paiuser)) == 0) {
            OSPPTransactionSetAssertedId(trans, OSPC_NFORMAT_E164, inbound.paiuser);
        }

        if (ospGetRpidUser(msg, inbound.rpiduser, sizeof(inbound.rpiduser)) == 0) {
            OSPPTransactionSetRemotePartyId(trans, OSPC_NFORMAT_E164, inbound.rpiduser);
        }

        if (ospGetPciUser(msg, inbound.pciuser, sizeof(inbound.pciuser)) == 0) {
            OSPPTransactionSetChargeInfo(trans, OSPC_NFORMAT_E164, inbound.pciuser);
        }

        if (ospGetDiversion(msg, inbound.divuser, sizeof(inbound.divuser), inbound.divhost, sizeof(inbound.divhost)) == 0) {
            ospConvertToOutAddress(inbound.divhost, divhostbuf, sizeof(divhostbuf));
        } else {
            divhostbuf[0] = '\0';
        }
        OSPPTransactionSetDiversion(trans, inbound.divuser, divhostbuf);

        if (ospGetUserAgent(msg, useragent, sizeof(useragent)) == 0) {
            OSPPTransactionSetUserAgent(trans, useragent);
        }

        OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);

        if (ospGetAVP(_osp_snid_avpid, _osp_snid_avptype, inbound.snid, sizeof(inbound.snid)) == 0) {
            OSPPTransactionSetNetworkIds(trans, inbound.snid, "");
        } else {
            inbound.snid[0] = '\0';
        }

        if (_osp_cinfo_avpid >= 0) {
            for (i = 0, avp = search_first_avp(_osp_cinfo_avptype, _osp_cinfo_avpid, NULL, 0);
                ((i < OSP_DEF_CINFONUM) && (avp != NULL));
                i++, avp = search_next_avp(avp, NULL))
            {
                get_avp_val(avp, &avpval);
                if ((avp->flags & AVP_VAL_STR) && (avpval.s.s && avpval.s.len)) {
                    snprintf(cinfo[i], sizeof(cinfo[i]), "%.*s", avpval.s.len, avpval.s.s);
                } else {
                    cinfo[i][0] = '\0';
                }
            }
            cinfonum = i;

            cinfostr[0] = '\0';
            for (i = 0; i < cinfonum; i++) {
                if (cinfo[cinfonum - i - 1][0] != '\0') {
                    OSPPTransactionSetCustomInfo(trans, i, cinfo[cinfonum - i - 1]);
                    snprintf(cinfostr + strlen(cinfostr), sizeof(cinfostr) - strlen(cinfostr), "custom_info%d '%s' ", i + 1, cinfo[cinfonum - i - 1]);
                }
            }
        }

        if (ospGetAVP(_osp_srcmedia_avpid, _osp_srcmedia_avptype, inbound.srcmedia, sizeof(inbound.srcmedia)) == 0) {
            OSPPTransactionSetSrcAudioAddr(trans, inbound.srcmedia);
        } else {
            inbound.srcmedia[0] = '\0';
        }

        inbound.date = 0;
        if (ospGetAVP(_osp_reqdate_avpid, _osp_reqdate_avptype, datebuf, sizeof(datebuf)) == 0) {
            if (ospStrToTime(datebuf, &inbound.date) == 0) {
                OSPPTransactionSetRequestDate(trans, inbound.date);
            }
        }

        if (_osp_sdpfp_avpid >= 0) {
            for (i = 0, avp = search_first_avp(_osp_sdpfp_avptype, _osp_sdpfp_avpid, NULL, 0);
                ((i < OSP_DEF_SDPFPNUM) && (avp != NULL));
                i++, avp = search_next_avp(avp, NULL))
            {
                get_avp_val(avp, &avpval);
                if ((avp->flags & AVP_VAL_STR) && (avpval.s.s && avpval.s.len)) {
                    snprintf(sdpfp[i], sizeof(sdpfp[i]), "%.*s", avpval.s.len, avpval.s.s);
                } else {
                    sdpfp[i][0] = '\0';
                }
            }
            sdpfpnum = i;

            for (i = 0; i < sdpfpnum; i++) {
                sdpfpstr[i] = sdpfp[sdpfpnum - i - 1];
            }

            OSPPTransactionSetFingerPrint(trans, sdpfpnum, (const char**)sdpfpstr);
        }

        ospReportIdentity(trans);

        LM_INFO("request auth and routing for: "
            "service '%d' "
            "source '%s' "
            "srcdev '%s' "
            "snid '%s' "
            "calling '%s' "
            "called '%s' "
            "preferred '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "fromdisplay '%s' "
            "paiuser '%s' "
            "rpiduser '%s' "
            "pciuser '%s' "
            "divuser '%s' "
            "divhost '%s' "
            "srcmedia '%s' "
            "callid '%.*s' "
            "destcount '%d' "
            "%s\n",
            _osp_service_type,
            sourcebuf,
            srcdevbuf,
            inbound.snid,
            inbound.calling,
            inbound.called,
            (preferred[0] == NULL) ? "" : preferred[0],
            rn,
            cic,
            npdi,
            /*
            opname[OSPC_OPNAME_SPID],
            opname[OSPC_OPNAME_OCN],
            opname[OSPC_OPNAME_SPN],
            opname[OSPC_OPNAME_ALTSPN],
            opname[OSPC_OPNAME_MCC],
            opname[OSPC_OPNAME_MNC],
            */
            inbound.fromdisplay,
            inbound.paiuser,
            inbound.rpiduser,
            inbound.pciuser,
            inbound.divuser,
            divhostbuf,
            inbound.srcmedia,
            callids[0]->Length,
            callids[0]->Value,
            destcount,
            cinfostr);

        gettimeofday(&ts, NULL);

        /* try to request authorization */
        errcode = OSPPTransactionRequestAuthorisation(
            trans,             /* transaction handle */
            sourcebuf,         /* from the configuration file */
            srcdevbuf,         /* source device of call, protocol specific, in OSP format */
            inbound.calling,   /* calling number in nodotted e164 notation */
            OSPC_NFORMAT_E164, /* calling number format */
            inbound.called,    /* called number */
            OSPC_NFORMAT_E164, /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        gettimeofday(&te, NULL);

        timersub(&te, &ts, &td);
        LM_INFO("authreq cost = %lu.%06lu for call-id '%.*s'\n", td.tv_sec, td.tv_usec, callids[0]->Length, callids[0]->Value);

        if ((errcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(trans, destcount, &inbound) == 0))
        {
            LM_INFO("there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->Length,
                callids[0]->Value);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LM_ERR("failed to request auth and routing (%d), call_id '%.*s'\n",
                errcode,
                callids[0]->Length,
                callids[0]->Value);
            switch (errcode) {
                case OSPC_ERR_HTTP_BAD_REQUEST:
                    result = -4000;
                    break;
                case OSPC_ERR_TRAN_BAD_REQUEST:
                    result = -4001;
                    break;
                case OSPC_ERR_HTTP_UNAUTHORIZED:
                    result = -4010;
                    break;
                case OSPC_ERR_TRAN_UNAUTHORIZED:
                    result = -4011;
                    break;
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -4030;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -4040;
                    break;
                case OSPC_ERR_TRAN_MAY_NOT_ORIGINATE:
                    result = -4050;
                    break;
                case OSPC_ERR_TRAN_CALLING_INVALID:
                    result = -4280;
                    break;
                case OSPC_ERR_SOCK_CONNECT_FAILED:
                    result = -4800;
                    break;
                case OSPC_ERR_SOCK_SELECT_FAILED:
                    result = -4801;
                    break;
                case OSPC_ERR_HTTP_SERVER_NOT_READY:
                    result = -4802;
                    break;
                case OSPC_ERR_TRAN_CALLED_FILTERING:
                    result = -4840;
                    break;
                case OSPC_ERR_HTTP_SERVICE_UNAVAILABLE:
                    result = -5030;
                    break;
                case OSPC_ERR_TRAN_DECLINE:
                    result = -6030;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = MODULE_RETURNCODE_ERROR;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (trans != -1) {
        OSPPTransactionDelete(trans);
    }

    return result;
}
Example #23
0
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure, MODULE_RETURNCODE_ERROR error
 */
int ospRequestRouting(
    struct sip_msg* msg,
    char* ignore1,
    char* ignore2)
{
    int errcode;
    time_t authtime;
    char calling[OSP_STRBUF_SIZE];
    char called[OSP_STRBUF_SIZE];
    char rn[OSP_STRBUF_SIZE];
    char cic[OSP_STRBUF_SIZE];
    int npdi;
    OSPE_OPERATOR_NAME type;
    char opname[OSPC_OPNAME_NUMBER][OSP_STRBUF_SIZE];
    char source[OSP_STRBUF_SIZE];
    char sourcebuf[OSP_STRBUF_SIZE];
    char srcdev[OSP_STRBUF_SIZE];
    char srcdevbuf[OSP_STRBUF_SIZE];
    char rpid[OSP_STRBUF_SIZE];
    char pai[OSP_STRBUF_SIZE];
    char divuser[OSP_STRBUF_SIZE];
    char divhost[OSP_STRBUF_SIZE];
    char divhostbuf[OSP_STRBUF_SIZE];
    char pci[OSP_STRBUF_SIZE];
    struct usr_avp* snidavp = NULL;
    int_str snidval;
    char snid[OSP_STRBUF_SIZE];
    struct usr_avp* cinfoavp = NULL;
    int_str cinfoval;
    unsigned int cinfonum = 0, i;
    char cinfo[OSP_DEF_CINFOS][OSP_STRBUF_SIZE];
    char cinfostr[OSP_STRBUF_SIZE];
    unsigned int callidnumber = 1;
    OSPT_CALL_ID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    char tohost[OSP_STRBUF_SIZE];
    char tohostbuf[OSP_STRBUF_SIZE];
    const char* preferred[2] = { NULL };
    unsigned int destcount;
    OSPTTRANHANDLE trans = -1;
    int result = MODULE_RETURNCODE_FALSE;

    if ((errcode = OSPPTransactionNew(_osp_provider, &trans)) != OSPC_ERR_NO_ERROR) {
        LM_ERR("failed to create new OSP transaction (%d)\n", errcode);
    } else if (ospGetFromUserpart(msg, calling, sizeof(calling)) != 0) {
        LM_ERR("failed to extract calling number\n");
    } else if ((ospGetUriUserpart(msg, called, sizeof(called)) != 0) && (ospGetToUserpart(msg, called, sizeof(called)) != 0)) {
        LM_ERR("failed to extract called number\n");
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LM_ERR("failed to extract call id\n");
    } else if (ospGetSource(msg, source, sizeof(source)) != 0) {
        LM_ERR("failed to extract source address\n");
    } else if (ospGetSourceDevice(msg, srcdev, sizeof(srcdev)) != 0) {
        LM_ERR("failed to extract source deivce address\n");
    } else {
        authtime = time(NULL);

        ospConvertToOutAddress(source, sourcebuf, sizeof(sourcebuf));
        ospConvertToOutAddress(srcdev, srcdevbuf, sizeof(srcdevbuf));

        switch (_osp_service_type) {
        case 1:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_NPQUERY);

            ospGetToHostpart(msg, tohost, sizeof(tohost));
            ospConvertToOutAddress(tohost, tohostbuf, sizeof(tohostbuf));
            preferred[0] = tohostbuf;

            destcount = 1;
            break;
        case 0:
        default:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_VOICE);

            destcount = _osp_max_dests;
            break;
        }

        if (ospGetNpParameters(msg, rn, sizeof(rn), cic, sizeof(cic), &npdi) == 0) {
            OSPPTransactionSetNumberPortability(trans, rn, cic, npdi);
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            if (ospGetOperatorName(msg, type, opname[type], sizeof(opname[type])) == 0) {
                OSPPTransactionSetOperatorName(trans, type, opname[type]);
            }
        }

        if (ospGetRpidUserpart(msg, rpid, sizeof(rpid)) == 0) {
            OSPPTransactionSetRemotePartyId(trans, OSPC_NFORMAT_E164, rpid);
        }

        if (ospGetPaiUserpart(msg, pai, sizeof(pai)) == 0) {
            OSPPTransactionSetAssertedId(trans, OSPC_NFORMAT_E164, pai);
        }

        if (ospGetDiversion(msg, divuser, sizeof(divuser), divhost, sizeof(divhost)) == 0) {
            ospConvertToOutAddress(divhost, divhostbuf, sizeof(divhostbuf));
        } else {
            divhostbuf[0] = '\0';
        }
        OSPPTransactionSetDiversion(trans, divuser, divhostbuf);

        OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);

        if (ospGetPChargeInfoUserpart(msg, pci, sizeof(pci)) == 0) {
            OSPPTransactionSetChargeInfo(trans, OSPC_NFORMAT_E164, pci);
        }

        if ((_osp_snid_avpid >= 0) &&
            ((snidavp = search_first_avp(_osp_snid_avptype, _osp_snid_avpid, &snidval, 0)) != NULL) &&
            (snidavp->flags & AVP_VAL_STR) && (snidval.s.s && snidval.s.len))
        {
            snprintf(snid, sizeof(snid), "%.*s", snidval.s.len, snidval.s.s);
            snid[sizeof(snid) - 1] = '\0';
            OSPPTransactionSetNetworkIds(trans, snid, "");
        } else {
            snid[0] = '\0';
        }

        if (_osp_cinfo_avpid >= 0) {
            for (i = 0, cinfoavp = search_first_avp(_osp_cinfo_avptype, _osp_cinfo_avpid, NULL, 0);
                ((i < OSP_DEF_CINFOS) && (cinfoavp != NULL));
                i++, cinfoavp = search_next_avp(cinfoavp, NULL))
            {
                get_avp_val(cinfoavp, &cinfoval);
                if ((cinfoavp->flags & AVP_VAL_STR) && (cinfoval.s.s && cinfoval.s.len)) {
                    snprintf(cinfo[i], sizeof(cinfo[i]), "%.*s", cinfoval.s.len, cinfoval.s.s);
                    cinfo[i][sizeof(cinfo[i]) - 1] = '\0';
                } else {
                    cinfo[i][0] = '\0';
                }
            }
            cinfonum = i;

            cinfostr[0] = '\0';
            for (i = 0; i < cinfonum; i++) {
                if (cinfo[cinfonum - i - 1][0] != '\0') {
                    OSPPTransactionSetCustomInfo(trans, i, cinfo[cinfonum - i - 1]);
                    snprintf(cinfostr + strlen(cinfostr), sizeof(cinfostr) - strlen(cinfostr), "custom_info%d '%s' ", i + 1, cinfo[cinfonum - i - 1]);
                }
            }
            cinfostr[sizeof(cinfostr) - 1] = '\0';
        }

        LM_INFO("request auth and routing for: "
            "service_type '%d' "
            "source '%s' "
            "source_dev '%s' "
            "source_networkid '%s' "
            "calling '%s' "
            "called '%s' "
            "preferred '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "rpid '%s' "
            "pai '%s' "
            "div_user '%s' "
            "div_host '%s' "
            "pci '%s' "
            "call_id '%.*s' "
            "dest_count '%d' "
            "%s\n",
            _osp_service_type,
            sourcebuf,
            srcdevbuf,
            snid,
            calling,
            called,
            (preferred[0] == NULL) ? "" : preferred[0],
            rn,
            cic,
            npdi,
            /*
            opname[OSPC_OPNAME_SPID],
            opname[OSPC_OPNAME_OCN],
            opname[OSPC_OPNAME_SPN],
            opname[OSPC_OPNAME_ALTSPN],
            opname[OSPC_OPNAME_MCC],
            opname[OSPC_OPNAME_MNC],
            */
            rpid,
            pai,
            divuser,
            divhostbuf,
            pci,
            callids[0]->Length,
            callids[0]->Value,
            destcount,
            cinfostr);

        /* try to request authorization */
        errcode = OSPPTransactionRequestAuthorisation(
            trans,             /* transaction handle */
            sourcebuf,         /* from the configuration file */
            srcdevbuf,         /* source device of call, protocol specific, in OSP format */
            calling,           /* calling number in nodotted e164 notation */
            OSPC_NFORMAT_E164, /* calling number format */
            called,            /* called number */
            OSPC_NFORMAT_E164, /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        if ((errcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(trans, destcount, source, srcdev, called, authtime, rpid, pai, divuser, divhostbuf, pci) == 0))
        {
            LM_INFO("there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->Length,
                callids[0]->Value);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LM_ERR("failed to request auth and routing (%d), call_id '%.*s'\n",
                errcode,
                callids[0]->Length,
                callids[0]->Value);
            switch (errcode) {
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -403;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -404;
                    break;
                case OSPC_ERR_TRAN_CALLING_INVALID:
                    result = -428;
                    break;
                case OSPC_ERR_TRAN_CALLED_FILTERING:
                    result = -484;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = MODULE_RETURNCODE_ERROR;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (trans != -1) {
        OSPPTransactionDelete(trans);
    }

    return result;
}