Exemplo n.º 1
0
/**
 * @brief Get a subscription from the subscription list based on the IMPI
 *  NB - does not return with a lock on the subscription but does increment ref count
 * @param impu string of impu to search for
 * @param s ims_subscription to be returned if found
 * @param leave_slot_locked if no subscription is found return with the slot locked (in case we want to add) 
 * @return 0 on success
 */
int get_subscription(str* impi_s, ims_subscription** s, int leave_slot_locked) {
    int subscription_hash, sl;
    ims_subscription* ptr;

    subscription_hash = core_hash(impi_s, 0, 0);
    sl = subscription_hash & (subs_hash_size - 1);
    lock_subscription_slot(sl);
    ptr = ims_subscription_list->slot[sl].first;
    while (ptr) {
        if ((impi_s->len == ptr->private_identity.len) && (memcmp(impi_s->s, ptr->private_identity.s, impi_s->len) == 0)) {
            LM_DBG("found an existing subscription for IMPI [%.*s]\n", impi_s->len, impi_s->s);
            (*s) = ptr;
            lock_subscription(ptr);
            ref_subscription_unsafe(ptr);
            unlock_subscription(ptr);
            unlock_subscription_slot(sl);
            return 0;
        }
        ptr = ptr->next;
    }
    if (!leave_slot_locked)
        unlock_subscription_slot(sl);
    return 1;
}
Exemplo n.º 2
0
/*
 * get all IMPUs as string from a subscription related to an impurecord. apply filter for barring (assumed to be called with lock on impurec)
 * barring-1 get all barred
 * barring-0 get all unbarred
 * barring-(-1) get all records
 * NB. Remember to free the block of memory pointed to by impus (pkg_malloc)
 */
int get_impus_from_subscription_as_string(udomain_t* _d, impurecord_t* impu_rec, int barring, str** impus, int* num_impus) {
    int i, j, count;
    *num_impus = 0;
    *impus = 0;
    ims_public_identity* impi;
    int bytes_needed = 0;
    int len = 0;

    LM_DBG("getting IMPU subscription set\n");

    if (!impu_rec) {
	LM_ERR("no impu record provided\n");
	return 1;
    }

    if (!impu_rec->s) {
	LM_DBG("no subscription associated with impu\n");
	return 0;
    }

    lock_subscription(impu_rec->s);
    for (i = 0; i < impu_rec->s->service_profiles_cnt; i++) {
	for (j = 0; j < impu_rec->s->service_profiles[i].public_identities_cnt; j++) {
	    impi = &(impu_rec->s->service_profiles[i].public_identities[j]);
	    if (barring < 0) {
		//get all records
		bytes_needed += impi->public_identity.len;
		(*num_impus)++;
	    } else {
		if (impi->barring == barring) {
		    //add the record to the list
		    bytes_needed += impi->public_identity.len;
		    (*num_impus)++;
		}
	    }
	}
    }
    LM_DBG("num of records returned is %d and we need %d bytes\n", *num_impus, bytes_needed);

    len = (sizeof (str)*(*num_impus)) + bytes_needed;
    *impus = (str*) pkg_malloc(len);
    if (*impus == 0) {
	LM_ERR("no more pkg_mem\n");
	return 0;
    }
    char* ptr = (char*) (*impus + *num_impus);

    //now populate the data
    count = 0;
    for (i = 0; i < impu_rec->s->service_profiles_cnt; i++) {
	for (j = 0; j < impu_rec->s->service_profiles[i].public_identities_cnt; j++) {
	    impi = &(impu_rec->s->service_profiles[i].public_identities[j]);
	    if (barring < 0) {
		//get all records
		(*impus)[count].s = ptr;
		memcpy(ptr, impi->public_identity.s, impi->public_identity.len);
		(*impus)[count].len = impi->public_identity.len;
		ptr += impi->public_identity.len;
		count++;
	    } else {
		if (impi->barring == barring) {
		    //add the record to the list
		    (*impus)[count].s = ptr;
		    memcpy(ptr, impi->public_identity.s, impi->public_identity.len);
		    (*impus)[count].len = impi->public_identity.len;
		    ptr += impi->public_identity.len;
		    count++;
		}
	    }
	}
    }

    if (ptr != ((char*) *impus + len)) {
	LM_CRIT("buffer overflow\n");
	return 1;
    }

    unlock_subscription(impu_rec->s);

    return 0;
}
Exemplo n.º 3
0
static void ul_rpc_show_impu(rpc_t* rpc, void* ctx) {
    int i, j;
    str impu;
    int res;
    udomain_t* domain;
    struct impurecord* impu_rec;
    ucontact_t* contact;
    void *ah, *sh, *ch, *cdh, *sdh, *sph, *spi;
    char numstr[21 + 16]; //enough for all numbers up to 64bits + longest length of field name (16)

    if (rpc->scan(ctx, "S", &impu) < 1) {
	rpc->fault(ctx, 400, "required IMPU argument");
	return;
    }

    LM_DBG("searching for impu <%.*s>\n", impu.len, impu.s);

    res = get_udomain("location", &domain);
    if (res != 0) {
	LM_ERR("Failed to get domain\n");
	return;
    }

    lock_udomain(domain, &impu);
    res = get_impurecord(domain, &impu, &impu_rec);
    if (res != 0) {
	unlock_udomain(domain, &impu);
	return;
    }

    //now print the data for this IMPU record
    if (rpc->add(ctx, "{", &ah) < 0) {
	rpc->fault(ctx, 500, "Internal error creating IMPU struct");
	unlock_udomain(domain, &impu);
	return;
    }

    if (rpc->struct_add(ah, "SsdSSSS",
	    "impu", &impu,
	    "state", get_impu_regstate_as_string(impu_rec->reg_state),
	    "barring", impu_rec->barring,
	    "ccf1", &impu_rec->ccf1,
	    "ccf2", &impu_rec->ccf2,
	    "ecf1", &impu_rec->ecf1,
	    "ecf2", &impu_rec->ecf2
	    ) < 0) {
	rpc->fault(ctx, 500, "Internal error adding impu data");
	unlock_udomain(domain, &impu);
	return;
    }

    if (rpc->struct_add(ah, "{", "subscription", &sh) < 0) {
	rpc->fault(ctx, 500, "Internal error adding impu subscription data");
	unlock_udomain(domain, &impu);
	return;
    }

    ims_subscription* subscription = impu_rec->s;
    lock_subscription(subscription);
    //add subscription data
    if (rpc->struct_add(sh, "S{", "impi", &subscription->private_identity, "service profiles", &sph) < 0) {
	rpc->fault(ctx, 500, "Internal error adding impu subscription data");
	unlock_subscription(subscription);
	unlock_udomain(domain, &impu);
	return;
    }

    //add subscription detail information
    for (i = 0; i < subscription->service_profiles_cnt; i++) {
	sprintf(numstr, "%d", i + 1);
	if (rpc->struct_add(sph, "{", numstr, &sdh) < 0) {
	    rpc->fault(ctx, 500, "Internal error adding impu subscription detail data");
	    unlock_subscription(subscription);
	    unlock_udomain(domain, &impu);
	    return;
	}
	if (rpc->struct_add(sdh, "{", "impus", &spi) < 0) {
	    rpc->fault(ctx, 500, "Internal error adding impu subscription data");
	    unlock_subscription(subscription);
	    unlock_udomain(domain, &impu);
	    return;
	}

	for (j = 0; j < subscription->service_profiles[i].public_identities_cnt; j++) {
	    sprintf(numstr, "%d", j + 1);
	    if (rpc->struct_add(spi, "S", numstr, &subscription->service_profiles[i].public_identities[j].public_identity) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu subscription detail data");
		unlock_subscription(subscription);
		unlock_udomain(domain, &impu);
		return;
	    }
	}
    }

    unlock_subscription(subscription);

    //add contact data
    if (rpc->struct_add(ah, "{", "contacts", &ch) < 0) {
	rpc->fault(ctx, 500, "Internal error adding impu contact data");
	unlock_udomain(domain, &impu);
	return;
    }

    i = 0;

    if (impu_rec->num_contacts > 0 && impu_rec->newcontacts[0]) {
	while (i < MAX_CONTACTS_PER_IMPU && (contact = impu_rec->newcontacts[i++])) {
	    //contact is not null terminated so we need to create a null terminated version
	    if (!contact_buf.s || (contact_buf.len <= contact->c.len)) {
		if (contact_buf.s && contact_buf.len <= contact->c.len) {
		    pkg_free(contact_buf.s);
		}
		contact_buflen = contact->c.len + 1;
		contact_buf.s = (char*) pkg_malloc(contact_buflen);
		if (!contact_buf.s) {
		    LM_ERR("no more pkg memory");
		    rpc->fault(ctx, 500, "Internal error adding impu contact header");
		    unlock_udomain(domain, &impu);
		    return;
		}
	    }
	    memcpy(contact_buf.s, contact->c.s, contact->c.len);
	    contact_buf.s[contact->c.len] = '\0';
	    contact_buf.len = contact->c.len;

	    LM_DBG("contact is %s\n", contact_buf.s);
	    if (rpc->struct_add(ch, "{", contact_buf.s, &cdh) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu contact header");
		unlock_udomain(domain, &impu);
		return;
	    }
	    if (rpc->struct_add(cdh, "dS",
		    "expires", contact->expires - time(NULL),
		    "client", &contact->user_agent) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu contact data");
		unlock_udomain(domain, &impu);
		return;
	    }
	    contact = contact->next;
	}
    }

    unlock_udomain(domain, &impu);

}