gsm improvements
code cleanup modified: README modified: action.cpp modified: action_efi.cpp modified: action_vbox.cpp modified: alawulaw.c modified: bchannel.c modified: bootstrap.c modified: callerid.c modified: cause.c modified: chan_lcr.c modified: default/gsm.conf modified: dss1.cpp modified: gsm.cpp modified: gsm.h modified: gsm_conf.c modified: message.h
This commit is contained in:
parent
063d622d53
commit
6bf7c7f9db
1
README
1
README
|
@ -502,5 +502,6 @@ Changes after Version 1.5
|
|||
- Fixed some GSM information elements.
|
||||
- OpenBSC api changes.
|
||||
- Fixed disabling of DTMF using 'n' option of chan_lcr.
|
||||
- Added GSM IMSI dialing by using dialing "imsi-<number>".
|
||||
|
||||
|
||||
|
|
588
action.cpp
588
action.cpp
File diff suppressed because it is too large
Load Diff
|
@ -30,8 +30,7 @@ void EndpointAppPBX::action_init_efi(void)
|
|||
struct port_list *portlist = ea_endpoint->ep_portlist;
|
||||
|
||||
/* if no caller id */
|
||||
if (e_callerinfo.id[0] == '\0')
|
||||
{
|
||||
if (e_callerinfo.id[0] == '\0') {
|
||||
/* facility rejected */
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DISCONNECT);
|
||||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
|
@ -68,23 +67,20 @@ void EndpointAppPBX::efi_message_eof(void)
|
|||
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) terminal %s end of file during state: %d\n", ea_endpoint->ep_serial, e_ext.number, e_vbox_state);
|
||||
|
||||
switch(e_efi_state)
|
||||
{
|
||||
switch(e_efi_state) {
|
||||
case EFI_STATE_HELLO:
|
||||
e_efi_state = EFI_STATE_DIE;
|
||||
set_tone_efi("die");
|
||||
break;
|
||||
case EFI_STATE_DIE:
|
||||
if (e_callerinfo.screen==INFO_SCREEN_USER)
|
||||
{
|
||||
if (e_callerinfo.screen==INFO_SCREEN_USER) {
|
||||
e_efi_state = EFI_STATE_BENUTZERDEFINIERTE;
|
||||
set_tone_efi("benutzerdefinierte");
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
case EFI_STATE_BENUTZERDEFINIERTE:
|
||||
if (e_callerinfo.present==INFO_PRESENT_RESTRICTED)
|
||||
{
|
||||
if (e_callerinfo.present==INFO_PRESENT_RESTRICTED) {
|
||||
e_efi_state = EFI_STATE_UNTERDRUECKTE;
|
||||
set_tone_efi("unterdrueckte");
|
||||
break;
|
||||
|
@ -101,12 +97,10 @@ void EndpointAppPBX::efi_message_eof(void)
|
|||
// fall through
|
||||
case EFI_STATE_DIGIT:
|
||||
digit[8] = numberrize_callerinfo(e_callerinfo.id,e_callerinfo.ntype, options.national, options.international)[e_efi_digit];
|
||||
if (digit[8])
|
||||
{
|
||||
if (digit[8]) {
|
||||
set_tone_efi(digit);
|
||||
e_efi_digit++;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
// e_efi_state = EFI_STATE_STOP;
|
||||
e_efi_state = EFI_STATE_ICH_WIEDERHOLE;
|
||||
// message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_DISCONNECT);
|
||||
|
@ -146,8 +140,7 @@ void EndpointAppPBX::set_tone_efi(const char *tone)
|
|||
if (tone == NULL)
|
||||
tone = "";
|
||||
|
||||
if (!ea_endpoint->ep_portlist)
|
||||
{
|
||||
if (!ea_endpoint->ep_portlist) {
|
||||
PERROR("EPOINT(%d) no portlist\n", ea_endpoint->ep_serial);
|
||||
}
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_VBOX_TONE);
|
||||
|
|
198
action_vbox.cpp
198
action_vbox.cpp
|
@ -80,8 +80,7 @@ void EndpointAppPBX::action_init_vbox_play(void)
|
|||
SCPY(e_vbox, e_ext.number);
|
||||
if ((rparam = routeparam(e_action, PARAM_EXTENSION)))
|
||||
SCPY(e_vbox, rparam->string_value);
|
||||
if (e_vbox[0] == '\0')
|
||||
{
|
||||
if (e_vbox[0] == '\0') {
|
||||
/* facility rejected */
|
||||
message_disconnect_port(portlist, CAUSE_FACILITYREJECTED, LOCATION_PRIVATE_LOCAL, "");
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
|
@ -110,8 +109,7 @@ void EndpointAppPBX::action_init_vbox_play(void)
|
|||
vbox_index_read(e_vbox_play);
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) number of calls: %d\n", ea_endpoint->ep_serial, e_vbox_index_num);
|
||||
|
||||
if (e_vbox_index_num == 0)
|
||||
{
|
||||
if (e_vbox_index_num == 0) {
|
||||
e_vbox_state = VBOX_STATE_NOTHING;
|
||||
SCPY(e_vbox_display, (char *)((language)?"keine Anrufe":"no calls"));
|
||||
e_vbox_display_refresh = 1;
|
||||
|
@ -137,16 +135,14 @@ void EndpointAppPBX::vbox_index_read(int num)
|
|||
e_vbox_index_num = 0;
|
||||
|
||||
SPRINT(filename, "%s/%s/vbox/index", EXTENSION_DATA, e_vbox);
|
||||
if (!(fp = fopen(filename, "r")))
|
||||
{
|
||||
if (!(fp = fopen(filename, "r"))) {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) no files in index\n", ea_endpoint->ep_serial);
|
||||
return;
|
||||
}
|
||||
fduse++;
|
||||
|
||||
i = 0;
|
||||
while((fgets(buffer,sizeof(buffer),fp)))
|
||||
{
|
||||
while((fgets(buffer,sizeof(buffer),fp))) {
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
|
||||
|
||||
|
@ -158,8 +154,7 @@ void EndpointAppPBX::vbox_index_read(int num)
|
|||
continue;
|
||||
|
||||
/* the selected entry */
|
||||
if (i == num)
|
||||
{
|
||||
if (i == num) {
|
||||
SCPY(e_vbox_index_file, name);
|
||||
e_vbox_index_year = year;
|
||||
e_vbox_index_mon = mon;
|
||||
|
@ -196,32 +191,27 @@ void EndpointAppPBX::vbox_index_remove(int num)
|
|||
|
||||
SPRINT(filename1, "%s/%s/vbox/index", EXTENSION_DATA, e_vbox);
|
||||
SPRINT(filename2, "%s/%s/vbox/index-temp", EXTENSION_DATA, e_vbox);
|
||||
if (!(fpr = fopen(filename1, "r")))
|
||||
{
|
||||
if (!(fpr = fopen(filename1, "r"))) {
|
||||
return;
|
||||
}
|
||||
if (!(fpw = fopen(filename2, "w")))
|
||||
{
|
||||
if (!(fpw = fopen(filename2, "w"))) {
|
||||
fclose(fpr);
|
||||
return;
|
||||
}
|
||||
fduse += 2;
|
||||
|
||||
i = 0;
|
||||
while((fgets(buffer,sizeof(buffer),fpr)))
|
||||
{
|
||||
while((fgets(buffer,sizeof(buffer),fpr))) {
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
|
||||
|
||||
if (buffer[0]=='\0' || buffer[0]=='#')
|
||||
{
|
||||
if (buffer[0]=='\0' || buffer[0]=='#') {
|
||||
fprintf(fpw, "%s\n", buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the selected entry will not be written */
|
||||
if (i != num)
|
||||
{
|
||||
if (i != num) {
|
||||
fprintf(fpw, "%s\n", buffer);
|
||||
}
|
||||
|
||||
|
@ -248,8 +238,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
|
||||
portlist = ea_endpoint->ep_portlist;
|
||||
|
||||
if (e_extdialing[0] == '\0')
|
||||
{
|
||||
if (e_extdialing[0] == '\0') {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) called with no digit\n", ea_endpoint->ep_serial);
|
||||
return;
|
||||
}
|
||||
|
@ -258,10 +247,8 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
|
||||
e_vbox_display_refresh = 1;
|
||||
|
||||
if (e_vbox_state == VBOX_STATE_RECORD_RECORD)
|
||||
{
|
||||
if (e_extdialing[0] == '1' || e_extdialing[0] == '0')
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_RECORD_RECORD) {
|
||||
if (e_extdialing[0] == '1' || e_extdialing[0] == '0') {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) stopping recording of announcement.\n", ea_endpoint->ep_serial);
|
||||
|
||||
port = find_port_id(portlist->port_id);
|
||||
|
@ -272,10 +259,8 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (e_vbox_state == VBOX_STATE_RECORD_PLAY)
|
||||
{
|
||||
if (e_extdialing[0] == '1')
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_RECORD_PLAY) {
|
||||
if (e_extdialing[0] == '1') {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) stopping playback of announcement.\n", ea_endpoint->ep_serial);
|
||||
|
||||
goto record_ask;
|
||||
|
@ -283,10 +268,8 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (e_vbox_state == VBOX_STATE_RECORD_ASK)
|
||||
{
|
||||
switch(e_extdialing[0])
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_RECORD_ASK) {
|
||||
switch(e_extdialing[0]) {
|
||||
case '3':
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) quit recoding menu.\n", ea_endpoint->ep_serial);
|
||||
ask_abort:
|
||||
|
@ -317,8 +300,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) record announcement.\n", ea_endpoint->ep_serial);
|
||||
/* close recording if already recording */
|
||||
port = find_port_id(portlist->port_id);
|
||||
if (port)
|
||||
{
|
||||
if (port) {
|
||||
port->close_record(0,0);
|
||||
port->open_record(CODEC_MONO, 1, 4000, e_ext.number, 0, "", 0); /* record announcement, skip the first 4000 samples */
|
||||
}
|
||||
|
@ -336,12 +318,10 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (e_vbox_state==VBOX_STATE_STORE_ASK || e_vbox_state==VBOX_STATE_DELETE_ASK)
|
||||
{
|
||||
if (e_vbox_state==VBOX_STATE_STORE_ASK || e_vbox_state==VBOX_STATE_DELETE_ASK) {
|
||||
char filename[256], filename2[256];
|
||||
|
||||
switch(e_extdialing[0])
|
||||
{
|
||||
switch(e_extdialing[0]) {
|
||||
case '3':
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) quit store/delete menu.\n", ea_endpoint->ep_serial);
|
||||
goto ask_abort;
|
||||
|
@ -351,13 +331,10 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
SPRINT(filename, "%s/%s/vbox/%s", EXTENSION_DATA, e_vbox, e_vbox_index_file);
|
||||
|
||||
/* move file */
|
||||
if (e_vbox_state == VBOX_STATE_STORE_ASK)
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_STORE_ASK) {
|
||||
SPRINT(filename, "%s/%s/recordings", EXTENSION_DATA, e_vbox);
|
||||
if (mkdir(filename, 0755) < 0)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
if (mkdir(filename, 0755) < 0) {
|
||||
if (errno != EEXIST) {
|
||||
PERROR("EPOINT(%d) cannot create directory '%s'\n", ea_endpoint->ep_serial, filename);
|
||||
goto done;
|
||||
}
|
||||
|
@ -373,8 +350,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
}
|
||||
|
||||
/* remove file */
|
||||
if (e_vbox_state == VBOX_STATE_DELETE_ASK)
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_DELETE_ASK) {
|
||||
remove(filename);
|
||||
e_vbox_state = VBOX_STATE_DELETE_DONE;
|
||||
if (e_ext.vbox_language)
|
||||
|
@ -388,8 +364,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
vbox_index_remove(e_vbox_play);
|
||||
vbox_index_read(e_vbox_play);
|
||||
/* stay at the last message+1, so we always get "no messages" */
|
||||
if (e_vbox_play>e_vbox_index_num && e_vbox_play)
|
||||
{
|
||||
if (e_vbox_play>e_vbox_index_num && e_vbox_play) {
|
||||
e_vbox_play = e_vbox_index_num-1;
|
||||
}
|
||||
default:
|
||||
|
@ -399,13 +374,11 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
}
|
||||
|
||||
/* dialing during menu */
|
||||
switch(e_extdialing[0])
|
||||
{
|
||||
switch(e_extdialing[0]) {
|
||||
/* process the vbox functions */
|
||||
case '1': /* previous */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) previous call is selected.\n", ea_endpoint->ep_serial);
|
||||
if (e_vbox_index_num == 0) /* nothing to play */
|
||||
{
|
||||
if (e_vbox_index_num == 0) { /* nothing to play */
|
||||
no_calls:
|
||||
e_vbox_state = VBOX_STATE_MENU;
|
||||
SCPY(e_vbox_display, (char *)((language)?"keine Anrufe":"no calls"));
|
||||
|
@ -413,8 +386,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
break;
|
||||
}
|
||||
e_vbox_play--;
|
||||
if (e_vbox_play < 0)
|
||||
{
|
||||
if (e_vbox_play < 0) {
|
||||
e_vbox_play = 0;
|
||||
|
||||
e_vbox_state = VBOX_STATE_MENU;
|
||||
|
@ -427,12 +399,10 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
e_vbox_state = VBOX_STATE_CALLINFO_INTRO;
|
||||
SPRINT(e_vbox_display, "#%d", e_vbox_play+1);
|
||||
vbox_index_read(e_vbox_play);
|
||||
if (e_vbox_index_mon!=now_tm->tm_mon || e_vbox_index_year!=now_tm->tm_year)
|
||||
{
|
||||
if (e_vbox_index_mon!=now_tm->tm_mon || e_vbox_index_year!=now_tm->tm_year) {
|
||||
UPRINT(strchr(e_vbox_display,'\0'), " %s", (language)?months_german[e_vbox_index_mon]:months_english[e_vbox_index_mon]);
|
||||
}
|
||||
if (e_vbox_index_mday!=now_tm->tm_mday || e_vbox_index_mon!=now_tm->tm_mon || e_vbox_index_year!=now_tm->tm_year)
|
||||
{
|
||||
if (e_vbox_index_mday!=now_tm->tm_mday || e_vbox_index_mon!=now_tm->tm_mon || e_vbox_index_year!=now_tm->tm_year) {
|
||||
UPRINT(strchr(e_vbox_display,'\0'), " %d", e_vbox_index_mday);
|
||||
}
|
||||
UPRINT(strchr(e_vbox_display,'\0'), " %02d:%02d", e_vbox_index_hour, e_vbox_index_min);
|
||||
|
@ -444,13 +414,11 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
case '2': /* play */
|
||||
if (e_vbox_play >= e_vbox_index_num)
|
||||
goto no_messages;
|
||||
if (e_vbox_index_num == 0) /* nothing to play */
|
||||
{
|
||||
if (e_vbox_index_num == 0) { /* nothing to play */
|
||||
goto no_calls;
|
||||
}
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) play call #%d.\n", ea_endpoint->ep_serial, e_vbox_play+1);
|
||||
if (e_vbox_state>VBOX_STATE_CALLINFO_BEGIN && e_vbox_state<VBOX_STATE_CALLINFO_END)
|
||||
{
|
||||
if (e_vbox_state>VBOX_STATE_CALLINFO_BEGIN && e_vbox_state<VBOX_STATE_CALLINFO_END) {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) play call #%d. abborting announcement and starting with playback\n", ea_endpoint->ep_serial, e_vbox_play+1);
|
||||
/* the callinfo is played, so we start with the call */
|
||||
e_vbox_counter = 0;
|
||||
|
@ -464,23 +432,20 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
set_play_vbox(e_vbox_index_file, 0);
|
||||
break;
|
||||
} else
|
||||
if (e_vbox_state==VBOX_STATE_PLAY && e_vbox_speed!=1)
|
||||
{
|
||||
if (e_vbox_state==VBOX_STATE_PLAY && e_vbox_speed!=1) {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) play call #%d. play speed is different from 1, so we play now with normal speed\n", ea_endpoint->ep_serial, e_vbox_play+1);
|
||||
/* we set play speed to normal */
|
||||
e_vbox_speed = 1;
|
||||
set_play_speed(e_vbox_speed);
|
||||
} else
|
||||
if (e_vbox_state == VBOX_STATE_PLAY)
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_PLAY) {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) play call #%d. play speed is equals 1, so we pause\n", ea_endpoint->ep_serial, e_vbox_play+1);
|
||||
/* we pause the current play */
|
||||
e_vbox_state = VBOX_STATE_PAUSE;
|
||||
SCPY(e_vbox_display, (char *)((language)?"druecke 2 f. wiedergabe":"press 2 to play"));
|
||||
set_tone_vbox("pause");
|
||||
} else
|
||||
if (e_vbox_state == VBOX_STATE_PAUSE)
|
||||
{
|
||||
if (e_vbox_state == VBOX_STATE_PAUSE) {
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) play call #%d. currently pause, so we continue play\n", ea_endpoint->ep_serial, e_vbox_play+1);
|
||||
/* we continue the current play */
|
||||
e_vbox_state = VBOX_STATE_PLAY;
|
||||
|
@ -488,8 +453,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
if (e_ext.vbox_display == VBOX_DISPLAY_DETAILED)
|
||||
UPRINT(strchr(e_vbox_display,'\0'), " (%s)", e_vbox_index_callerid);
|
||||
set_play_vbox(e_vbox_index_file, e_vbox_counter);
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* now we have something else going on, so we announce the call */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) play call #%d. announcing call during any other state\n", ea_endpoint->ep_serial, e_vbox_play+1);
|
||||
goto announce_call;
|
||||
|
@ -498,13 +462,11 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
|
||||
case '3': /* next */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) next call is selected.\n", ea_endpoint->ep_serial);
|
||||
if (e_vbox_index_num == 0) /* nothing to play */
|
||||
{
|
||||
if (e_vbox_index_num == 0) { /* nothing to play */
|
||||
goto no_calls;
|
||||
}
|
||||
e_vbox_play++;
|
||||
if (e_vbox_play >= e_vbox_index_num)
|
||||
{
|
||||
if (e_vbox_play >= e_vbox_index_num) {
|
||||
no_messages:
|
||||
e_vbox_play = e_vbox_index_num;
|
||||
|
||||
|
@ -518,8 +480,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
break;
|
||||
|
||||
case '4': /* rewind */
|
||||
if (e_vbox_state==VBOX_STATE_PLAY)
|
||||
{
|
||||
if (e_vbox_state==VBOX_STATE_PLAY) {
|
||||
if (e_vbox_speed >= -1)
|
||||
e_vbox_speed = -1;
|
||||
e_vbox_speed = e_vbox_speed * 2;
|
||||
|
@ -536,8 +497,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
break;
|
||||
|
||||
case '6': /* wind */
|
||||
if (e_vbox_state==VBOX_STATE_PLAY)
|
||||
{
|
||||
if (e_vbox_state==VBOX_STATE_PLAY) {
|
||||
if (e_vbox_speed <= 1)
|
||||
e_vbox_speed = 1;
|
||||
e_vbox_speed = e_vbox_speed * 2;
|
||||
|
@ -558,8 +518,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) entering the store menu\n", ea_endpoint->ep_serial);
|
||||
if (e_vbox_play >= e_vbox_index_num)
|
||||
goto no_messages;
|
||||
if (e_vbox_index_num == 0) /* nothing to play */
|
||||
{
|
||||
if (e_vbox_index_num == 0) { /* nothing to play */
|
||||
goto no_calls;
|
||||
}
|
||||
e_vbox_state = VBOX_STATE_STORE_ASK;
|
||||
|
@ -571,8 +530,7 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) entering the delete menu\n", ea_endpoint->ep_serial);
|
||||
if (e_vbox_play >= e_vbox_index_num)
|
||||
goto no_messages;
|
||||
if (e_vbox_index_num == 0) /* nothing to play */
|
||||
{
|
||||
if (e_vbox_index_num == 0) { /* nothing to play */
|
||||
goto no_calls;
|
||||
}
|
||||
e_vbox_state = VBOX_STATE_DELETE_ASK;
|
||||
|
@ -595,12 +553,10 @@ void EndpointAppPBX::action_dialing_vbox_play(void)
|
|||
break;
|
||||
|
||||
case '0':
|
||||
if (e_vbox_menu < 0) /* only if menu selection is pressed before*/
|
||||
{
|
||||
if (e_vbox_menu < 0) { /* only if menu selection is pressed before*/
|
||||
/* call if phonenumber is given */
|
||||
if (e_vbox_index_num)
|
||||
if (e_vbox_index_callerid[0]!='\0' && !!strcmp(e_vbox_index_callerid,"anonymous") && !!strcmp(e_vbox_index_callerid,"unknown"))
|
||||
{
|
||||
if (e_vbox_index_callerid[0]!='\0' && !!strcmp(e_vbox_index_callerid,"anonymous") && !!strcmp(e_vbox_index_callerid,"unknown")) {
|
||||
set_tone(portlist, "dialing");
|
||||
SPRINT(e_dialinginfo.id, "extern:%s", e_vbox_index_callerid);
|
||||
e_extdialing = e_dialinginfo.id;
|
||||
|
@ -651,15 +607,13 @@ void EndpointAppPBX::vbox_handler(void)
|
|||
{
|
||||
/* refresh if counter changes */
|
||||
if (e_vbox_state==VBOX_STATE_PLAY || e_vbox_state==VBOX_STATE_RECORD_PLAY)
|
||||
if (e_vbox_counter != e_vbox_counter_last)
|
||||
{
|
||||
if (e_vbox_counter != e_vbox_counter_last) {
|
||||
e_vbox_counter_last = e_vbox_counter;
|
||||
e_vbox_display_refresh = 1;
|
||||
}
|
||||
|
||||
/* refresh display, if required (include counter) */
|
||||
if (e_vbox_display_refresh && e_ext.vbox_display!=VBOX_DISPLAY_OFF)
|
||||
{
|
||||
if (e_vbox_display_refresh && e_ext.vbox_display!=VBOX_DISPLAY_OFF) {
|
||||
char counter[32];
|
||||
struct lcr_msg *message;
|
||||
|
||||
|
@ -688,8 +642,7 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) terminal %s end of file during state: %d\n", ea_endpoint->ep_serial, e_ext.number, e_vbox_state);
|
||||
|
||||
switch(e_vbox_state)
|
||||
{
|
||||
switch(e_vbox_state) {
|
||||
case VBOX_STATE_MENU:
|
||||
case VBOX_STATE_NOTHING:
|
||||
e_vbox_state = VBOX_STATE_MENU;
|
||||
|
@ -699,14 +652,12 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
break;
|
||||
|
||||
case VBOX_STATE_PLAY:
|
||||
if (e_vbox_speed > 0)
|
||||
{
|
||||
if (e_vbox_speed > 0) {
|
||||
e_vbox_state = VBOX_STATE_MENU;
|
||||
SCPY(e_vbox_display, (char *)((language)?"druecke 3 f. Naechste":"press 3 for next"));
|
||||
e_vbox_display_refresh = 1;
|
||||
set_tone_vbox("menu");
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* if we have endoffile because we were playing backwards, we continue to play forward */
|
||||
e_vbox_speed = 1;
|
||||
e_vbox_counter = 1;
|
||||
|
@ -734,12 +685,10 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
|
||||
case VBOX_STATE_CALLINFO_MONTH:
|
||||
e_vbox_state = VBOX_STATE_CALLINFO_DAY; //german month
|
||||
if (e_ext.vbox_language)
|
||||
{
|
||||
if (e_ext.vbox_language) {
|
||||
/* done with month, so we send the month*/
|
||||
SPRINT(buffer, "month_%02d", e_vbox_index_mon+1);
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* done with day, so we send the day */
|
||||
SPRINT(buffer, "day_%02d", e_vbox_index_mday);
|
||||
}
|
||||
|
@ -749,14 +698,12 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
case VBOX_STATE_CALLINFO_DAY: //german month
|
||||
skip_day_month:
|
||||
e_vbox_state = VBOX_STATE_CALLINFO_HOUR;
|
||||
if (e_ext.vbox_language)
|
||||
{
|
||||
if (e_ext.vbox_language) {
|
||||
if (e_vbox_index_hour == 1)
|
||||
SCPY(buffer, "number_ein");
|
||||
else
|
||||
SPRINT(buffer, "number_%02d", e_vbox_index_hour); /* 1-23 hours */
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
SPRINT(buffer, "number_%02d", ((e_vbox_index_hour+11)%12)+1); /* 12 hours am/pm */
|
||||
}
|
||||
set_tone_vbox(buffer);
|
||||
|
@ -764,11 +711,9 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
|
||||
case VBOX_STATE_CALLINFO_HOUR:
|
||||
e_vbox_state = VBOX_STATE_CALLINFO_OCLOCK;
|
||||
if (e_ext.vbox_language)
|
||||
{
|
||||
if (e_ext.vbox_language) {
|
||||
set_tone_vbox("oclock");
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
if (e_vbox_index_hour >= 12)
|
||||
set_tone_vbox("oclock_pm");
|
||||
else
|
||||
|
@ -778,15 +723,13 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
|
||||
case VBOX_STATE_CALLINFO_OCLOCK:
|
||||
e_vbox_state = VBOX_STATE_CALLINFO_MIN;
|
||||
if (e_ext.vbox_language)
|
||||
{
|
||||
if (e_ext.vbox_language) {
|
||||
// german says "zwölfuhr und eins"
|
||||
// if (e_vbox_index_min == 1)
|
||||
// SCPY(buffer, "number_eine");
|
||||
// else
|
||||
SPRINT(buffer, "number_%02d", e_vbox_index_min); /* 1-59 minutes */
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
SPRINT(buffer, "number_%02d", e_vbox_index_min);
|
||||
}
|
||||
set_tone_vbox(buffer);
|
||||
|
@ -805,12 +748,10 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
case VBOX_STATE_CALLINFO_MINUTES:
|
||||
start_digits:
|
||||
e_vbox_state = VBOX_STATE_CALLINFO_DIGIT;
|
||||
if (e_vbox_index_callerid[0]=='\0' || !strcmp(e_vbox_index_callerid,"anonymous") || !strcmp(e_vbox_index_callerid,"unknown"))
|
||||
{
|
||||
if (e_vbox_index_callerid[0]=='\0' || !strcmp(e_vbox_index_callerid,"anonymous") || !strcmp(e_vbox_index_callerid,"unknown")) {
|
||||
set_tone_vbox("call_anonymous");
|
||||
e_vbox_index_callerid_index = strlen(e_vbox_index_callerid);
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
set_tone_vbox("call_from");
|
||||
e_vbox_index_callerid_index = 0;
|
||||
}
|
||||
|
@ -819,13 +760,11 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
case VBOX_STATE_CALLINFO_DIGIT:
|
||||
while (e_vbox_index_callerid[e_vbox_index_callerid_index] && (e_vbox_index_callerid[e_vbox_index_callerid_index]<'0' || e_vbox_index_callerid[e_vbox_index_callerid_index]>'9'))
|
||||
e_vbox_index_callerid_index++;
|
||||
if (e_vbox_index_callerid[e_vbox_index_callerid_index])
|
||||
{
|
||||
if (e_vbox_index_callerid[e_vbox_index_callerid_index]) {
|
||||
SPRINT(buffer, "number_%02d", e_vbox_index_callerid[e_vbox_index_callerid_index]-'0');
|
||||
set_tone_vbox(buffer);
|
||||
e_vbox_index_callerid_index ++;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* the callinfo is played, so we start with the call */
|
||||
e_vbox_counter = 0;
|
||||
e_vbox_counter_last = 0;
|
||||
|
@ -864,14 +803,12 @@ void EndpointAppPBX::vbox_message_eof(void)
|
|||
|
||||
case VBOX_STATE_STORE_DONE:
|
||||
case VBOX_STATE_DELETE_DONE:
|
||||
if (e_vbox_index_num == 0) /* nothing to play */
|
||||
{
|
||||
if (e_vbox_index_num == 0) { /* nothing to play */
|
||||
e_vbox_state = VBOX_STATE_MENU;
|
||||
SCPY(e_vbox_display, (char *)((language)?"keine Anrufe":"no calls"));
|
||||
e_vbox_display_refresh = 1;
|
||||
set_tone_vbox("nothing");
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
e_vbox_state = VBOX_STATE_MENU;
|
||||
SCPY(e_vbox_display, (char *)((language)?"druecke 2 f. wiedergabe":"press 2 to play"));
|
||||
e_vbox_display_refresh = 1;
|
||||
|
@ -897,8 +834,7 @@ void EndpointAppPBX::set_tone_vbox(const char *tone)
|
|||
if (tone == NULL)
|
||||
tone = "";
|
||||
|
||||
if (!ea_endpoint->ep_portlist)
|
||||
{
|
||||
if (!ea_endpoint->ep_portlist) {
|
||||
PERROR("EPOINT(%d) no portlist\n", ea_endpoint->ep_serial);
|
||||
}
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_VBOX_TONE);
|
||||
|
@ -932,8 +868,7 @@ void EndpointAppPBX::set_play_vbox(const char *file, int offset)
|
|||
if (!strcmp(filename+strlen(filename)-5, ".isdn")) /* filename is always more than 5 digits long */
|
||||
filename[strlen(filename)-5] = '\0';
|
||||
|
||||
if (!ea_endpoint->ep_portlist)
|
||||
{
|
||||
if (!ea_endpoint->ep_portlist) {
|
||||
PERROR("EPOINT(%d) no portlist\n", ea_endpoint->ep_serial);
|
||||
}
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_VBOX_PLAY);
|
||||
|
@ -953,8 +888,7 @@ void EndpointAppPBX::set_play_speed(int speed)
|
|||
{
|
||||
struct lcr_msg *message;
|
||||
|
||||
if (!ea_endpoint->ep_portlist)
|
||||
{
|
||||
if (!ea_endpoint->ep_portlist) {
|
||||
PERROR("EPOINT(%d) no portlist\n", ea_endpoint->ep_serial);
|
||||
}
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_VBOX_PLAY_SPEED);
|
||||
|
|
|
@ -228,8 +228,7 @@ void generate_tables(char law)
|
|||
{
|
||||
int i, j;
|
||||
|
||||
if (law == 'a')
|
||||
{
|
||||
if (law == 'a') {
|
||||
audio_law_to_s32=audio_alaw_to_s32;
|
||||
/* generating alaw-table */
|
||||
i = j = 0;
|
||||
|
@ -242,8 +241,7 @@ void generate_tables(char law)
|
|||
= audio_alaw_relations[(j<<1)|1];
|
||||
i++;
|
||||
}
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
audio_law_to_s32=audio_ulaw_to_s32;
|
||||
/* generating ulaw-table */
|
||||
i = j = 0;
|
||||
|
|
93
bchannel.c
93
bchannel.c
|
@ -133,16 +133,14 @@ int bchannel_create(struct bchannel *bchannel, int mode)
|
|||
unsigned int on = 1;
|
||||
struct sockaddr_mISDN addr;
|
||||
|
||||
if (bchannel->b_sock > -1)
|
||||
{
|
||||
if (bchannel->b_sock > -1) {
|
||||
CERROR(bchannel->call, NULL, "Socket already created for handle 0x%x\n", bchannel->handle);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* open socket */
|
||||
bchannel->b_mode = mode;
|
||||
switch(bchannel->b_mode)
|
||||
{
|
||||
switch(bchannel->b_mode) {
|
||||
case 0:
|
||||
CDEBUG(bchannel->call, NULL, "Open DSP audio\n");
|
||||
bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
|
||||
|
@ -160,16 +158,14 @@ int bchannel_create(struct bchannel *bchannel, int mode)
|
|||
bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_HDLC);
|
||||
break;
|
||||
}
|
||||
if (bchannel->b_sock < 0)
|
||||
{
|
||||
if (bchannel->b_sock < 0) {
|
||||
CERROR(bchannel->call, NULL, "Failed to open bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", bchannel->handle);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* set nonblocking io */
|
||||
ret = ioctl(bchannel->b_sock, FIONBIO, &on);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret < 0) {
|
||||
CERROR(bchannel->call, NULL, "Failed to set bchannel-socket handle 0x%x into nonblocking IO\n", bchannel->handle);
|
||||
close(bchannel->b_sock);
|
||||
bchannel->b_sock = -1;
|
||||
|
@ -181,8 +177,7 @@ int bchannel_create(struct bchannel *bchannel, int mode)
|
|||
addr.dev = (bchannel->handle>>8);
|
||||
addr.channel = bchannel->handle & 0xff;
|
||||
ret = bind(bchannel->b_sock, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret < 0) {
|
||||
CERROR(bchannel->call, NULL, "Failed to bind bchannel-socket for handle 0x%x with mISDN-DSP layer. (port %d, channel %d) Did you load mISDN_dsp.ko?\n", bchannel->handle, addr.dev, addr.channel);
|
||||
close(bchannel->b_sock);
|
||||
bchannel->b_sock = -1;
|
||||
|
@ -202,8 +197,7 @@ void bchannel_activate(struct bchannel *bchannel, int activate)
|
|||
|
||||
/* activate bchannel */
|
||||
CDEBUG(bchannel->call, NULL, "%sActivating B-channel.\n", activate?"":"De-");
|
||||
switch(bchannel->b_mode)
|
||||
{
|
||||
switch(bchannel->b_mode) {
|
||||
case 0:
|
||||
case 2:
|
||||
act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
|
||||
|
@ -269,8 +263,7 @@ static void bchannel_activated(struct bchannel *bchannel)
|
|||
*/
|
||||
void bchannel_destroy(struct bchannel *bchannel)
|
||||
{
|
||||
if (bchannel->b_sock > -1)
|
||||
{
|
||||
if (bchannel->b_sock > -1) {
|
||||
close(bchannel->b_sock);
|
||||
bchannel->b_sock = -1;
|
||||
}
|
||||
|
@ -291,24 +284,20 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned char *buffer, i
|
|||
struct bchannel *remote_bchannel;
|
||||
int ret;
|
||||
|
||||
if (hh->prim == PH_CONTROL_IND)
|
||||
{
|
||||
if (hh->prim == PH_CONTROL_IND) {
|
||||
/* non dsp -> ignore ph_control */
|
||||
if (bchannel->b_mode == 1 || bchannel->b_mode == 3)
|
||||
return;
|
||||
if (len < 4)
|
||||
{
|
||||
if (len < 4) {
|
||||
CERROR(bchannel->call, NULL, "SHORT READ OF PH_CONTROL INDICATION\n");
|
||||
return;
|
||||
}
|
||||
if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
|
||||
{
|
||||
if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
|
||||
if (bchannel->call)
|
||||
lcr_in_dtmf(bchannel->call, cont & DTMF_TONE_MASK);
|
||||
return;
|
||||
}
|
||||
switch(cont)
|
||||
{
|
||||
switch(cont) {
|
||||
case DSP_BF_REJECT:
|
||||
CERROR(bchannel->call, NULL, "Blowfish crypt rejected.\n");
|
||||
break;
|
||||
|
@ -322,18 +311,15 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned char *buffer, i
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (hh->prim == PH_DATA_REQ)
|
||||
{
|
||||
if (!bchannel->b_txdata)
|
||||
{
|
||||
if (hh->prim == PH_DATA_REQ) {
|
||||
if (!bchannel->b_txdata) {
|
||||
/* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
|
||||
CDEBUG(bchannel->call, NULL, "ignoring tx data, because 'txdata' is turned off\n");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
|
||||
{
|
||||
if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
|
||||
CERROR(bchannel->call, NULL, "Bchannel received unknown primitve: 0x%lx\n", hh->prim);
|
||||
return;
|
||||
}
|
||||
|
@ -364,32 +350,27 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned char *buffer, i
|
|||
*/
|
||||
|
||||
/* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
|
||||
if (bchannel->b_rxoff)
|
||||
{
|
||||
if (bchannel->b_rxoff) {
|
||||
CDEBUG(bchannel->call, NULL, "ignoring data, because rx is turned off\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bchannel->call)
|
||||
{
|
||||
if (!bchannel->call) {
|
||||
CDEBUG(bchannel->call, NULL, "ignoring data, because no call associated with bchannel\n");
|
||||
return;
|
||||
}
|
||||
if (!bchannel->call->audiopath)
|
||||
{
|
||||
if (!bchannel->call->audiopath) {
|
||||
/* return, because we have no audio from port */
|
||||
return;
|
||||
}
|
||||
|
||||
if (bchannel->call->pipe[1] < 0)
|
||||
{
|
||||
if (bchannel->call->pipe[1] < 0) {
|
||||
/* nobody there */
|
||||
return;
|
||||
}
|
||||
|
||||
/* if no hdlc */
|
||||
if (bchannel->b_mode == 0 || bchannel->b_mode == 1)
|
||||
{
|
||||
if (bchannel->b_mode == 0 || bchannel->b_mode == 1) {
|
||||
d = data;
|
||||
for (i = 0; i < len; i++) {
|
||||
*d = flip_bits[*d];
|
||||
|
@ -424,8 +405,7 @@ void bchannel_transmit(struct bchannel *bchannel, unsigned char *data, int len)
|
|||
return;
|
||||
if (len > 1024 || len < 1)
|
||||
return;
|
||||
switch(bchannel->b_mode)
|
||||
{
|
||||
switch(bchannel->b_mode) {
|
||||
case 0:
|
||||
for (i = 0; i < len; i++)
|
||||
*p++ = flip_bits[*data++];
|
||||
|
@ -467,8 +447,7 @@ void bchannel_join(struct bchannel *bchannel, unsigned short id)
|
|||
bchannel->b_conf = 0;
|
||||
bchannel->b_rxoff = 0;
|
||||
}
|
||||
if (bchannel->b_state == BSTATE_ACTIVE)
|
||||
{
|
||||
if (bchannel->b_state == BSTATE_ACTIVE) {
|
||||
ph_control(sock, DSP_RECEIVE_OFF, bchannel->b_rxoff, "DSP-RX_OFF", bchannel->b_conf, bchannel->b_mode);
|
||||
ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode);
|
||||
}
|
||||
|
@ -547,17 +526,13 @@ int bchannel_handle(void)
|
|||
|
||||
/* process all bchannels */
|
||||
bchannel = bchannel_first;
|
||||
while(bchannel)
|
||||
{
|
||||
while(bchannel) {
|
||||
/* handle message from bchannel */
|
||||
if (bchannel->b_sock > -1)
|
||||
{
|
||||
if (bchannel->b_sock > -1) {
|
||||
ret = recv(bchannel->b_sock, buffer, sizeof(buffer), 0);
|
||||
if (ret >= (int)MISDN_HEADER_LEN)
|
||||
{
|
||||
if (ret >= (int)MISDN_HEADER_LEN) {
|
||||
work = 1;
|
||||
switch(hh->prim)
|
||||
{
|
||||
switch(hh->prim) {
|
||||
/* we don't care about confirms, we use rx data to sync tx */
|
||||
case PH_DATA_CNF:
|
||||
break;
|
||||
|
@ -589,8 +564,7 @@ int bchannel_handle(void)
|
|||
default:
|
||||
CERROR(bchannel->call, NULL, "child message not handled: prim(0x%x) socket(%d) data len(%d)\n", hh->prim, bchannel->b_sock, ret - MISDN_HEADER_LEN);
|
||||
}
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
if (ret < 0 && errno != EWOULDBLOCK)
|
||||
CERROR(bchannel->call, NULL, "Read from socket %d failed with return code %d\n", bchannel->b_sock, ret);
|
||||
}
|
||||
|
@ -611,8 +585,7 @@ struct bchannel *find_bchannel_handle(unsigned int handle)
|
|||
{
|
||||
struct bchannel *bchannel = bchannel_first;
|
||||
|
||||
while(bchannel)
|
||||
{
|
||||
while(bchannel) {
|
||||
if (bchannel->handle == handle)
|
||||
break;
|
||||
bchannel = bchannel->next;
|
||||
|
@ -625,8 +598,7 @@ struct bchannel *find_bchannel_ref(unsigned int ref)
|
|||
{
|
||||
struct bchannel *bchannel = bchannel_first;
|
||||
|
||||
while(bchannel)
|
||||
{
|
||||
while(bchannel) {
|
||||
if (bchannel->ref == ref)
|
||||
break;
|
||||
bchannel = bchannel->next;
|
||||
|
@ -656,15 +628,12 @@ void free_bchannel(struct bchannel *bchannel)
|
|||
{
|
||||
struct bchannel **temp = &bchannel_first;
|
||||
|
||||
while(*temp)
|
||||
{
|
||||
if (*temp == bchannel)
|
||||
{
|
||||
while(*temp) {
|
||||
if (*temp == bchannel) {
|
||||
*temp = (*temp)->next;
|
||||
if (bchannel->b_sock > -1)
|
||||
bchannel_destroy(bchannel);
|
||||
if (bchannel->call)
|
||||
{
|
||||
if (bchannel->call) {
|
||||
if (bchannel->call->bchannel)
|
||||
bchannel->call->bchannel = NULL;
|
||||
}
|
||||
|
|
173
bootstrap.c
173
bootstrap.c
|
@ -460,7 +460,6 @@ static void bootstrap_om_bs11(struct gsm_bts *bts)
|
|||
|
||||
/* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
|
||||
abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
|
||||
set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
|
||||
abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
|
||||
|
||||
/* Use TEI 1 for signalling */
|
||||
|
@ -477,43 +476,36 @@ static void bootstrap_om_bs11(struct gsm_bts *bts)
|
|||
/* SET CHANNEL ATTRIBUTE TS1 */
|
||||
abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
|
||||
set_ts_e1link(&trx->ts[1], 0, 2, 1);
|
||||
abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS2 */
|
||||
abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
|
||||
set_ts_e1link(&trx->ts[2], 0, 2, 2);
|
||||
abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS3 */
|
||||
abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
|
||||
set_ts_e1link(&trx->ts[3], 0, 2, 3);
|
||||
abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS4 */
|
||||
abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
|
||||
set_ts_e1link(&trx->ts[4], 0, 3, 0);
|
||||
abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS5 */
|
||||
abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
|
||||
set_ts_e1link(&trx->ts[5], 0, 3, 1);
|
||||
abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS6 */
|
||||
abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
|
||||
set_ts_e1link(&trx->ts[6], 0, 3, 2);
|
||||
abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS7 */
|
||||
abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
|
||||
set_ts_e1link(&trx->ts[7], 0, 3, 3);
|
||||
abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
|
||||
|
||||
/* end DB transmission */
|
||||
|
@ -586,6 +578,48 @@ static u_int8_t si1[] = {
|
|||
/* s1 reset*/0x2B
|
||||
};
|
||||
|
||||
static u_int8_t *gsm48_si1(u_int8_t *arfcn_list, int arfcn_len, int max_trans, int tx_integer, int cell_barr, int re, int ec, u_int8_t *ac_list, int ac_len)
|
||||
{
|
||||
static u_int8_t si[23];
|
||||
int i, bit, octet;
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
|
||||
/* header */
|
||||
si[0] = 0x55;
|
||||
si[1] = 0x06;
|
||||
si[2] = 0x19;
|
||||
/* ccdesc */
|
||||
for (i = 0; i < arfcn_len; i++) {
|
||||
if (arfcn_list[i] <= 124 && arfcn_list[i] > 0) {
|
||||
bit = (arfcn_list[i] - 1) & 7;
|
||||
octet = (arfcn_list[i] -1) / 8;
|
||||
si[18 - octet] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
/* rach */
|
||||
si[19] = (max_trans << 6);
|
||||
si[19] |= (tx_integer << 2);
|
||||
si[19] |= (cell_barr << 1);
|
||||
si[19] |= re;
|
||||
si[20] = (ec << 2);
|
||||
for (i = 0; i < ac_len; i++) {
|
||||
if (ac_list[i] <= 15 && ac_list[i] != 10) {
|
||||
bit = ac_list[i] & 7;
|
||||
octet = ac_list[i] / 8;
|
||||
si[21 - octet] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
/* s1 rest */
|
||||
si[22] = 0x2B;
|
||||
|
||||
/* testig */
|
||||
if (memcmp(&si1, &si, sizeof(si)))
|
||||
printf("SI1 does not match default template.\n");
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
/*
|
||||
SYSTEM INFORMATION TYPE 2
|
||||
Neighbour Cells Description
|
||||
|
@ -609,6 +643,49 @@ static u_int8_t si2[] = {
|
|||
/* rach*/0xD5, 0x00, 0x00
|
||||
};
|
||||
|
||||
static u_int8_t *gsm48_si2(int ba, u_int8_t *arfcn_list, int arfcn_len, u_int8_t ncc, int max_trans, int tx_integer, int cell_barr, int re, int ec, u_int8_t *ac_list, int ac_len)
|
||||
{
|
||||
static u_int8_t si[23];
|
||||
int i, bit, octet;
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
|
||||
/* header */
|
||||
si[0] = 0x59;
|
||||
si[1] = 0x06;
|
||||
si[2] = 0x1A;
|
||||
/* ncdesc */
|
||||
si[3] = (ba << 4);
|
||||
for (i = 0; i < arfcn_len; i++) {
|
||||
if (arfcn_list[i] <= 124 && arfcn_list[i] > 0) {
|
||||
bit = (arfcn_list[i] - 1) & 7;
|
||||
octet = (arfcn_list[i] -1) / 8;
|
||||
si[18 - octet] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
/* ncc */
|
||||
si[19] = ncc;
|
||||
/* rach */
|
||||
si[20] = (max_trans << 6);
|
||||
si[20] |= (tx_integer << 2);
|
||||
si[20] |= (cell_barr << 1);
|
||||
si[20] |= re;
|
||||
si[21] = (ec << 2);
|
||||
for (i = 0; i < ac_len; i++) {
|
||||
if (ac_list[i] <= 15 && ac_list[i] != 10) {
|
||||
bit = ac_list[i] & 7;
|
||||
octet = ac_list[i] / 8;
|
||||
si[22 - octet] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
|
||||
/* testig */
|
||||
if (memcmp(&si2, &si, sizeof(si)))
|
||||
printf("SI2 does not match default template.\n");
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
/*
|
||||
SYSTEM INFORMATION TYPE 3
|
||||
Cell identity = 00001 (1h)
|
||||
|
@ -711,6 +788,33 @@ static u_int8_t si5[] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u_int8_t *gsm48_si5(int ba, u_int8_t *arfcn_list, int arfcn_len)
|
||||
{
|
||||
static u_int8_t si[18];
|
||||
int i, bit, octet;
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
|
||||
/* header */
|
||||
si[0] = 0x06;
|
||||
si[1] = 0x1D;
|
||||
/* ncdesc */
|
||||
si[2] = (ba << 4);
|
||||
for (i = 0; i < arfcn_len; i++) {
|
||||
if (arfcn_list[i] <= 124 && arfcn_list[i] > 0) {
|
||||
bit = (arfcn_list[i] - 1) & 7;
|
||||
octet = (arfcn_list[i] -1) / 8;
|
||||
si[17 - octet] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
|
||||
/* testig */
|
||||
if (memcmp(&si3, &si, sizeof(si)))
|
||||
printf("SI3 does not match default template.\n");
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
// SYSTEM INFORMATION TYPE 6
|
||||
|
||||
/*
|
||||
|
@ -772,13 +876,37 @@ static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), typ
|
|||
static int set_system_infos(struct gsm_bts_trx *trx)
|
||||
{
|
||||
unsigned int i;
|
||||
u_int8_t *_si1;
|
||||
u_int8_t *_si2;
|
||||
u_int8_t *_si5;
|
||||
u_int8_t arfcn_list[8];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
|
||||
arfcn_list[0] = trx->arfcn;
|
||||
_si1 = gsm48_si1(arfcn_list, 1, 3, 5, 0, 1, 0, NULL, 0);
|
||||
|
||||
memset(arfcn_list, 0, sizeof(arfcn_list));
|
||||
arfcn_list[0] = trx->arfcn;
|
||||
arfcn_list[1] = 112;
|
||||
arfcn_list[2] = 62;
|
||||
arfcn_list[3] = 99;
|
||||
arfcn_list[4] = 77;
|
||||
arfcn_list[5] = 64;
|
||||
arfcn_list[6] = 54;
|
||||
arfcn_list[7] = 51;
|
||||
_si2 = gsm48_si2(0, arfcn_list, 8, 0xff, 3, 5, 0, 1, 0, NULL, 0);
|
||||
_si5 = gsm48_si5(0, arfcn_list, 8);
|
||||
|
||||
rsl_bcch_info(trx, RSL_SYSTEM_INFO_1, _si1, 23);
|
||||
rsl_bcch_info(trx, RSL_SYSTEM_INFO_2, _si2, 23);
|
||||
// rsl_bcch_info(trx, RSL_SYSTEM_INFO_3, _si3, );
|
||||
// rsl_bcch_info(trx, RSL_SYSTEM_INFO_4, _si4, );
|
||||
|
||||
for (i = 2; i < ARRAY_SIZE(bcch_infos); i++) {
|
||||
rsl_bcch_info(trx, bcch_infos[i].type,
|
||||
bcch_infos[i].data,
|
||||
bcch_infos[i].len);
|
||||
}
|
||||
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
|
||||
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, _si5, 18);
|
||||
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
|
||||
|
||||
return 0;
|
||||
|
@ -790,6 +918,7 @@ static int set_system_infos(struct gsm_bts_trx *trx)
|
|||
*/
|
||||
static void patch_tables(struct gsm_bts *bts)
|
||||
{
|
||||
#warning todo
|
||||
u_int8_t arfcn_low = bts->trx[0].arfcn & 0xff;
|
||||
u_int8_t arfcn_high = (bts->trx[0].arfcn >> 8) & 0x0f;
|
||||
/* covert the raw packet to the struct */
|
||||
|
@ -880,6 +1009,30 @@ static int bootstrap_bts(struct gsm_bts *bts, int lac, int arfcn)
|
|||
|
||||
paging_init(bts);
|
||||
|
||||
if (bts->type == GSM_BTS_TYPE_BS11) {
|
||||
struct gsm_bts_trx *trx = &bts->trx[0];
|
||||
set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
|
||||
set_ts_e1link(&trx->ts[1], 0, 2, 1);
|
||||
set_ts_e1link(&trx->ts[2], 0, 2, 2);
|
||||
set_ts_e1link(&trx->ts[3], 0, 2, 3);
|
||||
set_ts_e1link(&trx->ts[4], 0, 3, 0);
|
||||
set_ts_e1link(&trx->ts[5], 0, 3, 1);
|
||||
set_ts_e1link(&trx->ts[6], 0, 3, 2);
|
||||
set_ts_e1link(&trx->ts[7], 0, 3, 3);
|
||||
#ifdef HAVE_TRX1
|
||||
/* TRX 1 */
|
||||
trx = &bts->trx[1];
|
||||
set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
|
||||
set_ts_e1link(&trx->ts[1], 0, 2, 1);
|
||||
set_ts_e1link(&trx->ts[2], 0, 2, 2);
|
||||
set_ts_e1link(&trx->ts[3], 0, 2, 3);
|
||||
set_ts_e1link(&trx->ts[4], 0, 3, 0);
|
||||
set_ts_e1link(&trx->ts[5], 0, 3, 1);
|
||||
set_ts_e1link(&trx->ts[6], 0, 3, 2);
|
||||
set_ts_e1link(&trx->ts[7], 0, 3, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,11 @@
|
|||
*/
|
||||
const char *nationalize_callerinfo(const char *string, int *ntype, const char *national, const char *international)
|
||||
{
|
||||
if (!strncmp(international, string, strlen(international)))
|
||||
{
|
||||
if (!strncmp(international, string, strlen(international))) {
|
||||
*ntype = INFO_NTYPE_INTERNATIONAL;
|
||||
return(string+strlen(international));
|
||||
}
|
||||
if (!strncmp(national, string, strlen(national)))
|
||||
{
|
||||
if (!strncmp(national, string, strlen(national))) {
|
||||
*ntype = INFO_NTYPE_NATIONAL;
|
||||
return(string+strlen(national));
|
||||
}
|
||||
|
@ -41,8 +39,7 @@ const char *numberrize_callerinfo(const char *string, int ntype, const char *nat
|
|||
{
|
||||
static char result[256];
|
||||
|
||||
switch(ntype)
|
||||
{
|
||||
switch(ntype) {
|
||||
case INFO_NTYPE_NOTPRESENT:
|
||||
return("");
|
||||
|
||||
|
|
21
cause.c
21
cause.c
|
@ -383,37 +383,30 @@ char *get_isdn_cause(int cause, int location, int type)
|
|||
*/
|
||||
void collect_cause(int *multicause, int *multilocation, int newcause, int newlocation)
|
||||
{
|
||||
if (newcause == CAUSE_REJECTED) /* call rejected */
|
||||
{
|
||||
if (newcause == CAUSE_REJECTED) { /* call rejected */
|
||||
*multicause = newcause;
|
||||
*multilocation = newlocation;
|
||||
} else
|
||||
if (newcause==CAUSE_NORMAL && *multicause!=CAUSE_REJECTED) /* reject via hangup */
|
||||
{
|
||||
if (newcause==CAUSE_NORMAL && *multicause!=CAUSE_REJECTED) { /* reject via hangup */
|
||||
*multicause = newcause;
|
||||
*multilocation = newlocation;
|
||||
} else
|
||||
if (newcause==CAUSE_BUSY && *multicause!=CAUSE_REJECTED && *multicause!=CAUSE_NORMAL) /* busy */
|
||||
{
|
||||
if (newcause==CAUSE_BUSY && *multicause!=CAUSE_REJECTED && *multicause!=CAUSE_NORMAL) { /* busy */
|
||||
*multicause = newcause;
|
||||
*multilocation = newlocation;
|
||||
} else
|
||||
if (newcause==CAUSE_OUTOFORDER && *multicause!=CAUSE_BUSY && *multicause!=CAUSE_REJECTED && *multicause!=CAUSE_NORMAL) /* no L1 */
|
||||
{
|
||||
if (newcause==CAUSE_OUTOFORDER && *multicause!=CAUSE_BUSY && *multicause!=CAUSE_REJECTED && *multicause!=CAUSE_NORMAL) { /* no L1 */
|
||||
*multicause = newcause;
|
||||
*multilocation = newlocation;
|
||||
} else
|
||||
if (newcause!=CAUSE_NOUSER && *multicause!=CAUSE_OUTOFORDER && *multicause!=CAUSE_BUSY && *multicause!=CAUSE_REJECTED && *multicause!=CAUSE_NORMAL) /* anything but not 18 */
|
||||
{
|
||||
if (newcause!=CAUSE_NOUSER && *multicause!=CAUSE_OUTOFORDER && *multicause!=CAUSE_BUSY && *multicause!=CAUSE_REJECTED && *multicause!=CAUSE_NORMAL) { /* anything but not 18 */
|
||||
*multicause = newcause;
|
||||
*multilocation = newlocation;
|
||||
} else
|
||||
if (newcause==CAUSE_NOUSER && *multicause==CAUSE_NOUSER) /* cause 18, use the location */
|
||||
{
|
||||
if (newcause==CAUSE_NOUSER && *multicause==CAUSE_NOUSER) { /* cause 18, use the location */
|
||||
*multilocation = newlocation;
|
||||
} else
|
||||
if (*multicause==0) /* no cause yet, use newcause (should be 18) */
|
||||
{
|
||||
if (*multicause==0) { /* no cause yet, use newcause (should be 18) */
|
||||
*multicause = newcause;
|
||||
*multilocation = newlocation;
|
||||
}
|
||||
|
|
204
chan_lcr.c
204
chan_lcr.c
|
@ -254,8 +254,7 @@ struct chan_call *find_call_ref(unsigned int ref)
|
|||
struct chan_call *call = call_first;
|
||||
int assigned = (ref > 0);
|
||||
|
||||
while(call)
|
||||
{
|
||||
while(call) {
|
||||
if (call->ref == ref && call->ref_was_assigned == assigned)
|
||||
break;
|
||||
call = call->next;
|
||||
|
@ -267,23 +266,19 @@ void free_call(struct chan_call *call)
|
|||
{
|
||||
struct chan_call **temp = &call_first;
|
||||
|
||||
while(*temp)
|
||||
{
|
||||
if (*temp == call)
|
||||
{
|
||||
while(*temp) {
|
||||
if (*temp == call) {
|
||||
*temp = (*temp)->next;
|
||||
if (call->pipe[0] > -1)
|
||||
close(call->pipe[0]);
|
||||
if (call->pipe[1] > -1)
|
||||
close(call->pipe[1]);
|
||||
if (call->bchannel)
|
||||
{
|
||||
if (call->bchannel) {
|
||||
if (call->bchannel->call != call)
|
||||
CERROR(call, NULL, "Linked bchannel structure has no link to us.\n");
|
||||
call->bchannel->call = NULL;
|
||||
}
|
||||
if (call->bridge_call)
|
||||
{
|
||||
if (call->bridge_call) {
|
||||
if (call->bridge_call->bridge_call != call)
|
||||
CERROR(call, NULL, "Linked call structure has no link to us.\n");
|
||||
call->bridge_call->bridge_call = NULL;
|
||||
|
@ -327,11 +322,9 @@ unsigned short new_bridge_id(void)
|
|||
unsigned short id = 1;
|
||||
|
||||
/* search for lowest bridge id that is not in use and not 0 */
|
||||
while(id)
|
||||
{
|
||||
while(id) {
|
||||
call = call_first;
|
||||
while(call)
|
||||
{
|
||||
while(call) {
|
||||
if (call->bridge_id == id)
|
||||
break;
|
||||
call = call->next;
|
||||
|
@ -391,8 +384,7 @@ void apply_opt(struct chan_call *call, char *data)
|
|||
string[sizeof(string)-1] = '\0';
|
||||
|
||||
/* parse options */
|
||||
while((opt = strsep(&p, ":")))
|
||||
{
|
||||
while((opt = strsep(&p, ":"))) {
|
||||
switch(opt[0]) {
|
||||
case 'd':
|
||||
if (opt[1] == '\0') {
|
||||
|
@ -437,8 +429,7 @@ void apply_opt(struct chan_call *call, char *data)
|
|||
break;
|
||||
}
|
||||
i = 0;
|
||||
while(*key)
|
||||
{
|
||||
while(*key) {
|
||||
if (*key>='0' && *key<='9')
|
||||
call->bf_key[i] = (*key-'0') << 8;
|
||||
else if (*key>='a' && *key<='f')
|
||||
|
@ -605,14 +596,12 @@ static void send_setup_to_lcr(struct chan_call *call)
|
|||
strncpy(newparam.setup.callerinfo.id, call->cid_num, sizeof(newparam.setup.callerinfo.id)-1);
|
||||
if (call->cid_name[0])
|
||||
strncpy(newparam.setup.callerinfo.name, call->cid_name, sizeof(newparam.setup.callerinfo.name)-1);
|
||||
if (call->cid_rdnis[0])
|
||||
{
|
||||
if (call->cid_rdnis[0]) {
|
||||
strncpy(newparam.setup.redirinfo.id, call->cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
|
||||
newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
|
||||
newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
}
|
||||
switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
|
||||
{
|
||||
switch(ast->cid.cid_pres & AST_PRES_RESTRICTION) {
|
||||
case AST_PRES_RESTRICTED:
|
||||
newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
|
||||
break;
|
||||
|
@ -623,8 +612,7 @@ static void send_setup_to_lcr(struct chan_call *call)
|
|||
default:
|
||||
newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
|
||||
}
|
||||
switch(ast->cid.cid_ton)
|
||||
{
|
||||
switch(ast->cid.cid_ton) {
|
||||
case 4:
|
||||
newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
|
||||
break;
|
||||
|
@ -723,17 +711,14 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
|
||||
CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", exten, ast->context, complete?"yes":"no");
|
||||
|
||||
if (complete)
|
||||
{
|
||||
if (complete) {
|
||||
/* if not match */
|
||||
if (!ast_canmatch_extension(ast, ast->context, exten, 1, call->oad))
|
||||
{
|
||||
if (!ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) {
|
||||
CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at context '%s' - releasing.\n", exten, ast->context);
|
||||
cause = 1;
|
||||
goto release;
|
||||
}
|
||||
if (!ast_exists_extension(ast, ast->context, exten, 1, call->oad))
|
||||
{
|
||||
if (!ast_exists_extension(ast, ast->context, exten, 1, call->oad)) {
|
||||
CDEBUG(call, ast, "Got 'sending complete', but extension '%s' would match at context '%s', if more digits would be dialed - releasing.\n", exten, ast->context);
|
||||
cause = 28;
|
||||
goto release;
|
||||
|
@ -749,8 +734,7 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
goto start;
|
||||
}
|
||||
|
||||
if (ast_canmatch_extension(ast, ast->context, exten, 1, call->oad))
|
||||
{
|
||||
if (ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) {
|
||||
/* send setup acknowledge to lcr */
|
||||
if (call->state != CHAN_LCR_STATE_IN_DIALING) {
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
|
@ -801,8 +785,7 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
#endif
|
||||
|
||||
ret = ast_pbx_start(ast);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret < 0) {
|
||||
cause = (ret==-2)?34:27;
|
||||
goto release;
|
||||
}
|
||||
|
@ -829,8 +812,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
|
|||
ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
|
||||
#endif
|
||||
|
||||
if (!ast)
|
||||
{
|
||||
if (!ast) {
|
||||
/* release */
|
||||
CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n");
|
||||
send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
|
||||
|
@ -857,8 +839,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
|
|||
ast->cid.cid_name = strdup(param->setup.callerinfo.name);
|
||||
if (param->setup.redirinfo.id[0])
|
||||
ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international));
|
||||
switch (param->setup.callerinfo.present)
|
||||
{
|
||||
switch (param->setup.callerinfo.present) {
|
||||
case INFO_PRESENT_ALLOWED:
|
||||
ast->cid.cid_pres = AST_PRES_ALLOWED;
|
||||
break;
|
||||
|
@ -868,8 +849,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
|
|||
default:
|
||||
ast->cid.cid_pres = AST_PRES_UNAVAILABLE;
|
||||
}
|
||||
switch (param->setup.callerinfo.ntype)
|
||||
{
|
||||
switch (param->setup.callerinfo.ntype) {
|
||||
case INFO_NTYPE_SUBSCRIBER:
|
||||
ast->cid.cid_ton = 4;
|
||||
break;
|
||||
|
@ -988,8 +968,7 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa
|
|||
/* if bridge, forward disconnect and return */
|
||||
#ifdef TODO
|
||||
feature flag
|
||||
if (call->bridge_call)
|
||||
{
|
||||
if (call->bridge_call) {
|
||||
CDEBUG(call, call->ast, "Only signal disconnect via bridge.\n");
|
||||
bridge_message_if_bridged(call, message_type, param);
|
||||
return;
|
||||
|
@ -1001,8 +980,7 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa
|
|||
/* change to release state */
|
||||
call->state = CHAN_LCR_STATE_RELEASE;
|
||||
/* queue release asterisk */
|
||||
if (ast)
|
||||
{
|
||||
if (ast) {
|
||||
ast->hangupcause = call->cause;
|
||||
if (call->pbx_started)
|
||||
strcpy(call->queue_string, "H"); // overwrite other indications
|
||||
|
@ -1026,22 +1004,19 @@ static void lcr_in_release(struct chan_call *call, int message_type, union param
|
|||
/* change to release state */
|
||||
call->state = CHAN_LCR_STATE_RELEASE;
|
||||
/* copy release info */
|
||||
if (!call->cause)
|
||||
{
|
||||
if (!call->cause) {
|
||||
call->cause = param->disconnectinfo.cause;
|
||||
call->location = param->disconnectinfo.location;
|
||||
}
|
||||
/* if we have an asterisk instance, queue hangup, else we are done */
|
||||
if (ast)
|
||||
{
|
||||
if (ast) {
|
||||
ast->hangupcause = call->cause;
|
||||
if (call->pbx_started)
|
||||
strcpy(call->queue_string, "H");
|
||||
else {
|
||||
ast_hangup(ast); // call will be destroyed here
|
||||
}
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
free_call(call);
|
||||
}
|
||||
|
||||
|
@ -1059,8 +1034,7 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p
|
|||
if (!ast) return;
|
||||
|
||||
/* pbx not started */
|
||||
if (!call->pbx_started)
|
||||
{
|
||||
if (!call->pbx_started) {
|
||||
CDEBUG(call, call->ast, "Asterisk not started, adding digits to number.\n");
|
||||
strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1);
|
||||
lcr_start_pbx(call, ast, param->information.sending_complete);
|
||||
|
@ -1185,21 +1159,17 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
memset(&newparam, 0, sizeof(union parameter));
|
||||
|
||||
/* handle bchannel message*/
|
||||
if (message_type == MESSAGE_BCHANNEL)
|
||||
{
|
||||
switch(param->bchannel.type)
|
||||
{
|
||||
if (message_type == MESSAGE_BCHANNEL) {
|
||||
switch(param->bchannel.type) {
|
||||
case BCHANNEL_ASSIGN:
|
||||
CDEBUG(NULL, NULL, "Received BCHANNEL_ASSIGN message. (handle=%08lx) for ref %d\n", param->bchannel.handle, ref);
|
||||
if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
|
||||
{
|
||||
if ((bchannel = find_bchannel_handle(param->bchannel.handle))) {
|
||||
CERROR(NULL, NULL, "bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
|
||||
return(-1);
|
||||
}
|
||||
/* create bchannel */
|
||||
bchannel = alloc_bchannel(param->bchannel.handle);
|
||||
if (!bchannel)
|
||||
{
|
||||
if (!bchannel) {
|
||||
CERROR(NULL, NULL, "alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1208,8 +1178,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
bchannel->b_tx_gain = param->bchannel.tx_gain;
|
||||
bchannel->b_rx_gain = param->bchannel.rx_gain;
|
||||
strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
|
||||
if (param->bchannel.crypt_len && param->bchannel.crypt_len <= sizeof(bchannel->b_bf_key))
|
||||
{
|
||||
if (param->bchannel.crypt_len && param->bchannel.crypt_len <= sizeof(bchannel->b_bf_key)) {
|
||||
bchannel->b_bf_len = param->bchannel.crypt_len;
|
||||
memcpy(bchannel->b_bf_key, param->bchannel.crypt, param->bchannel.crypt_len);
|
||||
}
|
||||
|
@ -1220,8 +1189,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
* be created until it is removed again by LCR */
|
||||
/* link to call */
|
||||
call = find_call_ref(ref);
|
||||
if (call)
|
||||
{
|
||||
if (call) {
|
||||
bchannel->call = call;
|
||||
call->bchannel = bchannel;
|
||||
if (call->dsp_dtmf)
|
||||
|
@ -1257,8 +1225,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
|
||||
case BCHANNEL_REMOVE:
|
||||
CDEBUG(NULL, NULL, "Received BCHANNEL_REMOVE message. (handle=%08lx)\n", param->bchannel.handle);
|
||||
if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
|
||||
{
|
||||
if (!(bchannel = find_bchannel_handle(param->bchannel.handle))) {
|
||||
CERROR(NULL, NULL, "Bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1279,14 +1246,11 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
}
|
||||
|
||||
/* handle new ref */
|
||||
if (message_type == MESSAGE_NEWREF)
|
||||
{
|
||||
if (param->direction)
|
||||
{
|
||||
if (message_type == MESSAGE_NEWREF) {
|
||||
if (param->direction) {
|
||||
/* new ref from lcr */
|
||||
CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref);
|
||||
if (!ref || find_call_ref(ref))
|
||||
{
|
||||
if (!ref || find_call_ref(ref)) {
|
||||
CERROR(NULL, NULL, "Illegal new ref %ld received.\n", ref);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1300,13 +1264,11 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
/* set dtmf (default, use option 'n' to disable */
|
||||
call->dsp_dtmf = 1;
|
||||
/* wait for setup (or release from asterisk) */
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* new ref, as requested from this remote application */
|
||||
CDEBUG(NULL, NULL, "Received new ref by LCR, as requested from chan_lcr. (ref=%ld)\n", ref);
|
||||
call = find_call_ref(0);
|
||||
if (!call)
|
||||
{
|
||||
if (!call) {
|
||||
/* send release, if ref does not exist */
|
||||
CDEBUG(NULL, NULL, "No call found, that requests a ref.\n");
|
||||
send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
|
||||
|
@ -1319,8 +1281,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
|
||||
send_setup_to_lcr(call);
|
||||
/* release if asterisk has signed off */
|
||||
else if (call->state == CHAN_LCR_STATE_RELEASE)
|
||||
{
|
||||
else if (call->state == CHAN_LCR_STATE_RELEASE) {
|
||||
/* send release */
|
||||
if (call->cause)
|
||||
send_release_and_import(call, call->cause, call->location);
|
||||
|
@ -1335,22 +1296,19 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
|
|||
}
|
||||
|
||||
/* check ref */
|
||||
if (!ref)
|
||||
{
|
||||
if (!ref) {
|
||||
CERROR(NULL, NULL, "Received message %d without ref.\n", message_type);
|
||||
return(-1);
|
||||
}
|
||||
call = find_call_ref(ref);
|
||||
if (!call)
|
||||
{
|
||||
if (!call) {
|
||||
/* ignore ref that is not used (anymore) */
|
||||
CDEBUG(NULL, NULL, "Message %d from LCR ignored, because no call instance found.\n", message_type);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* handle messages */
|
||||
switch(message_type)
|
||||
{
|
||||
switch(message_type) {
|
||||
case MESSAGE_SETUP:
|
||||
lcr_in_setup(call, message_type, param);
|
||||
break;
|
||||
|
@ -1463,29 +1421,23 @@ int handle_socket(void)
|
|||
|
||||
/* read from socket */
|
||||
len = read(lcr_sock, &msg, sizeof(msg));
|
||||
if (len == 0)
|
||||
{
|
||||
if (len == 0) {
|
||||
CERROR(NULL, NULL, "Socket closed.\n");
|
||||
return(-1); // socket closed
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
if (len != sizeof(msg))
|
||||
{
|
||||
if (len > 0) {
|
||||
if (len != sizeof(msg)) {
|
||||
CERROR(NULL, NULL, "Socket short read. (len %d)\n", len);
|
||||
return(-1); // socket error
|
||||
}
|
||||
if (msg.message != ADMIN_MESSAGE)
|
||||
{
|
||||
if (msg.message != ADMIN_MESSAGE) {
|
||||
CERROR(NULL, NULL, "Socket received illegal message %d.\n", msg.message);
|
||||
return(-1);
|
||||
}
|
||||
receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
|
||||
work = 1;
|
||||
} else
|
||||
{
|
||||
if (errno != EWOULDBLOCK)
|
||||
{
|
||||
} else {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1496,15 +1448,12 @@ int handle_socket(void)
|
|||
return(work);
|
||||
admin = admin_first;
|
||||
len = write(lcr_sock, &admin->msg, sizeof(msg));
|
||||
if (len == 0)
|
||||
{
|
||||
if (len == 0) {
|
||||
CERROR(NULL, NULL, "Socket closed.\n");
|
||||
return(-1); // socket closed
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
if (len != sizeof(msg))
|
||||
{
|
||||
if (len > 0) {
|
||||
if (len != sizeof(msg)) {
|
||||
CERROR(NULL, NULL, "Socket short write. (len %d)\n", len);
|
||||
return(-1); // socket error
|
||||
}
|
||||
|
@ -1513,10 +1462,8 @@ int handle_socket(void)
|
|||
free(admin);
|
||||
|
||||
work = 1;
|
||||
} else
|
||||
{
|
||||
if (errno != EWOULDBLOCK)
|
||||
{
|
||||
} else {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1537,8 +1484,7 @@ int open_socket(void)
|
|||
union parameter param;
|
||||
|
||||
/* open socket */
|
||||
if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
CERROR(NULL, NULL, "Failed to create socket.\n");
|
||||
return(lcr_sock);
|
||||
}
|
||||
|
@ -1549,8 +1495,7 @@ int open_socket(void)
|
|||
sprintf(sock_address.sun_path, SOCKET_NAME, options.lock);
|
||||
|
||||
/* connect socket */
|
||||
if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
|
||||
{
|
||||
if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0) {
|
||||
close(lcr_sock);
|
||||
lcr_sock = -1;
|
||||
CDEBUG(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path);
|
||||
|
@ -1558,8 +1503,7 @@ int open_socket(void)
|
|||
}
|
||||
|
||||
/* set non-blocking io */
|
||||
if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0)
|
||||
{
|
||||
if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0) {
|
||||
close(lcr_sock);
|
||||
lcr_sock = -1;
|
||||
CERROR(NULL, NULL, "Failed to set socket into non-blocking IO.\n");
|
||||
|
@ -1776,8 +1720,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
|
|||
CDEBUG(NULL, NULL, "Received request from Asterisk. (data=%s)\n", (char *)data);
|
||||
|
||||
/* if socket is closed */
|
||||
if (lcr_sock < 0)
|
||||
{
|
||||
if (lcr_sock < 0) {
|
||||
CERROR(NULL, NULL, "Rejecting call from Asterisk, because LCR not running.\n");
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return NULL;
|
||||
|
@ -1785,8 +1728,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
|
|||
|
||||
/* create call instance */
|
||||
call = alloc_call();
|
||||
if (!call)
|
||||
{
|
||||
if (!call) {
|
||||
/* failed to create instance */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return NULL;
|
||||
|
@ -1802,8 +1744,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
|
|||
ast = ast_channel_alloc(1);
|
||||
#endif
|
||||
|
||||
if (!ast)
|
||||
{
|
||||
if (!ast) {
|
||||
CERROR(NULL, NULL, "Failed to create Asterisk channel.\n");
|
||||
free_call(call);
|
||||
/* failed to create instance */
|
||||
|
@ -1983,8 +1924,7 @@ static int lcr_digit(struct ast_channel *ast, char digit)
|
|||
CDEBUG(call, ast, "Received digit '%c' from Asterisk.\n", digit);
|
||||
|
||||
/* send information or queue them */
|
||||
if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
|
||||
{
|
||||
if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING) {
|
||||
CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n");
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.information.id[0] = digit;
|
||||
|
@ -1992,8 +1932,7 @@ static int lcr_digit(struct ast_channel *ast, char digit)
|
|||
send_message(MESSAGE_INFORMATION, call->ref, &newparam);
|
||||
} else
|
||||
if (!call->ref
|
||||
&& (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP))
|
||||
{
|
||||
&& (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP)) {
|
||||
CDEBUG(call, ast, "Queue digits, because we are in setup/dialing state and have no ref yet.\n");
|
||||
*buf = digit;
|
||||
strncat(call->dialque, buf, strlen(call->dialque)-1);
|
||||
|
@ -2103,8 +2042,7 @@ static int lcr_hangup(struct ast_channel *ast)
|
|||
/* disconnect asterisk, maybe not required */
|
||||
ast->tech_pvt = NULL;
|
||||
ast->fds[0] = -1;
|
||||
if (call->ref)
|
||||
{
|
||||
if (call->ref) {
|
||||
/* release */
|
||||
CDEBUG(call, ast, "Releasing ref and freeing call instance.\n");
|
||||
if (ast->hangupcause > 0)
|
||||
|
@ -2116,16 +2054,13 @@ static int lcr_hangup(struct ast_channel *ast)
|
|||
if (!pthread_equal(tid, chan_tid))
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* ref is not set, due to prepare setup or release */
|
||||
if (call->state == CHAN_LCR_STATE_RELEASE)
|
||||
{
|
||||
if (call->state == CHAN_LCR_STATE_RELEASE) {
|
||||
/* we get the response to our release */
|
||||
CDEBUG(call, ast, "Freeing call instance, because we have no ref AND we are requesting no ref.\n");
|
||||
free_call(call);
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
/* during prepare, we change to release state */
|
||||
CDEBUG(call, ast, "We must wait until we received our ref, until we can free call instance.\n");
|
||||
call->state = CHAN_LCR_STATE_RELEASE;
|
||||
|
@ -2537,16 +2472,14 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
|
|||
ast_mutex_lock(&chan_lock);
|
||||
call1 = ast1->tech_pvt;
|
||||
call2 = ast2->tech_pvt;
|
||||
if (call1 && call1->bridge_id)
|
||||
{
|
||||
if (call1 && call1->bridge_id) {
|
||||
call1->bridge_id = 0;
|
||||
if (call1->bchannel)
|
||||
bchannel_join(call1->bchannel, 0);
|
||||
if (call1->bridge_call)
|
||||
call1->bridge_call->bridge_call = NULL;
|
||||
}
|
||||
if (call2 && call1->bridge_id)
|
||||
{
|
||||
if (call2 && call1->bridge_id) {
|
||||
call2->bridge_id = 0;
|
||||
if (call2->bchannel)
|
||||
bchannel_join(call2->bchannel, 0);
|
||||
|
@ -2823,8 +2756,7 @@ int load_module(void)
|
|||
#endif
|
||||
|
||||
quit = 0;
|
||||
if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
|
||||
{
|
||||
if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0)) {
|
||||
/* failed to create thread */
|
||||
bchannel_deinitialize();
|
||||
close_socket();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# Enable debugging of OpenBSC library.
|
||||
# Refer to OpenBSC project for debugging options.
|
||||
# By default, debugging is turned off.
|
||||
#debug DRLL:DCC:DNM:DRR:DRSL:DNM:DSMS:DMNCC:DPAG:DMUX
|
||||
#debug DRLL:DCC:DMM:DRR:DRSL:DNM:DSMS:DMNCC:DMNSMS:DPAG:DMUX
|
||||
|
||||
# Two Loopback interfaces for audio transfer between OpenBSC and mISDN.
|
||||
# The first interface must provide B-channelis for each call mobile call.
|
||||
|
@ -50,8 +50,9 @@ allow-all
|
|||
|
||||
# To keep layer 2 connection to BS11 when quitting, use this option.
|
||||
# It is only usefull for developing. TRX will stay on.
|
||||
# Also changes in frequency, mcc, mnc, lac while keeping layer 2 will cause
|
||||
# malefunction of BSC.
|
||||
# Warning: Keeping layer 2 link may prevent emergency calls. (See below)
|
||||
# Layer 2 will only be kept, if lcr was killed manually.
|
||||
#keep-l2
|
||||
|
||||
# You must define a list of your BTS'.
|
||||
|
@ -72,6 +73,7 @@ bts bs11 9 123
|
|||
# emergency facility. If you can't do that, don't touch it!
|
||||
#no-emergency-shutdown
|
||||
|
||||
|
||||
# Write BTS-Link traffic to PCAP file.
|
||||
#pcapfile pcap
|
||||
|
||||
|
||||
|
|
12
dss1.cpp
12
dss1.cpp
|
@ -1064,8 +1064,10 @@ void Pdss1::disconnect_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3
|
|||
dec_ie_display(l3m, (unsigned char *)display, sizeof(display));
|
||||
end_trace();
|
||||
|
||||
if (cause < 0)
|
||||
if (cause < 0) {
|
||||
cause = 16;
|
||||
location = LOCATION_PRIVATE_LOCAL;
|
||||
}
|
||||
|
||||
/* release if remote sends us no tones */
|
||||
if (!p_m_mISDNport->earlyb) {
|
||||
|
@ -1152,8 +1154,10 @@ void Pdss1::release_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
|
|||
dec_ie_display(l3m, (unsigned char *)display, sizeof(display));
|
||||
end_trace();
|
||||
|
||||
if (cause < 0)
|
||||
if (cause < 0) {
|
||||
cause = 16;
|
||||
location = LOCATION_PRIVATE_LOCAL;
|
||||
}
|
||||
|
||||
/* sending release to endpoint */
|
||||
if (location == LOCATION_PRIVATE_LOCAL)
|
||||
|
@ -1203,8 +1207,10 @@ void Pdss1::release_complete_ind(unsigned int cmd, unsigned int pid, struct l3_m
|
|||
if (location == LOCATION_PRIVATE_LOCAL)
|
||||
location = LOCATION_PRIVATE_REMOTE;
|
||||
|
||||
if (cause < 0)
|
||||
if (cause < 0) {
|
||||
cause = 16;
|
||||
location = LOCATION_PRIVATE_LOCAL;
|
||||
}
|
||||
|
||||
/* sending release to endpoint */
|
||||
while(p_epointlist) {
|
||||
|
|
50
gsm.cpp
50
gsm.cpp
|
@ -16,6 +16,7 @@ extern "C" {
|
|||
#include "openbsc/trau_frame.h"
|
||||
#include "openbsc/select.h"
|
||||
#include "openbsc/debug.h"
|
||||
#include "openbsc/e1_input.h"
|
||||
#include "bootstrap.h"
|
||||
#include "gsm_audio.h"
|
||||
|
||||
|
@ -440,6 +441,7 @@ void Pgsm::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mnc
|
|||
SCPY(p_callerinfo.id, mncc->calling_number);
|
||||
else
|
||||
p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
|
||||
SCPY(p_callerinfo.imsi, mncc->imsi);
|
||||
p_callerinfo.screen = INFO_SCREEN_NETWORK;
|
||||
p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
p_callerinfo.isdn_port = p_m_portnum;
|
||||
|
@ -507,7 +509,11 @@ void Pgsm::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mnc
|
|||
|
||||
/* what infos did we got ... */
|
||||
gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
|
||||
add_trace("subscr", "number", "%s", p_callerinfo.id);
|
||||
if (p_callerinfo.id[0])
|
||||
add_trace("calling", "number", "%s", p_callerinfo.id);
|
||||
else
|
||||
SPRINT(p_callerinfo.id, "imsi-%s", p_callerinfo.imsi);
|
||||
add_trace("calling", "imsi", "%s", p_callerinfo.imsi);
|
||||
add_trace("dialing", "number", "%s", p_dialinginfo.id);
|
||||
end_trace();
|
||||
|
||||
|
@ -656,13 +662,26 @@ void Pgsm::setup_cnf(unsigned int msg_type, unsigned int callref, struct gsm_mnc
|
|||
gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
|
||||
end_trace();
|
||||
|
||||
SCPY(p_connectinfo.id, mncc->calling_number);
|
||||
SCPY(p_connectinfo.imsi, mncc->imsi);
|
||||
p_connectinfo.present = INFO_PRESENT_ALLOWED;
|
||||
p_connectinfo.screen = INFO_SCREEN_NETWORK;
|
||||
p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
p_connectinfo.isdn_port = p_m_portnum;
|
||||
SCPY(p_connectinfo.interface, p_m_mISDNport->ifport->interface->name);
|
||||
/* send resp */
|
||||
gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_COMPL_REQ, DIRECTION_OUT);
|
||||
if (p_connectinfo.id[0])
|
||||
add_trace("connect", "number", "%s", p_connectinfo.id);
|
||||
else
|
||||
SPRINT(p_connectinfo.id, "imsi-%s", p_connectinfo.imsi);
|
||||
add_trace("connect", "imsi", "%s", p_connectinfo.imsi);
|
||||
resp = create_mncc(MNCC_SETUP_COMPL_REQ, p_m_g_callref);
|
||||
end_trace();
|
||||
send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
|
||||
|
||||
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
|
||||
memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
|
||||
message_put(message);
|
||||
|
||||
new_state(PORT_STATE_CONNECT);
|
||||
|
@ -1102,8 +1121,13 @@ void Pgsm::message_setup(unsigned int epoint_id, int message_id, union parameter
|
|||
}
|
||||
/* dialing information */
|
||||
mncc->called = 1;
|
||||
SCPY(mncc->called_number, p_dialinginfo.id);
|
||||
add_trace("dialing", "number", "%s", mncc->called_number);
|
||||
if (!strncmp(p_dialinginfo.id, "imsi-", 5)) {
|
||||
SCPY(mncc->imsi, p_dialinginfo.id+5);
|
||||
add_trace("dialing", "imsi", "%s", mncc->imsi);
|
||||
} else {
|
||||
SCPY(mncc->called_number, p_dialinginfo.id);
|
||||
add_trace("dialing", "number", "%s", mncc->called_number);
|
||||
}
|
||||
|
||||
/* sending user-user */
|
||||
|
||||
|
@ -1595,7 +1619,9 @@ int gsm_exit(int rc)
|
|||
|
||||
int gsm_init(void)
|
||||
{
|
||||
char hlr[128];
|
||||
char hlr[128], filename[128];
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
int pcapfd;
|
||||
|
||||
/* create gsm instance */
|
||||
gsm = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
|
||||
|
@ -1621,17 +1647,33 @@ int gsm_init(void)
|
|||
PERROR("Expecting exactly one BTS. You defined %d.\n", gsm->conf.numbts);
|
||||
return gsm_exit(-1);
|
||||
}
|
||||
|
||||
/* bootstrap network */
|
||||
gsm->network = bootstrap_network(&message_bcs, gsm->conf.bts[0].type, gsm->conf.mcc, gsm->conf.mnc, gsm->conf.lac, gsm->conf.bts[0].frequency[0], gsm->conf.bts[0].card, !gsm->conf.keep_l2, gsm->conf.short_name, gsm->conf.long_name, hlr, gsm->conf.allow_all);
|
||||
if (!gsm->network) {
|
||||
PERROR("Failed to bootstrap GSM network.\n");
|
||||
return gsm_exit(-1);
|
||||
}
|
||||
|
||||
/* open gsm loop interface */
|
||||
if (gsm_sock_open(gsm->conf.interface_bsc)) {
|
||||
return gsm_exit(-1);
|
||||
}
|
||||
|
||||
/* open pcap file */
|
||||
if (gsm->conf.pcapfile[0]) {
|
||||
if (gsm->conf.pcapfile[0] == '/')
|
||||
SCPY(filename, gsm->conf.pcapfile);
|
||||
else
|
||||
SPRINT(filename, "%s/%s", CONFIG_DATA, gsm->conf.pcapfile);
|
||||
pcapfd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, mode);
|
||||
if (pcapfd < 0) {
|
||||
PERROR("Failed to open file for pcap\n");
|
||||
return gsm_exit(-1);
|
||||
}
|
||||
e1_set_pcap_fd(pcapfd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
1
gsm.h
1
gsm.h
|
@ -21,6 +21,7 @@ struct gsm_conf {
|
|||
int numbts; /* number of BTS' */
|
||||
struct bts_conf bts[8]; /* configure BTS' */
|
||||
int noemergshut; /* don't shut down on emergency */
|
||||
char pcapfile[128]; /* open capture file for BS11 links */
|
||||
};
|
||||
|
||||
struct lcr_gsm {
|
||||
|
|
127
gsm_conf.c
127
gsm_conf.c
|
@ -48,22 +48,19 @@ int gsm_conf(struct gsm_conf *gsm_conf)
|
|||
|
||||
SPRINT(filename, "%s/gsm.conf", CONFIG_DATA);
|
||||
|
||||
if (!(fp=fopen(filename,"r")))
|
||||
{
|
||||
if (!(fp=fopen(filename,"r"))) {
|
||||
SPRINT(gsm_conf_error, "Cannot open %s\n",filename);
|
||||
return(0);
|
||||
}
|
||||
|
||||
line=0;
|
||||
while((fgets(buffer,sizeof(buffer),fp)))
|
||||
{
|
||||
while((fgets(buffer,sizeof(buffer),fp))) {
|
||||
line++;
|
||||
buffer[sizeof(buffer)-1]=0;
|
||||
if (buffer[0]) buffer[strlen(buffer)-1]=0;
|
||||
p=buffer;
|
||||
|
||||
while(*p <= 32) /* skip spaces */
|
||||
{
|
||||
while(*p <= 32) { /* skip spaces */
|
||||
if (*p == 0)
|
||||
break;
|
||||
p++;
|
||||
|
@ -73,10 +70,8 @@ int gsm_conf(struct gsm_conf *gsm_conf)
|
|||
|
||||
option[0]=0;
|
||||
i=0; /* read option */
|
||||
while(*p > 32)
|
||||
{
|
||||
if (i+1 >= sizeof(option))
|
||||
{
|
||||
while(*p > 32) {
|
||||
if (i+1 >= sizeof(option)) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): option too long.\n",filename,line);
|
||||
goto error;
|
||||
}
|
||||
|
@ -84,8 +79,7 @@ int gsm_conf(struct gsm_conf *gsm_conf)
|
|||
option[i++] = *p++;
|
||||
}
|
||||
|
||||
while(*p <= 32) /* skip spaces */
|
||||
{
|
||||
while(*p <= 32) { /* skip spaces */
|
||||
if (*p == 0)
|
||||
break;
|
||||
p++;
|
||||
|
@ -93,21 +87,17 @@ int gsm_conf(struct gsm_conf *gsm_conf)
|
|||
|
||||
params[0][0] = 0;
|
||||
pnum = 0;
|
||||
while(*p!=0 && *p!='#' && pnum < 10) /* param */
|
||||
{
|
||||
while(*p!=0 && *p!='#' && pnum < 10) { /* param */
|
||||
i=0; /* read param */
|
||||
while(*p > 32)
|
||||
{
|
||||
if (i+1 >= sizeof(params[pnum]))
|
||||
{
|
||||
while(*p > 32) {
|
||||
if (i+1 >= sizeof(params[pnum])) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): param too long.\n",filename,line);
|
||||
goto error;
|
||||
}
|
||||
params[pnum][i+1] = '\0';
|
||||
params[pnum][i++] = *p++;
|
||||
}
|
||||
while(*p <= 32) /* skip spaces */
|
||||
{
|
||||
while(*p <= 32) { /* skip spaces */
|
||||
if (*p == 0)
|
||||
break;
|
||||
p++;
|
||||
|
@ -119,133 +109,113 @@ int gsm_conf(struct gsm_conf *gsm_conf)
|
|||
/* at this point we have option and param */
|
||||
|
||||
/* check option */
|
||||
if (!strcmp(option,"debug"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"debug")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line,option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->debug, params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"interface-bsc"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"interface-bsc")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->interface_bsc, params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"interface-lcr"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"interface-lcr")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->interface_lcr, params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"short-name"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"short-name")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->short_name, params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"long-name"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"long-name")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->long_name, params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"mcc"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"mcc")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
gsm_conf->mcc = atoi(params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"mnc"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"mnc")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
gsm_conf->mnc = atoi(params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"lac"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"lac")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
gsm_conf->lac = atoi(params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"hlr"))
|
||||
{
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (!strcmp(option,"hlr")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->hlr, params[0]);
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"allow-all"))
|
||||
{
|
||||
if (!strcmp(option,"allow-all")) {
|
||||
gsm_conf->allow_all = 1;
|
||||
} else
|
||||
if (!strcmp(option,"keep-l2"))
|
||||
{
|
||||
if (!strcmp(option,"keep-l2")) {
|
||||
gsm_conf->keep_l2 = 1;
|
||||
|
||||
} else
|
||||
if (!strcmp(option,"no-mergency-shutdown"))
|
||||
{
|
||||
if (!strcmp(option,"no-mergency-shutdown")) {
|
||||
gsm_conf->noemergshut = 1;
|
||||
} else
|
||||
if (!strcmp(option,"bts"))
|
||||
{
|
||||
if (gsm_conf->numbts == 8)
|
||||
{
|
||||
if (!strcmp(option,"pcapfile")) {
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
|
||||
goto error;
|
||||
}
|
||||
SCPY(gsm_conf->pcapfile, params[0]);
|
||||
} else
|
||||
if (!strcmp(option,"bts")) {
|
||||
if (gsm_conf->numbts == 8) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): too many BTS defined.\n",filename,line);
|
||||
goto error;
|
||||
}
|
||||
if (params[0][0]==0)
|
||||
{
|
||||
if (params[0][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter <bts-type> for option %s missing.\n",filename,line,option);
|
||||
goto error;
|
||||
}
|
||||
if (params[1][0]==0)
|
||||
{
|
||||
if (params[1][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter <card number> for option %s missing.\n",filename,line,option);
|
||||
goto error;
|
||||
}
|
||||
if (params[2][0]==0)
|
||||
{
|
||||
if (params[2][0]==0) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): parameter <frequency> for option %s missing.\n",filename,line,option);
|
||||
goto error;
|
||||
}
|
||||
if (!strcmp(params[0], "bs11"))
|
||||
{
|
||||
if (!strcmp(params[0], "bs11")) {
|
||||
gsm_conf->bts[gsm_conf->numbts].type = GSM_BTS_TYPE_BS11;
|
||||
} else {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): unknown BTS type '%s'.\n",filename,line,params[0]);
|
||||
|
@ -253,18 +223,15 @@ int gsm_conf(struct gsm_conf *gsm_conf)
|
|||
}
|
||||
gsm_conf->bts[gsm_conf->numbts].card = atoi(params[1]);
|
||||
gsm_conf->bts[gsm_conf->numbts].numtrx = 0;
|
||||
while (params[gsm_conf->bts[gsm_conf->numbts].numtrx+2][0])
|
||||
{
|
||||
if (gsm_conf->bts[gsm_conf->numbts].numtrx == 8)
|
||||
{
|
||||
while (params[gsm_conf->bts[gsm_conf->numbts].numtrx+2][0]) {
|
||||
if (gsm_conf->bts[gsm_conf->numbts].numtrx == 8) {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): too many frequencies defined.\n",filename,line);
|
||||
goto error;
|
||||
}
|
||||
gsm_conf->bts[gsm_conf->numbts].frequency[gsm_conf->bts[gsm_conf->numbts].numtrx++] = atoi(params[gsm_conf->bts[gsm_conf->numbts].numtrx+2]);
|
||||
}
|
||||
gsm_conf->numbts++;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
SPRINT(gsm_conf_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option);
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -165,6 +165,7 @@ struct caller_info {
|
|||
int ntype2; /* second type of number */
|
||||
int present2; /* second presentation */
|
||||
int screen2; /* second who provided the number */
|
||||
char imsi[16]; /* IMSI for gsm originated calls */
|
||||
};
|
||||
|
||||
/* call-info structure DIALING */
|
||||
|
@ -189,6 +190,7 @@ struct connect_info {
|
|||
int present; /* presentation */
|
||||
int screen; /* who provided the number */
|
||||
char display[84]; /* display information */
|
||||
char imsi[16]; /* IMSI for gsm terminated calls */
|
||||
};
|
||||
|
||||
/* call-info structure DISCONNECT */
|
||||
|
|
Loading…
Reference in New Issue