diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index be530c38d..d0d5996c2 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -737,5 +737,7 @@ int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv, extern const char *gsm0408_cc_msg_names[]; int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv); +int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type); +int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr); #endif diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 3c9ffbbec..bac920e31 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -1463,20 +1463,15 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg) struct gsm_bts *bts = msg->lchan->ts->trx->bts; struct gsm48_hdr *gh = msgb_l3(msg); u_int8_t *classmark2_lv = gh->data + 1; - u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv; - u_int8_t mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; + u_int8_t mi_type; char mi_string[GSM48_MI_SIZE]; struct gsm_subscriber *subscr = NULL; - struct paging_signal_data sig_data; int rc = 0; - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, *mi_lv); + gsm48_paging_extract_mi(msg, mi_string, &mi_type); DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n", mi_type, mi_string); - if (is_siemens_bts(bts)) - send_siemens_mrpci(msg->lchan, classmark2_lv); - switch (mi_type) { case GSM_MI_TYPE_TMSI: subscr = subscr_get_by_tmsi(bts->network, @@ -1499,30 +1494,7 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg) memcpy(subscr->equipment.classmark2, classmark2_lv+1, *classmark2_lv); db_sync_equipment(&subscr->equipment); - if (!msg->lchan->subscr) { - msg->lchan->subscr = subscr; - } else if (msg->lchan->subscr != subscr) { - DEBUGP(DRR, "<- 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 = msg->lchan->subscr; - } - - sig_data.subscr = subscr; - sig_data.bts = msg->lchan->ts->trx->bts; - sig_data.lchan = msg->lchan; - - dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data); - - /* Stop paging on the bts we received the paging response */ - paging_request_stop(msg->trx->bts, subscr, msg->lchan); - - /* FIXME: somehow signal the completion of the PAGING to - * the entity that requested the paging */ - + rc = gsm48_handle_paging_resp(msg, subscr); return rc; } diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c index c9cbd5c34..47ec8ab0e 100644 --- a/openbsc/src/gsm_04_08_utils.c +++ b/openbsc/src/gsm_04_08_utils.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #define GSM48_ALLOC_SIZE 1024 #define GSM48_ALLOC_HEADROOM 128 @@ -413,3 +415,45 @@ int send_siemens_mrpci(struct gsm_lchan *lchan, return rsl_siemens_mrpci(lchan, &mrpci); } +int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + u_int8_t *classmark2_lv = gh->data + 1; + u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv; + *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; + + return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv); +} + +int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr) +{ + struct gsm_bts *bts = msg->lchan->ts->trx->bts; + struct gsm48_hdr *gh = msgb_l3(msg); + u_int8_t *classmark2_lv = gh->data + 1; + struct paging_signal_data sig_data; + + if (is_siemens_bts(bts)) + send_siemens_mrpci(msg->lchan, classmark2_lv); + + if (!msg->lchan->subscr) { + msg->lchan->subscr = subscr; + } else if (msg->lchan->subscr != subscr) { + DEBUGP(DRR, "<- 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 = msg->lchan->subscr; + } + + sig_data.subscr = subscr; + sig_data.bts = msg->lchan->ts->trx->bts; + sig_data.lchan = msg->lchan; + + dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data); + + /* Stop paging on the bts we received the paging response */ + paging_request_stop(msg->trx->bts, subscr, msg->lchan); + return 0; +}