diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-07-29 11:44:28 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-07-29 11:44:28 +0200 |
commit | 901d57db07d21f8e7d7f4b11421f63c44c2b2600 (patch) | |
tree | 432aa762fd5194cf462127f1b47a24d81d58b6e2 | |
parent | 07b7bd79d68c56212b3e248e6f9273a6c556c69d (diff) | |
parent | f31dd860591e18d5f0ba45ef5d9ca8aac45fc9b7 (diff) |
Merge branch 'master' of git.osmocom.org:openbsc
38 files changed, 281 insertions, 117 deletions
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h index 37011a16e..d0c85ea30 100644 --- a/openbsc/include/openbsc/db.h +++ b/openbsc/include/openbsc/db.h @@ -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, diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index ff4aec1d5..d78252a93 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -35,6 +35,7 @@ enum { DLLC, DSNDCP, DNAT, + DCTRL, Debug_LastEntry, }; diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 5023d0684..62fbb85a5 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -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 { diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index b9b89e60c..ec6c2c001 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -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); diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index b9f81161f..7c290c7f3 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -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 diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h index 3212b3657..59b75c303 100644 --- a/openbsc/include/openbsc/osmo_msc_data.h +++ b/openbsc/include/openbsc/osmo_msc_data.h @@ -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; diff --git a/openbsc/include/openbsc/paging.h b/openbsc/include/openbsc/paging.h index 0872eb866..e1438ba4c 100644 --- a/openbsc/include/openbsc/paging.h +++ b/openbsc/include/openbsc/paging.h @@ -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 diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c index 028f9896f..ee8a87002 100644 --- a/openbsc/src/gprs/gb_proxy_main.c +++ b/openbsc/src/gprs/gb_proxy_main.c @@ -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> diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 46c49318f..098e4c25b 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -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 */ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index f7408ef97..7d4ed51e4 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -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 { diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index f193aa308..71694a433 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -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 */ diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index bfa2e52c8..fa61e0e3b 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -281,5 +281,6 @@ int main(int argc, char **argv) exit(3); } + /* not reached */ exit(0); } diff --git a/openbsc/src/ipaccess/ipaccess-firmware.c b/openbsc/src/ipaccess/ipaccess-firmware.c index 6d391075c..5f55bb526 100644 --- a/openbsc/src/ipaccess/ipaccess-firmware.c +++ b/openbsc/src/ipaccess/ipaccess-firmware.c @@ -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; } diff --git a/openbsc/src/ipaccess/ipaccess-proxy.c b/openbsc/src/ipaccess/ipaccess-proxy.c index b4d17e2c7..1dd5b8456 100644 --- a/openbsc/src/ipaccess/ipaccess-proxy.c +++ b/openbsc/src/ipaccess/ipaccess-proxy.c @@ -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"); } diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 494d4caba..49e86ba2c 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -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); diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 8356bd9a5..d74907b0a 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -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, diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 1be8cb7a1..02a3adfcc 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -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; } diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 971cdf703..26ed7d9f4 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -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); diff --git a/openbsc/src/libbsc/gsm_04_08_utils.c b/openbsc/src/libbsc/gsm_04_08_utils.c index 17bce85a6..92335f24c 100644 --- a/openbsc/src/libbsc/gsm_04_08_utils.c +++ b/openbsc/src/libbsc/gsm_04_08_utils.c @@ -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; diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c index 4dfa92161..fe60e3f6d 100644 --- a/openbsc/src/libbsc/paging.c +++ b/openbsc/src/libbsc/paging.c @@ -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; +} diff --git a/openbsc/src/libcommon/debug.c b/openbsc/src/libcommon/debug.c index 1372150c8..479390c10 100644 --- a/openbsc/src/libcommon/debug.c +++ b/openbsc/src/libcommon/debug.c @@ -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 { diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 58e3bed66..b52d58ad2 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -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; } diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c index 0e625cd79..91c69e094 100644 --- a/openbsc/src/libctrl/control_if.c +++ b/openbsc/src/libctrl/control_if.c @@ -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)); diff --git a/openbsc/src/libgb/gprs_bssgp_util.c b/openbsc/src/libgb/gprs_bssgp_util.c index b5393239e..a1eb37e18 100644 --- a/openbsc/src/libgb/gprs_bssgp_util.c +++ b/openbsc/src/libgb/gprs_bssgp_util.c @@ -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); } diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 1d26850ba..44a3b87ff 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -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; } diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 1ddd3fdf4..a7eeda4dc 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -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) " diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index ba72c37bd..ee7f5772c 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -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 */ diff --git a/openbsc/src/libmsc/sms_queue.c b/openbsc/src/libmsc/sms_queue.c index 30fa5f098..e685973a0 100644 --- a/openbsc/src/libmsc/sms_queue.c +++ b/openbsc/src/libmsc/sms_queue.c @@ -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, diff --git a/openbsc/src/libtrau/trau_frame.c b/openbsc/src/libtrau/trau_frame.c index 15cbe4ff9..8fbaf8606 100644 --- a/openbsc/src/libtrau/trau_frame.c +++ b/openbsc/src/libtrau/trau_frame.c @@ -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; } diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index 1a6d806a2..d02b0b5e4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -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; diff --git a/openbsc/src/osmo-bsc/osmo_bsc_grace.c b/openbsc/src/osmo-bsc/osmo_bsc_grace.c index c67984b70..fbc26acb3 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_grace.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_grace.c @@ -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) diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 7d5d835d6..7d376ef0e 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -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); } diff --git a/openbsc/src/osmo-bsc/osmo_bsc_rf.c b/openbsc/src/osmo-bsc/osmo_bsc_rf.c index cd64b52cc..6e9e027d9 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_rf.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_rf.c @@ -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) { diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c index c17690831..4f03b52ff 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c @@ -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; } diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c index 921fa09b2..ee1543cdb 100644 --- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c +++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c @@ -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; diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 9ed8e58fe..445f45915 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -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> diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index fc67a4d52..9693dc476 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -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> diff --git a/openbsc/src/utils/bs11_config.c b/openbsc/src/utils/bs11_config.c index 41acd6920..ef0107292 100644 --- a/openbsc/src/utils/bs11_config.c +++ b/openbsc/src/utils/bs11_config.c @@ -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); |