diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h index 3b695e52a..db236b5d0 100644 --- a/openbsc/include/openbsc/gb_proxy.h +++ b/openbsc/include/openbsc/gb_proxy.h @@ -37,4 +37,6 @@ int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg); /* Main input function for Gb proxy */ int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci); +int gbprox_signal(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data); #endif diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 3ed7fdfde..3c639437a 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -415,6 +415,38 @@ int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci) return rc; } +/* Signal handler for signals from NS layer */ +int gbprox_signal(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct ns_signal_data *nssd = signal_data; + struct gprs_nsvc *nsvc = nssd->nsvc; + struct gbprox_peer *peer; + + if (subsys != SS_NS) + return 0; + + /* We currently only care about signals from the SGSN */ + if (!nsvc->remote_end_is_sgsn) + return 0; + + /* iterate over all BTS peers and send the respective PDU */ + llist_for_each_entry(peer, &gbprox_bts_peers, list) { + switch (signal) { + case S_NS_RESET: + gprs_ns_tx_reset(peer->nsvc, nssd->cause); + break; + case S_NS_BLOCK: + gprs_ns_tx_block(peer->nsvc, nssd->cause); + break; + case S_NS_UNBLOCK: + gprs_ns_tx_unblock(peer->nsvc); + break; + } + } + return 0; +} + #include diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c index 0054b7844..72f1417bc 100644 --- a/openbsc/src/gprs/gb_proxy_main.c +++ b/openbsc/src/gprs/gb_proxy_main.c @@ -118,6 +118,7 @@ int main(int argc, char **argv) exit(1); } gbcfg.nsi = gbprox_nsi; + register_signal_handler(SS_NS, &gbprox_signal, NULL); nsip_listen(gbprox_nsi, gbcfg.nsip_listen_port); /* 'establish' the outgoing connection to the SGSN */