cr_carrier.c

Go to the documentation of this file.
00001 /*
00002  * $Id: cr_carrier.c 5240 2008-11-21 10:33:16Z henningw $
00003  *
00004  * Copyright (C) 2007-2008 1&1 Internet AG
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 /**
00024  * \file cr_carrier.c
00025  * \brief Contains the functions to manage carrier data.
00026  * \ingroup carrierroute
00027  * - Module; \ref carrierroute
00028  */
00029 
00030 #include <stdlib.h>
00031 #include "../../mem/shm_mem.h"
00032 #include "../../ut.h"
00033 #include "cr_carrier.h"
00034 #include "cr_domain.h"
00035 #include "cr_map.h"
00036 
00037 
00038 /**
00039  * Create a new carrier_data struct in shared memory and set it up.
00040  *
00041  * @param carrier_id id of carrier
00042  * @param carrier_name pointer to the name of the carrier
00043  * @param domains number of domains for that carrier
00044  *
00045  * @return a pointer to the newly allocated carrier data or NULL on
00046  * error, in which case it LOGs an error message.
00047  */
00048 struct carrier_data_t * create_carrier_data(int carrier_id, str *carrier_name, int domains) {
00049    struct carrier_data_t * tmp;
00050    if ((tmp = shm_malloc(sizeof(struct carrier_data_t))) == NULL) {
00051       SHM_MEM_ERROR;
00052       return NULL;
00053    }
00054    memset(tmp, 0, sizeof(struct carrier_data_t));
00055    tmp->id = carrier_id;
00056    tmp->name = carrier_name;
00057    tmp->domain_num = domains;
00058    if(domains > 0){
00059       if ((tmp->domains = shm_malloc(sizeof(struct domain_data_t *) * domains)) == NULL) {
00060          SHM_MEM_ERROR;
00061          shm_free(tmp);
00062          return NULL;
00063       }
00064       memset(tmp->domains, 0, sizeof(struct domain_data_t *) * domains);
00065    }
00066    return tmp;
00067 }
00068 
00069 
00070 /**
00071  * Destroys the given carrier and frees the used memory.
00072  *
00073  * @param carrier_data the structure to be destroyed.
00074  */
00075 void destroy_carrier_data(struct carrier_data_t *carrier_data) {
00076    int i;
00077    if (carrier_data) {
00078       if (carrier_data->domains != NULL) {
00079          for (i=0; i<carrier_data->domain_num; i++) {
00080             destroy_domain_data(carrier_data->domains[i]);
00081          }
00082          shm_free(carrier_data->domains);
00083       }
00084       shm_free(carrier_data);
00085    }
00086 }
00087 
00088 
00089 /**
00090  * Adds a domain_data struct to the given carrier data structure at the given index.
00091  * Other etries are moved one position up to make space for the new one.
00092  *
00093  * @param carrier_data the carrier data struct where domain_data should be inserted
00094  * @param domain_data the domain data struct to be inserted
00095  * @param index the index where to insert the domain_data structure in the domain array
00096  *
00097  * @return 0 on success, -1 on failure
00098  */
00099 int add_domain_data(struct carrier_data_t * carrier_data, struct domain_data_t * domain_data, int index) {
00100    LM_INFO("adding domain %d '%.*s' to carrier %d '%.*s'", domain_data->id, domain_data->name->len, domain_data->name->s, carrier_data->id, carrier_data->name->len, carrier_data->name->s);
00101    LM_DBG("domain position %d (domain_num=%d, first_empty_domain=%d)", index, (int) carrier_data->domain_num, (int) carrier_data->first_empty_domain);
00102 
00103    if ((index < 0) || (index > carrier_data->first_empty_domain)) {
00104       LM_ERR("got invalid index during binary search\n");
00105       return -1;
00106    }
00107       
00108    if (carrier_data->first_empty_domain >= carrier_data->domain_num) {
00109       LM_ERR("cannot add new domain '%.*s' into carrier '%.*s' - array already full\n", domain_data->name->len, domain_data->name->s, carrier_data->name->len, carrier_data->name->s);
00110       return -1;
00111    }
00112 
00113    if (index < carrier_data->first_empty_domain) {
00114       /* move other entries one position up */
00115       memmove(&carrier_data->domains[index+1], &carrier_data->domains[index], sizeof(struct domain_data_t *)*(carrier_data->first_empty_domain-index));
00116    }
00117    carrier_data->domains[index] = domain_data;
00118    carrier_data->first_empty_domain++;
00119 
00120    return 0;
00121 }
00122 
00123 
00124 /**
00125  * Returns the domain data for the given id by doing a binary search.
00126  * @note The domain array must be sorted!
00127  *
00128  * @param carrier_data carrier data to be searched
00129  * @param domain_id the id of desired domain
00130  *
00131  * @return a pointer to the desired domain data, NULL if not found.
00132  */
00133 struct domain_data_t * get_domain_data(struct carrier_data_t * carrier_data, int domain_id) {
00134    struct domain_data_t **ret;
00135    struct domain_data_t key;
00136    struct domain_data_t *pkey = &key;
00137 
00138    if (!carrier_data) {
00139       LM_ERR("NULL pointer in parameter\n");
00140       return NULL;
00141    }
00142    key.id = domain_id;
00143    ret = bsearch(&pkey, carrier_data->domains, carrier_data->domain_num, sizeof(carrier_data->domains[0]), compare_domain_data);
00144    if (ret) return *ret;
00145    return NULL;
00146 }
00147 
00148 
00149 /**
00150  * Compares the IDs of two carrier data structures.
00151  * A NULL pointer is always greater than any ID.
00152  *
00153  * @return -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2
00154  */
00155 int compare_carrier_data(const void *v1, const void *v2) {
00156   struct carrier_data_t *c1 = *(struct carrier_data_t * const *)v1;
00157    struct carrier_data_t *c2 = *(struct carrier_data_t * const *)v2;
00158    if (c1 == NULL) {
00159       if (c2 == NULL) return 0;
00160       else return 1;
00161    }
00162    else {
00163       if (c2 == NULL) return -1;
00164       else {
00165          if (c1->id < c2->id) return -1;
00166          else if (c1->id > c2->id) return 1;
00167          else return 0;
00168       }
00169    }
00170 }

Generated on Mon May 21 18:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6