diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2009-10-22 14:30:42 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2009-11-20 17:35:45 +0100 |
commit | 097bdeb77de0aad435dc99a89ca1b586e8872b55 (patch) | |
tree | f8a6367f82d21f7bdfe8f86c4dec9eae8a44fe6c /openbsc/src/bsc_msc_ip.c | |
parent | 1b85de02e0add59189159ecdaca59d2786d7266d (diff) |
[bssap] First go at implementing ASSIGNMENT REQUEST
Diffstat (limited to 'openbsc/src/bsc_msc_ip.c')
-rw-r--r-- | openbsc/src/bsc_msc_ip.c | 119 |
1 files changed, 118 insertions, 1 deletions
diff --git a/openbsc/src/bsc_msc_ip.c b/openbsc/src/bsc_msc_ip.c index f3c85904e..27603a7eb 100644 --- a/openbsc/src/bsc_msc_ip.c +++ b/openbsc/src/bsc_msc_ip.c @@ -52,6 +52,7 @@ struct gsm_network *bsc_gsmnet = 0; static const char *config_file = "openbsc.cfg"; static char *msc_address = "127.0.0.1"; static struct bsc_fd msc_connection; +static struct in_addr local_addr; extern int ipacc_rtp_direct; extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file); @@ -74,6 +75,7 @@ struct bss_sccp_connection_data *bss_sccp_create_data() void bss_sccp_free_data(struct bss_sccp_connection_data *data) { + bsc_del_timer(&data->T10); bsc_free_queued(data->sccp); bts_free_queued(data); talloc_free(data); @@ -267,6 +269,67 @@ static int handle_cipher_m_complete(struct msgb *msg) return 1; } +/* Receive a ASSIGNMENT COMPLETE */ +static int handle_ass_compl(struct msgb *msg) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + + DEBUGP(DMSC, "ASSIGNMENT COMPLETE from MS, forwarding to MSC\n"); + + if (!msg->lchan->msc_data) { + DEBUGP(DMSC, "No MSC data\n"); + return -1; + } + + if (msgb_l3len(msg) - sizeof(*gh) != 1) { + DEBUGP(DMSC, "assignment failure invalid: %d\n", + msgb_l3len(msg) - sizeof(*gh)); + return -1; + } + gsm0808_send_assignment_compl(msg->lchan, gh->data[0]); + return 1; +} + +/* + * Receive a ASSIGNMENT FAILURE. If the message is failed + * to be parsed the T10 timer will send the failure. + */ +static int handle_ass_fail(struct msgb *msg) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + + DEBUGP(DMSC, "ASSIGNMENT FAILURE from MS, forwarding to MSC\n"); + if (!msg->lchan->msc_data) { + DEBUGP(DMSC, "No MSC data\n"); + return -1; + } + + if (msgb_l3len(msg) - sizeof(*gh) != 1) { + DEBUGP(DMSC, "assignment failure invalid: %d\n", + msgb_l3len(msg) - sizeof(*gh)); + return -1; + } + + gsm0808_send_assignment_failure(msg->lchan, + GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, &gh->data[0]); + return 1; +} + +/* + * Receive a GSM04.08 MODIFY ACK. Actually we have to check + * the content to see if this was a success or not. + */ +static int handle_modify_ack(struct msgb *msg) +{ + int rc; + + /* modify RSL */ + rc = gsm48_rx_rr_modif_ack(msg); + + gsm0808_send_assignment_compl(msg->lchan, 0); + return 1; +} + /* Receive a GSM 04.08 Radio Resource (RR) message */ static int gsm0408_rcv_rr(struct msgb *msg) { @@ -284,6 +347,15 @@ static int gsm0408_rcv_rr(struct msgb *msg) case GSM48_MT_RR_CIPH_M_COMPL: rc = handle_cipher_m_complete(msg); break; + case GSM48_MT_RR_ASS_COMPL: + rc = handle_ass_compl(msg); + break; + case GSM48_MT_RR_ASS_FAIL: + rc = handle_ass_fail(msg); + break; + case GSM48_MT_RR_CHAN_MODE_MODIF_ACK: + rc = handle_modify_ack(msg); + break; default: break; } @@ -345,6 +417,43 @@ int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id) return rc; } +/* handle ipaccess signals */ +static int handle_abisip_signal(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct gsm_lchan *lchan = signal_data; + struct gsm_bts_trx_ts *ts; + int rc; + + if (subsys != SS_ABISIP) + return 0; + + ts = lchan->ts; + + switch (signal) { + case S_ABISIP_CRCX_ACK: + /* we can ask it to connect now */ + if (lchan->msc_data) { + DEBUGP(DMSC, "Connecting BTS to port: %d conn: %d\n", + lchan->msc_data->rtp_port, ts->abis_ip.conn_id); + + rc = rsl_ipacc_mdcx(lchan, ntohl(local_addr.s_addr), + lchan->msc_data->rtp_port, + ts->abis_ip.conn_id, + lchan->msc_data->rtp_payload2); + if (rc < 0) { + DEBUGP(DMSC, "Failed to send connect: %d\n", rc); + return rc; + } + } + break; + case S_ABISIP_DLCX_IND: + break; + } + + return 0; +} + static void print_usage() { printf("Usage: bsc_hack\n"); @@ -522,6 +631,7 @@ static void print_help() printf(" -s --disable-color\n"); printf(" -c --config-file filename The config file to use.\n"); printf(" -m --msc=IP. The address of the MSC.\n"); + printf(" -l --local=IP. The local address of the MGCP.\n"); } static void handle_options(int argc, char** argv) @@ -536,10 +646,11 @@ static void handle_options(int argc, char** argv) {"timestamp", 0, 0, 'T'}, {"rtp-proxy", 0, 0, 'P'}, {"msc", 1, 0, 'm'}, + {"local", 1, 0, 'l'}, {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "hd:sTPc:m:", + c = getopt_long(argc, argv, "hd:sTPc:m:l:", long_options, &option_index); if (c == -1) break; @@ -567,6 +678,9 @@ static void handle_options(int argc, char** argv) case 'm': msc_address = strdup(optarg); break; + case 'l': + inet_aton(optarg, &local_addr); + break; default: /* ignore */ break; @@ -612,6 +726,9 @@ int main(int argc, char **argv) sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL); sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL); + /* initialize ipaccess handling */ + register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL); + rc = connect_to_msc(msc_address, 5000); if (rc < 0) { fprintf(stderr, "Opening the MSC connection failed.\n"); |