#ifdef __cplusplus
extern "C" {
#endif
-#include <openbsc/openbsc.h>
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/db.h>
}
/*
- * Inform anyone...
- */
-static void bsc_hack_channel_allocated(struct gsm_lchan *lchan) {
-}
-
-/*
* Patch the various SYSTEM INFORMATION tables to update
* the LAI
*/
}
}
-void *bootstrap_network(int (*mncc_recv)(void *, int, void *),int bts_type, int mcc, int mnc, int lac, int arfcn, int cardnr, int release_l2, char *name_short, char *name_long, char *hlr, int allow_all)
+static int bootstrap_bts(struct gsm_bts *bts, int lac, int arfcn)
+{
+ bts->location_area_code = lac;
+ bts->trx[0].arfcn = arfcn;
+
+ /* Control Channel Description */
+ memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
+ bts->chan_desc.att = 1;
+ bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
+ bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
+ bts->chan_desc.t3212 = 0;
+
+ patch_tables(bts);
+
+ paging_init(bts);
+
+ return 0;
+}
+
+
+struct gsm_network *bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *), int bts_type, int mcc, int mnc, int lac, int arfcn, int cardnr, int release_l2, char *name_short, char *name_long, char *hlr, int allow_all)
{
struct gsm_bts *bts;
struct gsm_network *gsmnet;
+ /* seed the PRNG for TMSI */
+ srand(time(NULL));
+
+ /* initialize our data structures */
+ gsmnet = gsm_network_init(2, (gsm_bts_type)bts_type, mcc, mnc, mncc_recv);
+ if (!gsmnet)
+ return 0;
+
/* open database */
- if (db_init(hlr)) {
+ if (db_init(hlr, gsmnet)) {
fprintf(stderr, "DB: Failed to init HLR database '%s'. Please check the option settings.\n", hlr);
return NULL;
}
return NULL;
}
- /* seed the PRNG for TMSI */
- srand(time(NULL));
-
- /* initialize our data structures */
- gsmnet = gsm_network_init(1, (gsm_bts_type)bts_type, mcc, mnc, mncc_recv);
- if (!gsmnet)
- return 0;
-
gsmnet->name_long = name_long;
gsmnet->name_short = name_short;
bts = &gsmnet->bts[0];
- bts->location_area_code = lac;
- bts->trx[0].arfcn = arfcn;
+ bootstrap_bts(bts, lac, arfcn);
/* Control Channel Description */
memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
patch_tables(bts);
paging_init(bts);
- bts->paging.channel_allocated = bsc_hack_channel_allocated;
telnet_init(gsmnet, 4242);
/* E1 mISDN input setup */
if (bts_type == GSM_BTS_TYPE_BS11) {
+ gsmnet->num_bts = 1;
if (e1_config(bts, cardnr, release_l2))
return NULL;
} else {
- if (ia_config(bts))
+ bts->ip_access.site_id = 1801;
+ bts->ip_access.bts_id = 0;
+ bts = &gsmnet->bts[1];
+ bootstrap_bts(bts, lac, arfcn);
+ bts->ip_access.site_id = 1800;
+ bts->ip_access.bts_id = 0;
+ if (ipaccess_setup(gsmnet))
return NULL;
+
}
if (allow_all)
return gsmnet;
}
-int shutdown_net(void *network)
+int shutdown_net(struct gsm_network *network)
{
struct gsm_network *net = (struct gsm_network *)network;
unsigned int i;
#include "main.h"
extern "C" {
-#include "openbsc/openbsc.h"
+#include "openbsc/gsm_data.h"
#include "openbsc/mncc.h"
#include "openbsc/trau_frame.h"
+#include "openbsc/select.h"
+#include "openbsc/debug.h"
#include "bootstrap.h"
#include "gsm_audio.h"
mncc->callref = callref;
return (mncc);
}
-static int send_and_free_mncc(void *net, unsigned int msg_type, void *data)
+static int send_and_free_mncc(struct gsm_network *net, unsigned int msg_type, void *data)
{
int ret;
frame->msg_type = GSM_TRAU_FRAME;
frame->callref = p_m_g_callref;
memcpy(frame->data, tf, sizeof(struct decoded_trau_frame));
- mncc_send(gsm->network, frame->msg_type, frame);
+ mncc_send((struct gsm_network *)gsm->network, frame->msg_type, frame);
}
add_trace("cause", "value", "%d", mncc->cause_value);
add_trace("reason", NULL, "callref already in use");
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_RELEASE);
p_m_delete = 1;
return;
add_trace("cause", "value", "%d", mncc->cause_value);
add_trace("reason", NULL, "port is blocked");
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_RELEASE);
p_m_delete = 1;
return;
add_trace("cause", "value", "%d", mncc->cause_value);
add_trace("reason", NULL, "no channel");
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_RELEASE);
p_m_delete = 1;
return;
mode->lchan_mode = 0x01; /* GSM V1 */
add_trace("mode", NULL, "0x%02x", mode->lchan_mode);
end_trace();
- send_and_free_mncc(gsm->network, mode->msg_type, mode);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mode->msg_type, mode);
/* send call proceeding */
gsm_trace_header(p_m_mISDNport, this, MNCC_CALL_PROC_REQ, DIRECTION_OUT);
add_trace("progress", "descr", "%d", proceeding->progress_descr);
}
end_trace();
- send_and_free_mncc(gsm->network, proceeding->msg_type, proceeding);
+ send_and_free_mncc((struct gsm_network *)gsm->network, proceeding->msg_type, proceeding);
new_state(PORT_STATE_IN_PROCEEDING);
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
end_trace();
frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc(gsm->network, frame->msg_type, frame);
+ send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
p_m_g_tch_connected = 1;
}
end_trace();
resp = create_mncc(MNCC_START_DTMF_RSP, p_m_g_callref);
resp->keypad = mncc->keypad;
- send_and_free_mncc(gsm->network, resp->msg_type, resp);
+ send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
/* send dialing information */
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
end_trace();
resp = create_mncc(MNCC_STOP_DTMF_RSP, p_m_g_callref);
resp->keypad = mncc->keypad;
- send_and_free_mncc(gsm->network, resp->msg_type, resp);
+ send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
}
/* PROCEEDING INDICATION */
mode->lchan_mode = 0x01; /* GSM V1 */
add_trace("mode", NULL, "0x%02x", mode->lchan_mode);
end_trace();
- send_and_free_mncc(gsm->network, mode->msg_type, mode);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mode->msg_type, mode);
}
gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_COMPL_REQ, DIRECTION_OUT);
resp = create_mncc(MNCC_SETUP_COMPL_REQ, p_m_g_callref);
end_trace();
- send_and_free_mncc(gsm->network, resp->msg_type, resp);
+ 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);
message_put(message);
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
end_trace();
frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc(gsm->network, frame->msg_type, frame);
+ send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
p_m_g_tch_connected = 1;
}
}
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
end_trace();
frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc(gsm->network, frame->msg_type, frame);
+ send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
p_m_g_tch_connected = 1;
}
}
add_trace("cause", "value", "%d", resp->cause_value);
#endif
end_trace();
- send_and_free_mncc(gsm->network, resp->msg_type, resp);
+ send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
/* sending release to endpoint */
while(p_epointlist) {
gsm_trace_header(p_m_mISDNport, this, MNCC_HOLD_CNF, DIRECTION_OUT);
end_trace();
resp = create_mncc(MNCC_HOLD_CNF, p_m_g_callref);
- send_and_free_mncc(gsm->network, resp->msg_type, resp);
+ send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
/* disable audio */
if (p_m_g_tch_connected) { /* it should be true */
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_DROP, DIRECTION_OUT);
end_trace();
frame = create_mncc(MNCC_FRAME_DROP, p_m_g_callref);
- send_and_free_mncc(gsm->network, frame->msg_type, frame);
+ send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
p_m_g_tch_connected = 0;
}
}
gsm_trace_header(p_m_mISDNport, this, MNCC_RETRIEVE_CNF, DIRECTION_OUT);
end_trace();
resp = create_mncc(MNCC_RETRIEVE_CNF, p_m_g_callref);
- send_and_free_mncc(gsm->network, resp->msg_type, resp);
+ send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
/* enable audio */
if (!p_m_g_tch_connected) { /* it should be true */
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
end_trace();
frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc(gsm->network, frame->msg_type, frame);
+ send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
p_m_g_tch_connected = 1;
}
}
/*
* BSC sends message to port
*/
-static int message_bcs(void *net, int msg_type, void *arg)
+static int message_bcs(struct gsm_network *net, int msg_type, void *arg)
{
struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
unsigned int callref = mncc->callref;
add_trace("cause", "location", "%d", rej->cause_location);
add_trace("cause", "value", "%d", rej->cause_value);
end_trace();
- send_and_free_mncc(gsm->network, rej->msg_type, rej);
+ send_and_free_mncc((struct gsm_network *)gsm->network, rej->msg_type, rej);
return 0;
}
/* creating port object, transparent until setup with hdlc */
//todo
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_OUT_SETUP);
end_trace();
mncc = create_mncc(MNCC_NOTIFY_REQ, p_m_g_callref);
mncc->notify = notify;
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
}
}
}
add_trace("progress", "descr", "%d", mncc->progress_descr);
}
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_IN_ALERTING);
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
end_trace();
mncc = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
p_m_g_tch_connected = 1;
}
}
add_trace("connected", "number", "%s", mncc->connected_number);
}
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_CONNECT_WAITING);
}
add_trace("cause", "location", "%d", mncc->cause_location);
add_trace("cause", "value", "%d", mncc->cause_value);
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_OUT_DISCONNECT);
gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
end_trace();
mncc = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
p_m_g_tch_connected = 1;
}
}
add_trace("cause", "location", "%d", mncc->cause_location);
add_trace("cause", "value", "%d", mncc->cause_value);
end_trace();
- send_and_free_mncc(gsm->network, mncc->msg_type, mncc);
+ send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
new_state(PORT_STATE_RELEASE);
p_m_delete = 1;
{
int ret1, ret2;
- ret1 = bsc_upqueue(gsm->network);
+ ret1 = bsc_upqueue((struct gsm_network *)gsm->network);
ret2 = bsc_select_main(1); /* polling */
if (ret1 || ret2)
return 1;
gsm_sock_close();
/* shutdown network */
if (gsm->network)
- shutdown_net(gsm->network);
+ shutdown_net((struct gsm_network *)gsm->network);
/* free network */
if (gsm->network) {
- free(gsm->network); /* TBD */
+ free((struct gsm_network *)gsm->network); /* TBD */
}
free(gsm);
gsm = NULL;