mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-10-23 08:12:01 +00:00
add preliminary paging response handling, incomplete
In gsm_04_08.c, add a static handle_paging_resp() to take over from the libbsc function gsm48_handle_paging_resp(). Use the subscr->requests listing to handle a Paging Response and call the pending cbfn. In NITB, this used to be done via BTS, and I haven't entirely resolved yet how exactly to rewire this in standalone libmsc. So far, this "works for me", but is worth another visit. Still missing: enable Integrity Protection.
This commit is contained in:
@@ -88,6 +88,20 @@ enum gsm_subscriber_update_reason {
|
||||
GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct for pending channel requests. This is managed in the
|
||||
* llist_head requests of each subscriber. The reference counting
|
||||
* should work in such a way that a subscriber with a pending request
|
||||
* remains in memory.
|
||||
*/
|
||||
struct subscr_request {
|
||||
struct llist_head entry;
|
||||
|
||||
/* the callback data */
|
||||
gsm_cbfn *cbfn;
|
||||
void *param;
|
||||
};
|
||||
|
||||
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
|
||||
|
@@ -1245,6 +1245,47 @@ static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *m
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int handle_paging_resp(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct subscr_request *req, *req2;
|
||||
|
||||
if (!conn->subscr) {
|
||||
conn->subscr = subscr;
|
||||
} else if (conn->subscr != subscr) {
|
||||
LOGP(DRR, LOGL_ERROR, "<- Channel already owned by someone else?\n");
|
||||
subscr_put(subscr);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
DEBUGP(DRR, "<- Channel already owned by us\n");
|
||||
subscr_put(subscr);
|
||||
subscr = conn->subscr;
|
||||
}
|
||||
|
||||
osmo_counter_inc(conn->network->stats.paging.completed);
|
||||
|
||||
if (!subscr->is_paging) {
|
||||
LOGP(DRR, LOGL_ERROR, "Paging Response received for subscriber that is not paging\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
llist_for_each_entry_safe(req, req2, &subscr->requests, entry) {
|
||||
gsm_cbfn *cbfn = req->cbfn;
|
||||
void *param = req->param;
|
||||
|
||||
llist_del(&req->entry);
|
||||
req = NULL;
|
||||
|
||||
if (conn && cbfn) {
|
||||
LOGP(DPAG, LOGL_DEBUG, "Calling paging cbfn.\n");
|
||||
cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED,
|
||||
msg, conn, param);
|
||||
} else
|
||||
LOGP(DPAG, LOGL_DEBUG, "Paging without action.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Receive a PAGING RESPONSE message from the MS */
|
||||
static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
||||
{
|
||||
@@ -1254,7 +1295,6 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
|
||||
uint8_t mi_type;
|
||||
char mi_string[GSM48_MI_SIZE];
|
||||
struct gsm_subscriber *subscr = NULL;
|
||||
int rc = 0;
|
||||
|
||||
resp = (struct gsm48_pag_resp *) &gh->data[0];
|
||||
gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh),
|
||||
@@ -1289,12 +1329,12 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
|
||||
/* We received a paging */
|
||||
conn->expire_timer_stopped = 1;
|
||||
|
||||
/* FIXME start Integrity Protection in Iu mode */
|
||||
|
||||
#if BEFORE_MSCSPLIT
|
||||
rc = gsm48_handle_paging_resp(conn, msg, subscr);
|
||||
return rc;
|
||||
return gsm48_handle_paging_resp(conn, msg, subscr);
|
||||
#else
|
||||
LOGP(DRR, LOGL_ERROR, "MSC wants to tell BSC to gsm48_handle_paging_resp() but A-interface not implemented\n");
|
||||
return -1;
|
||||
return handle_paging_resp(conn, msg, subscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -48,20 +48,6 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq,
|
||||
gsm_cbfn *cb, void *cb_data);
|
||||
|
||||
|
||||
/*
|
||||
* Struct for pending channel requests. This is managed in the
|
||||
* llist_head requests of each subscriber. The reference counting
|
||||
* should work in such a way that a subscriber with a pending request
|
||||
* remains in memory.
|
||||
*/
|
||||
struct subscr_request {
|
||||
struct llist_head entry;
|
||||
|
||||
/* the callback data */
|
||||
gsm_cbfn *cbfn;
|
||||
void *param;
|
||||
};
|
||||
|
||||
static struct gsm_subscriber *get_subscriber(struct gsm_subscriber_group *sgrp,
|
||||
int type, const char *ident)
|
||||
{
|
||||
|
Reference in New Issue
Block a user