gprs_ns2: Encapsulate setting NSE dialect
Setting the NSE dialect possibly involves the creating (or destruction)
of a IP-SNS FSM. Encapsulate that, rather than having every caller
re-implement that.
Change-Id: I24fdc26fbcfda039bd58ea166f4d5c2fd1801da1
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index e19ae78..93b7c3a 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -781,7 +781,6 @@
enum gprs_ns2_ll linklayer, enum gprs_ns2_dialect dialect)
{
struct gprs_ns2_nse *nse;
- char sns[16];
nse = gprs_ns2_nse_by_nsei(nsi, nsei);
if (nse) {
@@ -792,17 +791,13 @@
nse = talloc_zero(nsi, struct gprs_ns2_nse);
if (!nse)
return NULL;
+ nse->dialect = GPRS_NS2_DIALECT_UNDEF;
- if (dialect == GPRS_NS2_DIALECT_SNS) {
- snprintf(sns, sizeof(sns), "NSE%05u-SNS", nsei);
- nse->bss_sns_fi = ns2_sns_bss_fsm_alloc(nse, sns);
- if (!nse->bss_sns_fi) {
- talloc_free(nse);
- return NULL;
- }
+ if (ns2_nse_set_dialect(nse, dialect) < 0) {
+ talloc_free(nse);
+ return NULL;
}
- nse->dialect = dialect;
nse->ll = linklayer;
nse->nsei = nsei;
nse->nsi = nsi;
@@ -814,6 +809,38 @@
return nse;
}
+int ns2_nse_set_dialect(struct gprs_ns2_nse *nse, enum gprs_ns2_dialect dialect)
+{
+ char sns[16];
+
+ if (nse->dialect == dialect)
+ return 0;
+
+ switch (nse->dialect) {
+ case GPRS_NS2_DIALECT_UNDEF:
+ if (dialect == GPRS_NS2_DIALECT_SNS) {
+ snprintf(sns, sizeof(sns), "NSE%05u-SNS", nse->nsei);
+ nse->bss_sns_fi = ns2_sns_bss_fsm_alloc(nse, sns);
+ if (!nse->bss_sns_fi)
+ return -1;
+ }
+ nse->dialect = dialect;
+ break;
+ default:
+ if (dialect == GPRS_NS2_DIALECT_UNDEF) {
+ if (nse->bss_sns_fi)
+ osmo_fsm_inst_term(nse->bss_sns_fi, OSMO_FSM_TERM_REQUEST, NULL);
+ nse->bss_sns_fi = NULL;
+ nse->dialect = GPRS_NS2_DIALECT_UNDEF;
+ } else {
+ /* we don't support arbitrary changes without going through UNDEF first */
+ return -EPERM;
+ }
+ }
+
+ return 0;
+}
+
/*! Return the NSEI
* \param[in] nse NS Entity
* \return the nsei.