Merge branch 'master' of git.osmocom.org:openbsc

This commit is contained in:
Harald Welte 2011-07-29 11:44:28 +02:00
commit 901d57db07
38 changed files with 281 additions and 117 deletions

View File

@ -31,8 +31,8 @@ struct gsm_subscriber;
/* one time initialisation */
int db_init(const char *name);
int db_prepare();
int db_fini();
int db_prepare(void);
int db_fini(void);
/* subscriber management */
struct gsm_subscriber *db_create_subscriber(struct gsm_network *net,

View File

@ -35,6 +35,7 @@ enum {
DLLC,
DSNDCP,
DNAT,
DCTRL,
Debug_LastEntry,
};

View File

@ -78,7 +78,7 @@ struct sgsn_mm_ctx {
/* CKSN */
enum gprs_ciph_algo ciph_algo;
struct {
uint8_t buf[14]; /* 10.5.5.12a */
uint8_t buf[52]; /* 10.5.5.12a */
uint8_t len;
} ms_radio_access_capa;
struct {

View File

@ -1,10 +1,11 @@
#ifndef _GSM_04_08_H
#define _GSM_04_08_H
#include <openbsc/meas_rep.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <openbsc/meas_rep.h>
struct msgb;
struct gsm_bts;
@ -31,7 +32,8 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id);
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, uint8_t ra);
enum gsm_chreq_reason_t get_reason_by_chreq(uint8_t ra, int neci);
/* don't use "enum gsm_chreq_reason_t" to avoid circular dependency */
int get_reason_by_chreq(uint8_t ra, int neci);
void gsm_net_update_ctype(struct gsm_network *net);
int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);

View File

@ -82,7 +82,7 @@ struct mgcp_trunk_config;
typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
typedef int (*mgcp_reset)(struct mgcp_config *cfg);
typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg);
#define PORT_ALLOC_STATIC 0
#define PORT_ALLOC_DYNAMIC 1

View File

@ -65,7 +65,7 @@ struct osmo_msc_data {
char *mid_call_txt;
int mid_call_timeout;
char *rf_ctrl_name;
struct osmo_bsc_rf *rf_ctl;
struct osmo_bsc_rf *rf_ctrl;
/* ussd welcome text */
char *ussd_welcome_txt;

View File

@ -68,4 +68,6 @@ void paging_update_buffer_space(struct gsm_bts *bts, uint16_t);
/* pending paging requests */
unsigned int paging_pending_requests_nr(struct gsm_bts *bts);
void *paging_get_data(struct gsm_bts *bts, struct gsm_subscriber *subscr);
#endif

View File

@ -36,7 +36,6 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/process.h>
#include <openbsc/signal.h>
#include <openbsc/debug.h>

View File

@ -675,8 +675,9 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
/* MS Radio Access Capability 10.5.5.12a */
ms_ra_acc_cap_len = *cur++;
ms_ra_acc_cap = cur;
if (ms_ra_acc_cap_len > 51)
if (ms_ra_acc_cap_len > 52)
goto err_inval;
cur += ms_ra_acc_cap_len;
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
@ -735,8 +736,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
ctx->cell_id = cid;
/* Update MM Context with other data */
ctx->drx_parms = drx_par;
ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len;
memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap, ms_ra_acc_cap_len);
ctx->ms_radio_access_capa.len = OSMO_MIN(ms_ra_acc_cap_len,
sizeof((ctx->ms_radio_access_capa.buf)));
memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap,
ctx->ms_radio_access_capa.len);
ctx->ms_network_capa.len = msnc_len;
memcpy(ctx->ms_network_capa.buf, msnc, msnc_len);
@ -754,7 +757,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
GPRS_ALGO_GEA0, NULL);
DEBUGPC(DMM, "\n");
return ctx ? gsm48_gmm_authorize(ctx, GMM_T3350_MODE_ATT) : 0;
return gsm48_gmm_authorize(ctx, GMM_T3350_MODE_ATT);
err_inval:
DEBUGPC(DMM, "\n");
@ -910,6 +913,9 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
/* MS Radio Access Capability 10.5.5.12a */
ms_ra_acc_cap_len = *cur++;
ms_ra_acc_cap = cur;
if (ms_ra_acc_cap_len > 52)
return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_PROTO_ERR_UNSPEC);
cur += ms_ra_acc_cap_len;
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status,
* DRX parameter, MS network capability */

View File

@ -696,7 +696,7 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
struct gprs_llc_llme *llme;
/* FIXME: don't use the TLLI but the 0xFFFF unassigned? */
llme = llme_alloc(msgb_tlli(msg));
LOGP(DLLC, LOGL_DEBUG, "LLC RX: unknown TLLI 0x08x, "
LOGP(DLLC, LOGL_DEBUG, "LLC RX: unknown TLLI 0x%08x, "
"creating LLME on the fly\n", msgb_tlli(msg));
lle = &llme->lle[llhp.sapi];
} else {

View File

@ -500,8 +500,6 @@ int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi,
rate_ctr_add(&mmctx->ctrg->ctr[GMM_CTR_BYTES_UDATA_IN], npdu_len);
return gtp_data_req(pdp->ggsn->gsn, pdp->lib, npdu, npdu_len);
return gtp_data_req(pdp->ggsn->gsn, pdp->lib, npdu, npdu_len);
}
/* libgtp select loop integration */

View File

@ -281,5 +281,6 @@ int main(int argc, char **argv)
exit(3);
}
/* not reached */
exit(0);
}

View File

@ -59,9 +59,9 @@ int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned int
}
if (memcmp(firmware_header->more_magic, more_magic, 2) != 0) {
fprintf(stderr, "Wrong more magic. Got: 0x%x %x %x %x\n",
fprintf(stderr, "Wrong more magic. Got: 0x%x 0x%x vs. 0x%x 0x%x\n",
firmware_header->more_magic[0] & 0xff, firmware_header->more_magic[1] & 0xff,
firmware_header->more_magic[2] & 0xff, firmware_header->more_magic[3] & 0xff);
more_magic[0], more_magic[1]);
return -1;
}

View File

@ -103,7 +103,7 @@ struct ipa_bts_conn {
uint16_t gprs_orig_port;
uint32_t gprs_orig_ip;
char *id_tags[0xff];
char *id_tags[256];
uint8_t *id_resp;
unsigned int id_resp_len;
};
@ -488,7 +488,7 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,
return 0;
}
if (trx_id > MAX_TRX) {
if (trx_id >= MAX_TRX) {
LOGP(DINP, LOGL_ERROR, "We don't support more "
"than %u TRX\n", MAX_TRX);
return -EINVAL;
@ -1076,7 +1076,7 @@ static void signal_handler(int signal)
}
}
static void print_help()
static void print_help(void)
{
printf(" ipaccess-proxy is a proxy BTS.\n");
printf(" -h --help. This help text.\n");
@ -1090,7 +1090,7 @@ static void print_help()
printf(" -V --version. Print the version of OpenBSC.\n");
}
static void print_usage()
static void print_usage(void)
{
printf("Usage: ipaccess-proxy [options]\n");
}

View File

@ -776,7 +776,7 @@ static int sw_load_segment(struct abis_nm_sw *sw)
char seg_buf[256];
char *line_buf = seg_buf+2;
unsigned char *tlv;
uint8_t len;
int len;
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);

View File

@ -427,7 +427,7 @@ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
*/
msgb_v_put(msg, RSL_IE_CHAN_IDENT);
len = msgb_put(msg, 1);
msgb_tlv_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
msgb_tv_fixed_put(msg, GSM48_IE_CHANDESC_2, sizeof(cd), (const uint8_t *) &cd);
if (lchan->ts->hopping.enabled)
msgb_tlv_put(msg, GSM48_IE_MA_AFTER, lchan->ts->hopping.ma_len,

View File

@ -406,6 +406,9 @@ static int bootstrap_bts(struct gsm_bts *bts)
bts->si_common.ncc_permitted = 0xff;
/* Initialize the BTS state */
gsm_bts_mo_reset(bts);
return 0;
}

View File

@ -189,9 +189,9 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
dump_pchan_load_vty(vty, " ", &pl);
/* show rf */
if (net->msc_data && net->msc_data->rf_ctl)
if (net->msc_data && net->msc_data->rf_ctrl)
vty_out(vty, " Last RF Command: %s%s",
net->msc_data->rf_ctl->last_state_command,
net->msc_data->rf_ctrl->last_state_command,
VTY_NEWLINE);
}
@ -1055,11 +1055,14 @@ DEFUN(show_e1ts,
}
if (argc >= 1) {
int num = atoi(argv[0]);
llist_for_each_entry(line, &e1inp_line_list, list) {
if (line->num == num)
struct e1inp_line *l;
llist_for_each_entry(l, &e1inp_line_list, list) {
if (l->num == num) {
line = l;
break;
}
}
if (!line || line->num != num) {
if (!line) {
vty_out(vty, "E1 line %s is invalid%s",
argv[0], VTY_NEWLINE);
return CMD_WARNING;
@ -1067,7 +1070,7 @@ DEFUN(show_e1ts,
}
if (argc >= 2) {
ts_nr = atoi(argv[1]);
if (ts_nr > NUM_E1_TS) {
if (ts_nr >= NUM_E1_TS) {
vty_out(vty, "E1 timeslot %s is invalid%s",
argv[1], VTY_NEWLINE);
return CMD_WARNING;
@ -1157,7 +1160,7 @@ DEFUN(cfg_net_ncc,
DEFUN(cfg_net_mnc,
cfg_net_mnc_cmd,
"mobile network code <1-999>",
"mobile network code <0-999>",
"Set the GSM mobile network code")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);

View File

@ -190,7 +190,7 @@ enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra)
return GSM_LCHAN_SDCCH;
}
enum gsm_chreq_reason_t get_reason_by_chreq(uint8_t ra, int neci)
int get_reason_by_chreq(uint8_t ra, int neci)
{
int i;
int length;

View File

@ -405,3 +405,17 @@ unsigned int paging_pending_requests_nr(struct gsm_bts *bts)
return requests;
}
/**
* Find any paging data for the given subscriber at the given BTS.
*/
void *paging_get_data(struct gsm_bts *bts, struct gsm_subscriber *subscr)
{
struct gsm_paging_request *req;
llist_for_each_entry(req, &bts->paging.pending_requests, entry)
if (req->subscr == subscr)
return req->cbfn_param;
return NULL;
}

View File

@ -175,6 +175,11 @@ static const struct log_info_cat default_categories[] = {
.description = "GSM 08.08 NAT/Multipkexer",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DCTRL] = {
.name = "DCTRL",
.description = "Control interface",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
};
enum log_filter {

View File

@ -36,7 +36,6 @@
void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
{
mo->nm_state.administrative = NM_STATE_NULL;
mo->nm_state.operational = NM_OPSTATE_NULL;
mo->nm_state.availability = NM_AVSTATE_POWER_OFF;
}

View File

@ -22,6 +22,7 @@
*/
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -365,7 +366,7 @@ static char *get_all_rate_ctr_in_group(const struct rate_ctr_group *ctrg, int in
return NULL;
for (i=0;i<ctrg->desc->num_ctr;i++) {
counters = talloc_asprintf_append(counters, "\n%s.%u.%s %lu",
counters = talloc_asprintf_append(counters, "\n%s.%u.%s %"PRIu64,
ctrg->desc->group_name_prefix, ctrg->idx,
ctrg->desc->ctr_desc[i].name,
get_rate_ctr_value(&ctrg->ctr[i], intv));

View File

@ -111,9 +111,8 @@ int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg)
uint16_t _bvci = htons(*bvci);
msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
}
if (orig_msg)
msgb_tvlv_put(msg, BSSGP_IE_PDU_IN_ERROR,
msgb_bssgp_len(orig_msg), msgb_bssgph(orig_msg));
msgb_tvlv_put(msg, BSSGP_IE_PDU_IN_ERROR,
msgb_bssgp_len(orig_msg), msgb_bssgph(orig_msg));
return gprs_ns_sendmsg(bssgp_nsi, msg);
}

View File

@ -831,8 +831,20 @@ out_silent:
static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg)
{
struct mgcp_msg_ptr data_ptrs[6];
const char *trans_id;
struct mgcp_endpoint *endp;
int found;
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs),
&trans_id, &endp);
if (found != 0) {
LOGP(DMGCP, LOGL_ERROR, "Failed to find the endpoint.\n");
return NULL;
}
if (cfg->reset_cb)
cfg->reset_cb(cfg);
cfg->reset_cb(endp->tcfg);
return NULL;
}

View File

@ -221,7 +221,7 @@ out_err:
}
int db_prepare()
int db_prepare(void)
{
dbi_result result;
int i;
@ -245,15 +245,13 @@ int db_prepare()
return 0;
}
int db_fini()
int db_fini(void)
{
dbi_conn_close(conn);
dbi_shutdown();
if (db_dirname)
free(db_dirname);
if (db_basename)
free(db_basename);
free(db_dirname);
free(db_basename);
return 0;
}
@ -276,9 +274,9 @@ struct gsm_subscriber *db_create_subscriber(struct gsm_network *net, char *imsi)
}
subscr = subscr_alloc();
subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
if (!subscr)
return NULL;
subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
result = dbi_conn_queryf(conn,
"INSERT INTO Subscriber "
"(imsi, created, updated) "

View File

@ -554,7 +554,8 @@ static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m
{
uint8_t *smsp = msgb_sms(msg);
struct gsm_sms *gsms;
uint8_t sms_mti, sms_mms, sms_vpf, sms_alphabet, sms_rp;
unsigned int sms_alphabet;
uint8_t sms_mti, sms_mms, sms_vpf, sms_rp;
uint8_t *sms_vp;
uint8_t da_len_bytes;
uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */

View File

@ -51,6 +51,8 @@ struct gsm_sms_pending {
unsigned long long sms_id;
int failed_attempts;
int resend;
int no_detach;
};
struct gsm_sms_queue {
@ -86,17 +88,24 @@ static int sms_is_in_pending(struct gsm_sms_queue *smsq, struct gsm_sms *sms)
return sms_find_pending(smsq, sms) != NULL;
}
static int sms_subscriber_is_pending(struct gsm_sms_queue *smsq,
struct gsm_subscriber *subscr)
static struct gsm_sms_pending *sms_subscriber_find_pending(
struct gsm_sms_queue *smsq,
struct gsm_subscriber *subscr)
{
struct gsm_sms_pending *pending;
llist_for_each_entry(pending, &smsq->pending_sms, entry) {
if (pending->subscr == subscr)
return 1;
return pending;
}
return 0;
return NULL;
}
static int sms_subscriber_is_pending(struct gsm_sms_queue *smsq,
struct gsm_subscriber *subscr)
{
return sms_subscriber_find_pending(smsq, subscr) != NULL;
}
static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq,
@ -146,7 +155,7 @@ static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error
if (++pending->failed_attempts < smsq->max_fail)
return sms_pending_resend(pending);
if (paging_error) {
if (paging_error && !pending->no_detach) {
LOGP(DSMS, LOGL_NOTICE,
"Subscriber %llu is not reachable. Setting LAC=0.\n", pending->subscr->id);
pending->subscr->lac = GSM_LAC_RESERVED_DETACHED;
@ -321,16 +330,41 @@ int sms_queue_start(struct gsm_network *network, int max_pending)
return 0;
}
static int sub_ready_for_sm(struct gsm_subscriber *subscr)
static int sub_ready_for_sm(struct gsm_network *net, struct gsm_subscriber *subscr)
{
struct gsm_subscriber_connection *conn;
struct gsm_sms *sms;
struct gsm_sms_pending *pending;
struct gsm_subscriber_connection *conn;
/*
* The code used to be very clever and tried to submit
* a SMS during the Location Updating Request. This has
* two issues:
* 1.) The Phone might not be ready yet, e.g. the C155
* will not respond to the Submit when it is booting.
* 2.) The queue is already trying to submit SMS to the
* user and by not responding to the paging request
* we will set the LAC back to 0. We would have to
* stop the paging and move things over.
*
* We need to be careful in what we try here.
*/
/* check if we have pending requests */
pending = sms_subscriber_find_pending(net->sms_queue, subscr);
if (pending) {
LOGP(DMSC, LOGL_NOTICE,
"Pending paging while subscriber %llu attached.\n",
subscr->id);
pending->no_detach = 1;
return 0;
}
/* A subscriber has attached. Check if there are
* any pending SMS for him to be delivered */
conn = connection_for_subscr(subscr);
if (!conn)
return -1;
/* Now try to deliver any pending SMS to this sub */
sms = db_sms_get_unsent_for_subscr(subscr);
if (!sms)
return -1;
@ -347,7 +381,7 @@ static int sms_subscr_cb(unsigned int subsys, unsigned int signal,
return 0;
/* this is readyForSM */
return sub_ready_for_sm(subscr);
return sub_ready_for_sm(handler_data, subscr);
}
static int sms_sms_cb(unsigned int subsys, unsigned int signal,

View File

@ -140,8 +140,14 @@ int trau_frame_up2down(struct decoded_trau_frame *fr)
case TRAU_FT_EFR:
/* clear time alignment */
memset(fr->c_bits+5, 0, 6);
/* FIXME: set UFE appropriately */
/* FIXME: SP / BFI in case of DTx */
/* set UFE appropriately */
fr->c_bits[11] = 1; /* C12 (UFE), good frame (TODO) */
/* C13 .. C15 are spare and coded as '1' */
memset(fr->c_bits+12, 0x01, 3);
/* SP / BFI in case of DTx */
fr->c_bits[15] = 1; /* C16 (SP), no DTX (TODO) */
/* C17 .. C21 are spare and coded as '1' */
memset(fr->c_bits+16, 0x01, 5);
break;
case TRAU_FT_IDLE_UP:
memcpy(fr->c_bits, ft_idle_down_bits, 5);
@ -246,7 +252,7 @@ static struct decoded_trau_frame fr_idle_frame = {
.t_bits = { 1, 1, 1, 1 },
};
static uint8_t encoded_idle_frame[TRAU_FRAME_BITS];
static int dbits_initted;
static int dbits_initted = 0;
uint8_t *trau_idle_frame(void)
{
@ -254,7 +260,27 @@ uint8_t *trau_idle_frame(void)
if (!dbits_initted) {
/* set all D-bits to 1 */
memset(&fr_idle_frame.d_bits, 0x01, 260);
memset(&fr_idle_frame.c_bits, 0x01, 25); /* spare are set to 1 */
/* set Downlink Idle Speech Frame pattern */
fr_idle_frame.c_bits[0] = 0; /* C1 */
fr_idle_frame.c_bits[1] = 1; /* C2 */
fr_idle_frame.c_bits[2] = 1; /* C3 */
fr_idle_frame.c_bits[3] = 1; /* C4 */
fr_idle_frame.c_bits[4] = 0; /* C5 */
/* set no Time Alignment pattern */
fr_idle_frame.c_bits[5] = 0; /* C6 */
fr_idle_frame.c_bits[6] = 0; /* C7 */
fr_idle_frame.c_bits[7] = 0; /* C8 */
fr_idle_frame.c_bits[8] = 0; /* C9 */
fr_idle_frame.c_bits[9] = 0; /* C10 */
fr_idle_frame.c_bits[10] = 0; /* C11 */
/* already set to 1, but maybe we need to modify it in the future */
fr_idle_frame.c_bits[11] = 1; /* C12 (UFE), good frame */
fr_idle_frame.c_bits[15] = 1; /* C16 (SP), no DTX */
encode_fr(encoded_idle_frame, &fr_idle_frame);
dbits_initted = 1; /* set it to 1 to not call it again */
}
return encoded_idle_frame;
}

View File

@ -24,6 +24,8 @@
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/sccp/sccp.h>
#define return_when_not_connected(conn) \
if (!conn->sccp_con) {\
LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
@ -102,11 +104,13 @@ static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
conn->bts->cell_identity);
if (!resp) {
LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n");
sccp_connection_free(conn->sccp_con->sccp);
bsc_delete_connection(conn->sccp_con);
return BSC_API_CONN_POL_REJECT;
}
if (bsc_open_connection(conn->sccp_con, resp) != 0) {
sccp_connection_free(conn->sccp_con->sccp);
bsc_delete_connection(conn->sccp_con);
msgb_free(resp);
return BSC_API_CONN_POL_REJECT;

View File

@ -26,9 +26,9 @@
int bsc_grace_allow_new_connection(struct gsm_network *network)
{
if (!network->msc_data->rf_ctl)
if (!network->msc_data->rf_ctrl)
return 1;
return network->msc_data->rf_ctl->policy == S_RF_ON;
return network->msc_data->rf_ctrl->policy == S_RF_ON;
}
static int handle_sub(struct gsm_lchan *lchan, const char *text)

View File

@ -29,8 +29,8 @@
#include <openbsc/ipaccess.h>
#include <osmocom/core/application.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/process.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/sccp/sccp.h>
@ -49,7 +49,7 @@
struct gsm_network *bsc_gsmnet = 0;
static const char *config_file = "openbsc.cfg";
static const char *rf_ctl = NULL;
static const char *rf_ctrl = NULL;
extern const char *openbsc_copyright;
static int daemonize = 0;
@ -120,7 +120,7 @@ static void handle_options(int argc, char **argv)
log_set_log_level(osmo_stderr_target, atoi(optarg));
break;
case 'r':
rf_ctl = optarg;
rf_ctrl = optarg;
break;
default:
/* ignore */
@ -172,18 +172,57 @@ static void signal_handler(int signal)
}
struct location {
struct llist_head list;
unsigned long age;
int valid;
double lat;
double lon;
double height;
unsigned long age;
};
static struct location myloc;
static LLIST_HEAD(locations);
void cleanup_locations()
{
struct location *myloc, *tmp;
int invalpos = 0, i = 0;
LOGP(DCTRL, LOGL_DEBUG, "Checking position list.\n");
llist_for_each_entry_safe(myloc, tmp, &locations, list) {
i++;
if (i > 3) {
LOGP(DCTRL, LOGL_DEBUG, "Deleting old position.\n");
llist_del(&myloc->list);
talloc_free(myloc);
} else if (!myloc->valid) { /* Only capture the newest of subsequent invalid positions */
invalpos++;
if (invalpos > 1) {
LOGP(DCTRL, LOGL_DEBUG, "Deleting subsequent invalid position.\n");
invalpos--;
i--;
llist_del(&myloc->list);
talloc_free(myloc);
}
} else {
invalpos = 0;
}
}
LOGP(DCTRL, LOGL_DEBUG, "Found %i positions.\n", i);
}
CTRL_CMD_DEFINE(net_loc, "location");
int get_net_loc(struct ctrl_cmd *cmd, void *data)
{
cmd->reply = talloc_asprintf(cmd, "%lu,%f,%f,%f", myloc.age, myloc.lat, myloc.lon, myloc.height);
struct location *myloc;
if (llist_empty(&locations)) {
cmd->reply = talloc_asprintf(cmd, "0,0,0,0,0");
return CTRL_CMD_REPLY;
} else {
myloc = llist_entry(locations.next, struct location, list);
}
cmd->reply = talloc_asprintf(cmd, "%lu,%i,%f,%f,%f", myloc->age, myloc->valid, myloc->lat, myloc->lon, myloc->height);
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
@ -194,24 +233,38 @@ int get_net_loc(struct ctrl_cmd *cmd, void *data)
int set_net_loc(struct ctrl_cmd *cmd, void *data)
{
char *saveptr, *lat, *lon, *height, *age, *tmp;
char *saveptr, *lat, *lon, *height, *age, *valid, *tmp;
struct location *myloc;
tmp = talloc_strdup(cmd, cmd->value);
if (!tmp)
goto oom;
myloc = talloc_zero(tall_bsc_ctx, struct location);
if (!myloc) {
talloc_free(tmp);
goto oom;
}
INIT_LLIST_HEAD(&myloc->list);
age = strtok_r(tmp, ",", &saveptr);
valid = strtok_r(NULL, ",", &saveptr);
lat = strtok_r(NULL, ",", &saveptr);
lon = strtok_r(NULL, ",", &saveptr);
height = strtok_r(NULL, "\0", &saveptr);
myloc.age = atol(age);
myloc.lat = atof(lat);
myloc.lon = atof(lon);
myloc.height = atof(height);
myloc->age = atol(age);
myloc->valid = atoi(valid);
myloc->lat = atof(lat);
myloc->lon = atof(lon);
myloc->height = atof(height);
talloc_free(tmp);
/* Add location to the end of the list */
llist_add(&myloc->list, &locations);
cleanup_locations();
return get_net_loc(cmd, data);
oom:
cmd->reply = "OOM";
@ -220,9 +273,9 @@ oom:
int verify_net_loc(struct ctrl_cmd *cmd, const char *value, void *data)
{
char *saveptr, *latstr, *lonstr, *heightstr, *agestr, *tmp;
int ret = 0;
char *saveptr, *latstr, *lonstr, *heightstr, *agestr, *validstr, *tmp;
unsigned long age;
int valid;
double lat, lon, height;
tmp = talloc_strdup(cmd, value);
@ -230,23 +283,27 @@ int verify_net_loc(struct ctrl_cmd *cmd, const char *value, void *data)
return 1;
agestr = strtok_r(tmp, ",", &saveptr);
validstr = strtok_r(NULL, ",", &saveptr);
latstr = strtok_r(NULL, ",", &saveptr);
lonstr = strtok_r(NULL, ",", &saveptr);
heightstr = strtok_r(NULL, "\0", &saveptr);
if ((agestr == 0) || (latstr == 0) || (lonstr == 0) || (heightstr == 0))
ret = 1;
if ((agestr == NULL) || (validstr == NULL) || (latstr == NULL) ||
(lonstr == NULL) || (heightstr == NULL))
return 1;
age = atol(agestr);
valid = atoi(validstr);
lat = atof(latstr);
lon = atof(lonstr);
height = atof(heightstr);
talloc_free(tmp);
if ((age == 0) || (lat < -90) || (lat > 90) || (lon < -180) || (lon > 180))
if ((age == 0) || (lat < -90) || (lat > 90) || (lon < -180) ||
(lon > 180) || (valid < 0) || (valid > 2))
return 1;
return ret;
return 0;
}
CTRL_CMD_DEFINE(trx_rf_lock, "rf_locked");
@ -371,13 +428,13 @@ int main(int argc, char **argv)
ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_rf_lock);
data = bsc_gsmnet->msc_data;
if (rf_ctl)
bsc_replace_string(data, &data->rf_ctrl_name, rf_ctl);
if (rf_ctrl)
bsc_replace_string(data, &data->rf_ctrl_name, rf_ctrl);
if (data->rf_ctrl_name) {
data->rf_ctl = osmo_bsc_rf_create(data->rf_ctrl_name,
data->rf_ctrl = osmo_bsc_rf_create(data->rf_ctrl_name,
bsc_gsmnet);
if (!data->rf_ctl) {
if (!data->rf_ctrl) {
fprintf(stderr, "Failed to create the RF service.\n");
exit(1);
}

View File

@ -243,7 +243,7 @@ static int rf_write_cmd(struct osmo_fd *fd, struct msgb *msg)
return 0;
}
static int rf_ctl_accept(struct osmo_fd *bfd, unsigned int what)
static int rf_ctrl_accept(struct osmo_fd *bfd, unsigned int what)
{
struct osmo_bsc_rf_conn *conn;
struct osmo_bsc_rf *rf = bfd->data;
@ -338,7 +338,7 @@ struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net
}
bfd->when = BSC_FD_READ;
bfd->cb = rf_ctl_accept;
bfd->cb = rf_ctrl_accept;
bfd->data = rf;
if (osmo_fd_register(bfd) != 0) {

View File

@ -264,14 +264,14 @@ static void bsc_close_connections(struct bsc_msc_connection *msc_con)
static int handle_msc_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct osmo_msc_data *data;
struct msc_signal_data *msc;
if (subsys != SS_MSC)
return 0;
data = (struct osmo_msc_data *) signal_data;
msc = signal_data;
if (signal == S_MSC_LOST)
bsc_close_connections(data->msc_con);
bsc_close_connections(msc->data->msc_con);
return 0;
}

View File

@ -2,8 +2,8 @@
/* The main method to drive it as a standalone process */
/*
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009 by On-Waves
* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@ -40,7 +40,6 @@
#include <osmocom/core/application.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/process.h>
#include <osmocom/core/select.h>
#include <osmocom/vty/telnet_interface.h>
@ -59,6 +58,7 @@ void subscr_put() { abort(); }
#warning "Make use of the rtp proxy code"
static struct mgcp_config *cfg;
static struct mgcp_trunk_config *reset_trunk;
static int reset_endpoints = 0;
static int daemonize = 0;
@ -122,9 +122,10 @@ static void handle_options(int argc, char **argv)
}
/* simply remember this */
static int mgcp_rsip_cb(struct mgcp_config *cfg)
static int mgcp_rsip_cb(struct mgcp_trunk_config *tcfg)
{
reset_endpoints = 1;
reset_trunk = tcfg;
return 0;
}
@ -171,12 +172,14 @@ static int read_call_agent(struct osmo_fd *fd, unsigned int what)
}
if (reset_endpoints) {
LOGP(DMGCP, LOGL_NOTICE, "Asked to reset endpoints.\n");
LOGP(DMGCP, LOGL_NOTICE,
"Asked to reset endpoints: %d/%d\n",
reset_trunk->trunk_nr, reset_trunk->trunk_type);
reset_endpoints = 0;
/* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */
for (i = 1; i < cfg->trunk.number_endpoints; ++i)
mgcp_free_endp(&cfg->trunk.endpoints[i]);
for (i = 1; i < reset_trunk->number_endpoints; ++i)
mgcp_free_endp(&reset_trunk->endpoints[i]);
}
return 0;

View File

@ -47,7 +47,6 @@
#include <osmocom/core/application.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/process.h>
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>

View File

@ -32,7 +32,6 @@
#include <openbsc/db.h>
#include <osmocom/core/application.h>
#include <osmocom/core/select.h>
#include <osmocom/core/process.h>
#include <openbsc/debug.h>
#include <openbsc/e1_input.h>
#include <osmocom/core/talloc.h>

View File

@ -35,6 +35,7 @@
#include <openbsc/gsm_data.h>
#include <openbsc/abis_nm.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/tlv.h>
#include <openbsc/debug.h>
#include <osmocom/core/select.h>
@ -209,35 +210,31 @@ static int swload_cbfn(unsigned int hook, unsigned int event, struct msgb *msg,
return 0;
}
static const char *bs11_link_state[] = {
[0x00] = "Down",
[0x01] = "Up",
[0x02] = "Restoring",
static const struct value_string bs11_linkst_names[] = {
{ 0, "Down" },
{ 1, "Up" },
{ 2, "Restoring" },
{ 0, NULL }
};
static const char *linkstate_name(uint8_t linkstate)
{
if (linkstate > ARRAY_SIZE(bs11_link_state))
return "Unknown";
return bs11_link_state[linkstate];
return get_value_string(bs11_linkst_names, linkstate);
}
static const char *mbccu_load[] = {
[0] = "No Load",
[1] = "Load BTSCAC",
[2] = "Load BTSDRX",
[3] = "Load BTSBBX",
[4] = "Load BTSARC",
[5] = "Load",
static const struct value_string mbccu_load_names[] = {
{ 0, "No Load" },
{ 1, "Load BTSCAC" },
{ 2, "Load BTSDRX" },
{ 3, "Load BTSBBX" },
{ 4, "Load BTSARC" },
{ 5, "Load" },
{ 0, NULL }
};
static const char *mbccu_load_name(uint8_t linkstate)
{
if (linkstate > ARRAY_SIZE(mbccu_load))
return "Unknown";
return mbccu_load[linkstate];
return get_value_string(mbccu_load_names, linkstate);
}
static const char *bts_phase_name(uint8_t phase)
@ -899,7 +896,8 @@ int main(int argc, char **argv)
status_timer.cb = status_timer_cb;
while (1) {
osmo_select_main(0);
if (osmo_select_main(0) < 0)
break;
}
abis_nm_bs11_factory_logon(g_bts, 0);