init ems server code
This commit is contained in:
379
plat/public/src/uwav/number.c
Normal file
379
plat/public/src/uwav/number.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* public/uwav/number.c
|
||||
*
|
||||
* Copyright (C) 2008 ADC, Inc
|
||||
* Written by: Xinyu Yan <xinyu.yan@adc.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "./number.h"
|
||||
|
||||
/*
|
||||
ITU:
|
||||
0-spare
|
||||
1-subscriber
|
||||
2-unknown
|
||||
3-NDD
|
||||
4-IDD
|
||||
|
||||
GSM 09.02:
|
||||
-- bits 765: nature of address indicator
|
||||
-- 000 unknown
|
||||
-- 001 international number
|
||||
-- 010 national significant number
|
||||
-- 011 network specific number
|
||||
-- 100 subscriber number
|
||||
-- 101 reserved
|
||||
-- 110 abbreviated number
|
||||
-- 111 reserved for extension
|
||||
*/
|
||||
|
||||
static const u8 NAI_GSM2ITU[8] = {0x02, 0x04, 0x03, 0x03, 0x01, 0x02, 0x02, 0x02};
|
||||
static const u8 NAI_ITU2GSM[8] = {0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00};
|
||||
|
||||
u8 nai_gsm_to_itu(u8 nai)
|
||||
{
|
||||
return NAI_GSM2ITU[nai & 0x07];
|
||||
}
|
||||
|
||||
u8 nai_itu_to_gsm(u8 nai)
|
||||
{
|
||||
return NAI_ITU2GSM[nai & 0x07];
|
||||
}
|
||||
|
||||
void num_itu_to_gsm(num32_t *gsm_num, const num32_t *itu_num)
|
||||
{
|
||||
int i;
|
||||
|
||||
gsm_num->num_of_digit = itu_num->num_of_digit;
|
||||
|
||||
for(i = 0; i < itu_num->num_of_digit; i++)
|
||||
{
|
||||
if(itu_num->digit[i] == 0x0b)
|
||||
gsm_num->digit[i] = 0x0a;
|
||||
else if(itu_num->digit[i] == 0x0c)
|
||||
gsm_num->digit[i] = 0x0b;
|
||||
else
|
||||
gsm_num->digit[i] = itu_num->digit[i];
|
||||
}
|
||||
}
|
||||
|
||||
u8 *msc_isdn_to_bcd(u8 *bcd, const isdn_t *isdn)
|
||||
{
|
||||
int i;
|
||||
const num32_t *num = &isdn->num;
|
||||
u8 *bcdptr;
|
||||
|
||||
bcd[0] = (num->num_of_digit+1)/2 + 1;
|
||||
bcd[1] = 0x81 | (nai_itu_to_gsm(isdn->nai) << 4);
|
||||
bcdptr = bcd + 2;
|
||||
for(i = 0; ((i < 32) && (i < num->num_of_digit)); i++)
|
||||
{
|
||||
if((i & 1) == 0)
|
||||
*bcdptr = (num->digit[i] << 4) | 0x0f;
|
||||
else
|
||||
{
|
||||
*bcdptr = (*bcdptr & 0xf0) + num->digit[i];
|
||||
bcdptr++;
|
||||
}
|
||||
}
|
||||
return bcd;
|
||||
}
|
||||
|
||||
isdn_t *netbcd_to_isdn(isdn_t *isdn, const u8 *bcd)
|
||||
{
|
||||
u8 bcd_digits;
|
||||
u8 digit;
|
||||
num32_t *num = &isdn->num;
|
||||
|
||||
if(bcd[0] < 1)
|
||||
{
|
||||
num->num_of_digit = 0;
|
||||
return isdn;
|
||||
}
|
||||
bcd_digits = (bcd[0]-1) * 2;
|
||||
isdn->nai = nai_gsm_to_itu((bcd[1] >> 4) & 0x07);
|
||||
bcd += 2;
|
||||
for(num->num_of_digit = 0; (num->num_of_digit<32)&&(num->num_of_digit<bcd_digits); num->num_of_digit++)
|
||||
{
|
||||
if((num->num_of_digit & 1) == 0)
|
||||
digit = *bcd & 0x0f;
|
||||
else
|
||||
digit = *(bcd++) >> 4;
|
||||
if(is_dail_digit(digit))
|
||||
num->digit[num->num_of_digit] = digit;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return isdn;
|
||||
}
|
||||
|
||||
u8 *isdn_to_netbcd(u8 *bcd, const isdn_t *isdn)
|
||||
{
|
||||
int i;
|
||||
const num32_t *num = &isdn->num;
|
||||
u8 *bcdptr;
|
||||
|
||||
bcd[0] = (num->num_of_digit+1)/2 + 1;
|
||||
bcd[1] = 0x81 | (nai_itu_to_gsm(isdn->nai) << 4);
|
||||
bcdptr = bcd + 2;
|
||||
for(i = 0; ((i < 32) && (i < num->num_of_digit)); i++)
|
||||
{
|
||||
if((i & 1) == 0)
|
||||
*bcdptr = 0xf0 + (num->digit[i] & 0x0f);
|
||||
else
|
||||
{
|
||||
*bcdptr = (num->digit[i] << 4) | (*bcdptr & 0x0f);
|
||||
bcdptr++;
|
||||
}
|
||||
}
|
||||
return bcd;
|
||||
}
|
||||
|
||||
/* TBCD: Telephony Binary Coded Decimal (GSM 09.02) */
|
||||
int tbcd_to_string(char *str, const u8 *tbcd, u8 tbcd_len)
|
||||
{
|
||||
int i;
|
||||
u8 max_digits;
|
||||
u8 digit;
|
||||
|
||||
max_digits = tbcd_len * 2;
|
||||
for(i = 0; i < max_digits; i++)
|
||||
{
|
||||
if((i & 1) == 0)
|
||||
digit = *tbcd & 0x0f;
|
||||
else
|
||||
digit = *(tbcd++) >> 4;
|
||||
if(is_dail_digit(digit))
|
||||
digit_to_char(str[i], digit);
|
||||
else
|
||||
break;
|
||||
}
|
||||
str[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
isdn_t *tpaddr_to_isdn(isdn_t *isdn, const u8 *tpaddr)
|
||||
{
|
||||
u8 bcd_digits;
|
||||
u8 digit;
|
||||
num32_t *num = &isdn->num;
|
||||
|
||||
bcd_digits = tpaddr[0];
|
||||
isdn->nai = nai_gsm_to_itu((tpaddr[1] >> 4) & 0x07);
|
||||
tpaddr += 2;
|
||||
for(num->num_of_digit = 0; (num->num_of_digit<32)&&(num->num_of_digit<bcd_digits); num->num_of_digit++)
|
||||
{
|
||||
if((num->num_of_digit & 1) == 0)
|
||||
digit = *tpaddr & 0x0f;
|
||||
else
|
||||
digit = *(tpaddr++) >> 4;
|
||||
if(is_dail_digit(digit))
|
||||
num->digit[num->num_of_digit] = digit;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return isdn;
|
||||
}
|
||||
|
||||
int string_to_num32(num32_t *num, const char *str)
|
||||
{
|
||||
u8 digit;
|
||||
|
||||
for(num->num_of_digit = 0; num->num_of_digit < 32; num->num_of_digit++, str++)
|
||||
{
|
||||
if((*str >= '0') && (*str <= '9'))
|
||||
digit = *str - '0';
|
||||
else if(*str == '*')
|
||||
digit = 0x0b;
|
||||
else if(*str == '#')
|
||||
digit = 0x0c;
|
||||
else
|
||||
break;
|
||||
num->digit[num->num_of_digit] = digit;
|
||||
}
|
||||
return num->num_of_digit;
|
||||
}
|
||||
|
||||
int num32_to_string(char *str, const num32_t *num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; ((i < 32) && (i < num->num_of_digit)); i++)
|
||||
{
|
||||
if(num->digit[i] <= 9)
|
||||
str[i] = num->digit[i] + '0';
|
||||
else if(num->digit[i] == 0x0b)
|
||||
str[i] = '*';
|
||||
else if(num->digit[i] == 0x0c)
|
||||
str[i] = '#';
|
||||
}
|
||||
str[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
int string_to_num16(num16_t *num, const char *str)
|
||||
{
|
||||
u8 digit;
|
||||
|
||||
for(num->num_of_digit = 0; num->num_of_digit < 16; num->num_of_digit++, str++)
|
||||
{
|
||||
if((*str >= '0') && (*str <= '9'))
|
||||
digit = *str - '0';
|
||||
else if(*str == '*')
|
||||
digit = 0x0b;
|
||||
else if(*str == '#')
|
||||
digit = 0x0c;
|
||||
else
|
||||
break;
|
||||
num->digit[num->num_of_digit] = digit;
|
||||
}
|
||||
return num->num_of_digit;
|
||||
}
|
||||
|
||||
int num16_to_string(char *str, const num16_t *num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; ((i < 16) && (i < num->num_of_digit)); i++)
|
||||
{
|
||||
if(num->digit[i] <= 9)
|
||||
str[i] = num->digit[i] + '0';
|
||||
else if(num->digit[i] == 0x0b)
|
||||
str[i] = '*';
|
||||
else if(num->digit[i] == 0x0c)
|
||||
str[i] = '#';
|
||||
}
|
||||
str[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
int string_to_num8(num8_t *num, const char *str)
|
||||
{
|
||||
u8 digit;
|
||||
|
||||
for(num->num_of_digit = 0; num->num_of_digit < 8; num->num_of_digit++, str++)
|
||||
{
|
||||
if((*str >= '0') && (*str <= '9'))
|
||||
digit = *str - '0';
|
||||
else if(*str == '*')
|
||||
digit = 0x0b;
|
||||
else if(*str == '#')
|
||||
digit = 0x0c;
|
||||
else
|
||||
break;
|
||||
num->digit[num->num_of_digit] = digit;
|
||||
}
|
||||
return num->num_of_digit;
|
||||
}
|
||||
|
||||
int num8_to_string(char *str, const num8_t *num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; ((i < 8) && (i < num->num_of_digit)); i++)
|
||||
{
|
||||
if(num->digit[i] <= 9)
|
||||
str[i] = num->digit[i] + '0';
|
||||
else if(num->digit[i] == 0x0b)
|
||||
str[i] = '*';
|
||||
else if(num->digit[i] == 0x0c)
|
||||
str[i] = '#';
|
||||
}
|
||||
str[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
int digit_to_netbcd(u8 *netbcd, u8 *digit, u8 max_digit)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < max_digit; i++)
|
||||
{
|
||||
if((i & 1) == 0)
|
||||
*netbcd = 0xf0 + (digit[i] & 0x0f);
|
||||
else
|
||||
{
|
||||
*netbcd = (digit[i] << 4) | (*netbcd & 0x0f);
|
||||
netbcd++;
|
||||
}
|
||||
}
|
||||
return (max_digit+1)/2;
|
||||
}
|
||||
|
||||
int netbcd_to_digit(u8 *digit, u8 *netbcd, u8 max_digit)
|
||||
{
|
||||
int i;
|
||||
u8 d;
|
||||
|
||||
for(i = 0; i < max_digit; i++)
|
||||
{
|
||||
if((i & 1) == 0)
|
||||
d = *netbcd & 0x0f;
|
||||
else
|
||||
d = *(netbcd++) >> 4;
|
||||
|
||||
if(d != 0x0f)
|
||||
digit[i] = d;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void msc_save_lai(u8 *lai, u8 *mcc, u8 *mnc, int lac)
|
||||
{
|
||||
lai[0] = (mcc[1] << 4) + (mcc[0] & 0x0f);
|
||||
lai[1] = (mnc[2] << 4) | mcc[2];
|
||||
lai[2] = (mnc[1] << 4) + (mnc[0] & 0x0f);
|
||||
lai[3] = lac >> 8;
|
||||
lai[4] = lac;
|
||||
}
|
||||
|
||||
void msc_load_lai(u8 *mcc, u8 *mnc, int *lac, u8 *lai)
|
||||
{
|
||||
mcc[0] = lai[0] & 0x0f;
|
||||
mcc[1] = lai[0] >> 4;
|
||||
mcc[2] = lai[1] & 0x0f;
|
||||
mnc[0] = lai[2] & 0x0f;
|
||||
mnc[1] = lai[2] >> 4;
|
||||
mnc[2] = lai[1] >> 4;
|
||||
*lac = (lai[3] << 8) + lai[4];
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* return the digit counts of number */
|
||||
static int bcd_to_num16(num16_t *num, const u8 *bcd)
|
||||
{
|
||||
u8 digit;
|
||||
|
||||
for(num->num_of_digit = 0; num->num_of_digit < 16; num->num_of_digit++)
|
||||
{
|
||||
if((num->num_of_digit & 1) == 0)
|
||||
digit = *bcd >> 4;
|
||||
else
|
||||
digit = *(bcd++) & 0x0f;
|
||||
if(is_dail_digit(digit))
|
||||
num->digit[num->num_of_digit] = digit;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return num->num_of_digit ;
|
||||
}
|
||||
|
||||
/* return the length of bcd */
|
||||
static int num16_to_bcd(u8 *bcd, const num16_t *num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; ((i < 16) && (i < num->num_of_digit)); i++)
|
||||
{
|
||||
if((i & 1) == 0)
|
||||
*bcd = (num->digit[i] << 4) | 0x0f;
|
||||
else
|
||||
*(bcd++) = (*bcd & 0xf0) + num->digit[i];
|
||||
}
|
||||
return (i+1)/2;
|
||||
}
|
||||
#endif
|
||||
|
||||
80
plat/public/src/uwav/number.h
Normal file
80
plat/public/src/uwav/number.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef _UWAV_NUMBER_H
|
||||
#define _UWAV_NUMBER_H
|
||||
|
||||
#include "../include/public.h"
|
||||
|
||||
/*
|
||||
* Number type definition:
|
||||
* 32 digits number is used for party number handling
|
||||
* 16 digits number is used for prefix parameter
|
||||
* 8 digits number is used for short number parameter, i.e. cc, ndc
|
||||
*/
|
||||
typedef struct number32 {
|
||||
u8 num_of_digit;
|
||||
u8 digit[32];
|
||||
} num32_t;
|
||||
|
||||
typedef struct number16 {
|
||||
u8 num_of_digit;
|
||||
u8 digit[16];
|
||||
} num16_t;
|
||||
|
||||
typedef struct number8 {
|
||||
u8 num_of_digit;
|
||||
u8 digit[8];
|
||||
} num8_t;
|
||||
|
||||
typedef struct isdn_num {
|
||||
u8 nai; /* Nature of Address Indicator */
|
||||
// u8 npi; /* Number Plan Indicator */
|
||||
u8 pi;
|
||||
u8 si; /* Screen Indicator */
|
||||
num32_t num;
|
||||
} isdn_t;
|
||||
|
||||
struct number_change {
|
||||
u8 nai;
|
||||
u8 del_count;
|
||||
num16_t insert;
|
||||
};
|
||||
|
||||
#define is_dail_digit(digit) (digit < 0x0e)
|
||||
#define char_to_digit(digit, ch) do { \
|
||||
if((ch >= '0') && (ch <= '9')) \
|
||||
digit = ch - '0'; \
|
||||
else if(ch == '*') \
|
||||
digit = 0x0b; \
|
||||
else if(ch == '#') \
|
||||
digit = 0x0c; \
|
||||
else \
|
||||
break; \
|
||||
} while(0)
|
||||
#define digit_to_char(ch, digit) do { \
|
||||
if(digit <= 9) \
|
||||
ch = digit + '0'; \
|
||||
else if(digit == 0x0b) \
|
||||
ch = '*'; \
|
||||
else if(digit == 0x0c) \
|
||||
ch = '#'; \
|
||||
} while(0)
|
||||
|
||||
extern u8 nai_gsm_to_itu(u8 nai);
|
||||
extern u8 nai_itu_to_gsm(u8 nai);
|
||||
extern u8 *msc_isdn_to_bcd(u8 *bcd, const isdn_t *isdn);
|
||||
extern isdn_t *netbcd_to_isdn(isdn_t *isdn, const u8 *bcd);
|
||||
extern u8 *isdn_to_netbcd(u8 *bcd, const isdn_t *isdn);
|
||||
extern int tbcd_to_string(char *str, const u8 *tbcd, u8 tbcd_len);
|
||||
extern isdn_t *tpaddr_to_isdn(isdn_t *isdn, const u8 *tpaddr);
|
||||
extern int string_to_num32(num32_t *num, const char *str);
|
||||
extern int num32_to_string(char *str, const num32_t *num);
|
||||
extern int string_to_num16(num16_t *num, const char *str);
|
||||
extern int num16_to_string(char *str, const num16_t *num);
|
||||
extern int string_to_num8(num8_t *num, const char *str);
|
||||
extern int num8_to_string(char *str, const num8_t *num);
|
||||
extern int digit_to_netbcd(u8 *netbcd, u8 *digit, u8 max_digit);
|
||||
extern int netbcd_to_digit(u8 *digit, u8 *netbcd, u8 max_digit);
|
||||
extern void msc_save_lai(u8 *lai, u8 *mcc, u8 *mnc, int lac);
|
||||
extern void msc_load_lai(u8 *mcc, u8 *mnc, int *lac, u8 *lai);
|
||||
|
||||
#endif
|
||||
|
||||
176
plat/public/src/uwav/numgrp.c
Normal file
176
plat/public/src/uwav/numgrp.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
|
||||
* public/uwav/numgrp.c
|
||||
|
||||
*
|
||||
|
||||
* Copyright (C) 2008 ADC, Inc
|
||||
|
||||
* Written by: Xinyu Yan <xinyu.yan@adc.com>
|
||||
|
||||
*
|
||||
|
||||
* Description: number group lookup algorithm
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "numgrp.h"
|
||||
|
||||
|
||||
|
||||
static struct numgrp_table group_table[MAX_NUMBER_GROUP_TABLE];
|
||||
|
||||
|
||||
|
||||
struct numgrp_table *assign_numgrp_table(char *name, int size)
|
||||
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
assert(size <= MAX_NUMBER_GROUP_TABLE_SIZE);
|
||||
|
||||
|
||||
|
||||
for(i = 0; i < MAX_NUMBER_GROUP_TABLE; i++)
|
||||
|
||||
{
|
||||
|
||||
if(group_table[i].size == 0)
|
||||
|
||||
{
|
||||
|
||||
strncpy(group_table[i].name, name, 32);
|
||||
|
||||
group_table[i].size = size;
|
||||
|
||||
group_table[i].len = 0;
|
||||
|
||||
group_table[i].item = malloc(sizeof(struct number_group) * size);
|
||||
|
||||
return &group_table[i];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int delete_numgrp_table(struct numgrp_table *table)
|
||||
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
for(i = 0; i < MAX_NUMBER_GROUP_TABLE; i++)
|
||||
|
||||
{
|
||||
|
||||
if(&group_table[i] == table)
|
||||
|
||||
{
|
||||
|
||||
free(group_table[i].item);
|
||||
|
||||
memset(&group_table[i], 0, sizeof(struct numgrp_table));
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*Return an integer greater than, equal to, or less than 0, if the number pointed to
|
||||
|
||||
by n1 is greater than, equal to, or less than the number pointed to by n2, respectively*/
|
||||
|
||||
static int numcmp(const num16_t *n1, const num16_t *n2)
|
||||
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
if(n1->num_of_digit > n2->num_of_digit)
|
||||
|
||||
return 1;
|
||||
|
||||
else if(n1->num_of_digit < n2->num_of_digit)
|
||||
|
||||
return -1;
|
||||
|
||||
for(i = 0; i < n1->num_of_digit; i++)
|
||||
|
||||
{
|
||||
|
||||
if(n1->digit[i] > n2->digit[i])
|
||||
|
||||
return 1;
|
||||
|
||||
else if(n1->digit[i] < n2->digit[i])
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*Return an integer greater than, equal to, or less than 0, if the number pointed to
|
||||
|
||||
by n is greater than, equal to, or less than the group pointed to by start and end, respectively*/
|
||||
|
||||
static int numgrpcmp(const num16_t *start, const num16_t *end, const num16_t *n)
|
||||
|
||||
{
|
||||
|
||||
int ret1, ret2;
|
||||
|
||||
|
||||
|
||||
ret1 = numcmp(n, start);
|
||||
|
||||
ret2 = numcmp(n, end);
|
||||
|
||||
if((ret1 >= 0) && (ret2 <= 0))
|
||||
|
||||
return 0;
|
||||
|
||||
else if(ret2 > 0)
|
||||
|
||||
return 1;
|
||||
|
||||
else
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
29
plat/public/src/uwav/numgrp.h
Normal file
29
plat/public/src/uwav/numgrp.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _UWAV_NUMGRP_H_
|
||||
|
||||
#define _UWAV_NUMGRP_H_
|
||||
|
||||
|
||||
|
||||
#include "number.h"
|
||||
|
||||
|
||||
|
||||
#define MAX_NUMBER_GROUP_TABLE 32
|
||||
|
||||
#define MAX_NUMBER_GROUP_TABLE_SIZE 1024
|
||||
|
||||
|
||||
|
||||
struct number_group {
|
||||
|
||||
num16_t start;
|
||||
|
||||
num16_t end;
|
||||
|
||||
int index;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct numgrp_table {
|
||||
Reference in New Issue
Block a user