PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
						    int cred_cnt,
						    const pjsip_cred_info *c)
{
    PJ_ASSERT_RETURN(sess && c, PJ_EINVAL);

    if (cred_cnt == 0) {
	sess->cred_cnt = 0;
    } else {
	int i;
	sess->cred_info = (pjsip_cred_info*)
			  pj_pool_alloc(sess->pool, cred_cnt * sizeof(*c));
	for (i=0; i<cred_cnt; ++i) {
	    sess->cred_info[i].data_type = c[i].data_type;

	    /* When data_type is PJSIP_CRED_DATA_EXT_AKA,
	     * callback must be specified.
	     */
	    if ((c[i].data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {

#if !PJSIP_HAS_DIGEST_AKA_AUTH
		if (!PJSIP_HAS_DIGEST_AKA_AUTH) {
		    pj_assert(!"PJSIP_HAS_DIGEST_AKA_AUTH is not enabled");
		    return PJSIP_EAUTHINAKACRED;
		}
#endif

		/* Callback must be specified */
		PJ_ASSERT_RETURN(c[i].ext.aka.cb != NULL, PJ_EINVAL);

		/* Verify K len */
		PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN,
				 PJSIP_EAUTHINAKACRED);

		/* Verify OP len */
		PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN,
				 PJSIP_EAUTHINAKACRED);

		/* Verify AMF len */
		PJ_ASSERT_RETURN(c[i].ext.aka.amf.slen <= PJSIP_AKA_AMFLEN,
				 PJSIP_EAUTHINAKACRED);

		sess->cred_info[i].ext.aka.cb = c[i].ext.aka.cb;
		pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.k,
			  &c[i].ext.aka.k);
		pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.op,
			  &c[i].ext.aka.op);
		pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.amf,
			  &c[i].ext.aka.amf);
	    }

	    pj_strdup(sess->pool, &sess->cred_info[i].scheme, &c[i].scheme);
	    pj_strdup(sess->pool, &sess->cred_info[i].realm, &c[i].realm);
	    pj_strdup(sess->pool, &sess->cred_info[i].username, &c[i].username);
	    pj_strdup(sess->pool, &sess->cred_info[i].data, &c[i].data);
	}
	sess->cred_cnt = cred_cnt;
    }

    return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
						    int cred_cnt,
						    const pjsip_cred_info *c)
{
    PJ_ASSERT_RETURN(sess && c, PJ_EINVAL);

    if (cred_cnt == 0) {
	sess->cred_cnt = 0;
    } else {
	int i;
	sess->cred_info = (pjsip_cred_info*)
			  pj_pool_alloc(sess->pool, cred_cnt * sizeof(*c));
	for (i=0; i<cred_cnt; ++i) {
	    sess->cred_info[i].data_type = c[i].data_type;

	     
	    if ((c[i].data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {

#if !PJSIP_HAS_DIGEST_AKA_AUTH
		if (!PJSIP_HAS_DIGEST_AKA_AUTH) {
		    pj_assert(!"PJSIP_HAS_DIGEST_AKA_AUTH is not enabled");
		    return PJSIP_EAUTHINAKACRED;
		}
#endif

		 
		PJ_ASSERT_RETURN(c[i].ext.aka.cb != NULL, PJ_EINVAL);

		 
		PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN,
				 PJSIP_EAUTHINAKACRED);

		 
		PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN,
				 PJSIP_EAUTHINAKACRED);

		 
		PJ_ASSERT_RETURN(c[i].ext.aka.amf.slen <= PJSIP_AKA_AMFLEN,
				 PJSIP_EAUTHINAKACRED);

		sess->cred_info[i].ext.aka.cb = c[i].ext.aka.cb;
		pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.k,
			  &c[i].ext.aka.k);
		pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.op,
			  &c[i].ext.aka.op);
		pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.amf,
			  &c[i].ext.aka.amf);
	    }

	    pj_strdup(sess->pool, &sess->cred_info[i].scheme, &c[i].scheme);
	    pj_strdup(sess->pool, &sess->cred_info[i].realm, &c[i].realm);
	    pj_strdup(sess->pool, &sess->cred_info[i].username, &c[i].username);
	    pj_strdup(sess->pool, &sess->cred_info[i].data, &c[i].data);
	}
	sess->cred_cnt = cred_cnt;
    }

    return PJ_SUCCESS;
}