aboutsummaryrefslogtreecommitdiffstats
path: root/src/gb
diff options
context:
space:
mode:
Diffstat (limited to 'src/gb')
-rw-r--r--src/gb/Makefile.am6
-rw-r--r--src/gb/gprs_ns2.c66
-rw-r--r--src/gb/gprs_ns2_fr.c2
-rw-r--r--src/gb/gprs_ns2_frgre.c2
-rw-r--r--src/gb/gprs_ns2_internal.h5
-rw-r--r--src/gb/gprs_ns2_udp.c4
6 files changed, 84 insertions, 1 deletions
diff --git a/src/gb/Makefile.am b/src/gb/Makefile.am
index c829c293..cbee3338 100644
--- a/src/gb/Makefile.am
+++ b/src/gb/Makefile.am
@@ -28,6 +28,12 @@ libosmogb_la_SOURCES = gprs_ns.c gprs_ns_frgre.c gprs_ns_vty.c gprs_ns_sns.c \
gprs_ns2_message.c gprs_ns2_vty.c gprs_ns2_vty2.c \
gprs_bssgp2.c bssgp_bvc_fsm.c \
common_vty.c frame_relay.c
+
+# convenience library for testing with access to all non-static symbols
+noinst_LTLIBRARIES = libosmogb-test.la
+libosmogb_test_la_LIBADD = $(libosmogb_la_LIBADD)
+libosmogb_test_la_SOURCES= $(libosmogb_la_SOURCES)
+
endif
EXTRA_DIST = libosmogb.map
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 1098f221..e43b6365 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -471,7 +471,7 @@ void ns2_prim_status_ind(struct gprs_ns2_nse *nse,
nsp.nsei = nse->nsei;
nsp.bvci = bvci;
nsp.u.status.cause = cause;
- nsp.u.status.transfer = -1;
+ nsp.u.status.transfer = ns2_count_transfer_cap(nse, bvci);
nsp.u.status.first = nse->first;
nsp.u.status.persistent = nse->persistent;
if (nsvc)
@@ -1263,4 +1263,68 @@ enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode(
}
}
+static void add_bind_array(struct gprs_ns2_vc_bind **array,
+ struct gprs_ns2_vc_bind *bind, int size)
+{
+ int i;
+ for (i=0; i < size; i++) {
+ if (array[i] == bind)
+ return;
+ if (!array[i])
+ break;
+ }
+
+ if (i == size)
+ return;
+
+ array[i] = bind;
+}
+
+/*! calculate the transfer capabilities for a nse
+ * \param nse the nse to count the transfer capability
+ * \param bvci a bvci - unused
+ * \return the transfer capability in mbit. On error < 0.
+ */
+int ns2_count_transfer_cap(struct gprs_ns2_nse *nse,
+ uint16_t bvci)
+{
+ struct gprs_ns2_vc *nsvc;
+ struct gprs_ns2_vc_bind **active_binds;
+ int i, active_nsvcs = 0, transfer_cap = 0;
+
+ /* calculate the transfer capabilities based on the binds.
+ * A bind has a transfer capability which is shared across all NSVCs.
+ * Take care the bind cap is not counted twice within a NSE.
+ * This should be accurate for FR and UDP but not for FR/GRE. */
+
+ if (!nse->alive)
+ return 0;
+
+ llist_for_each_entry(nsvc, &nse->nsvc, list) {
+ if (gprs_ns2_vc_is_unblocked(nsvc))
+ active_nsvcs++;
+ }
+ /* an alive nse should always have active_nsvcs */
+ OSMO_ASSERT(active_nsvcs);
+
+ active_binds = talloc_zero_array(nse, struct gprs_ns2_vc_bind*, active_nsvcs);
+ if (!active_binds)
+ return -ENOMEM;
+
+ llist_for_each_entry(nsvc, &nse->nsvc, list) {
+ if (!gprs_ns2_vc_is_unblocked(nsvc))
+ continue;
+ add_bind_array(active_binds, nsvc->bind, active_nsvcs);
+ }
+
+ /* TODO: change calcuation for FR/GRE */
+ for (i = 0; i < active_nsvcs; i++) {
+ if (active_binds[i])
+ transfer_cap += active_binds[i]->transfer_capability;
+ }
+
+ talloc_free(active_binds);
+ return transfer_cap;
+}
+
/*! @} */
diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c
index e972a343..ca2d38cf 100644
--- a/src/gb/gprs_ns2_fr.c
+++ b/src/gb/gprs_ns2_fr.c
@@ -579,6 +579,8 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
bind->driver = &vc_driver_fr;
bind->ll = GPRS_NS2_LL_FR;
+ /* 2 mbit */
+ bind->transfer_capability = 2;
bind->send_vc = fr_vc_sendmsg;
bind->free_vc = free_vc;
bind->dump_vty = dump_vty;
diff --git a/src/gb/gprs_ns2_frgre.c b/src/gb/gprs_ns2_frgre.c
index 014517aa..625d05cf 100644
--- a/src/gb/gprs_ns2_frgre.c
+++ b/src/gb/gprs_ns2_frgre.c
@@ -569,6 +569,8 @@ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
bind->driver = &vc_driver_frgre;
bind->ll = GPRS_NS2_LL_FR_GRE;
+ /* 2 mbit transfer capability. Counting should be done different for this. */
+ bind->transfer_capability = 2;
bind->send_vc = frgre_vc_sendmsg;
bind->free_vc = free_vc;
bind->nsi = nsi;
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index 4c0cdd01..c33f7f8a 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -198,6 +198,9 @@ struct gprs_ns2_vc_bind {
bool accept_ipaccess;
bool accept_sns;
+ /*! transfer capability in mbit */
+ int transfer_capability;
+
/*! which link-layer are we based on? */
enum gprs_ns2_ll ll;
@@ -312,3 +315,5 @@ int gprs_ns2_vc_is_unblocked(struct gprs_ns2_vc *nsvc);
/* nse */
void ns2_nse_notify_unblocked(struct gprs_ns2_vc *nsvc, bool unblocked);
enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode(enum gprs_ns2_dialect dialect);
+int ns2_count_transfer_cap(struct gprs_ns2_nse *nse,
+ uint16_t bvci);
diff --git a/src/gb/gprs_ns2_udp.c b/src/gb/gprs_ns2_udp.c
index 90582794..370937f5 100644
--- a/src/gb/gprs_ns2_udp.c
+++ b/src/gb/gprs_ns2_udp.c
@@ -336,6 +336,10 @@ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
bind->driver = &vc_driver_ip;
bind->ll = GPRS_NS2_LL_UDP;
+ /* expect 100 mbit at least.
+ * TODO: ask the network layer about the speed. But would require
+ * notification on change. */
+ bind->transfer_capability = 100;
bind->send_vc = nsip_vc_sendmsg;
bind->free_vc = free_vc;
bind->dump_vty = dump_vty;