From c7e7f6868b6f24346424dee904f4e76d3f216ff4 Mon Sep 17 00:00:00 2001 From: Ivan Kluchnikov Date: Fri, 29 Jun 2012 22:53:15 +0400 Subject: [PATCH] Implemented Paging procedure on CCCH. Added functions: - gprs_bssgp_pcu_rx_paging_ps() for handling paging message from BSSGP; - write_paging_request() for writing paging request message; - gprs_rlcmac_paging_request() and pcu_l1if_tx_pch() for sending paging request message to BTS. --- src/gprs_bssgp_pcu.cpp | 17 ++++++++++++++++- src/gprs_rlcmac.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/gprs_rlcmac.h | 2 ++ src/pcu_l1_if.cpp | 11 +++++++++++ src/pcu_l1_if.h | 1 + 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index df37618a..2dfaba38 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -56,6 +56,20 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) tbf_dl_data_transfer(tbf, llc_pdu, llc_pdu_len); } +int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, struct tlv_parsed *tp) +{ + uint8_t *ptmsi = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_TMSI); + uint16_t ptmsi_len = TLVP_LEN(tp, BSSGP_IE_TMSI); + + LOGP(DBSSGP, LOGL_NOTICE, " P-TMSI = "); + for (int i = 0; i < ptmsi_len; i++) + { + LOGPC(DBSSGP, LOGL_NOTICE, "%02x", ptmsi[i]); + } + LOGPC(DBSSGP, LOGL_NOTICE, "\n"); + + gprs_rlcmac_paging_request(ptmsi, ptmsi_len); +} /* Receive a BSSGP PDU from a BSS on a PTP BVCI */ int gprs_bssgp_pcu_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_bvc_ctx *bctx) @@ -123,7 +137,8 @@ int gprs_bssgp_pcu_rx_sign(struct msgb *msg, struct tlv_parsed *tp, struct bssgp LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP_PDUT_BVC_RESET_ACK\n"); break; case BSSGP_PDUT_PAGING_PS: - LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP_PDUT_PAGING_PS\n"); + LOGP(DBSSGP, LOGL_NOTICE, "RX: [SGSN->PCU] BSSGP_PDUT_PAGING_PS\n"); + gprs_bssgp_pcu_rx_paging_ps(msg, tp); break; case BSSGP_PDUT_PAGING_CS: LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP_PDUT_PAGING_CS\n"); diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 17120f9e..711fb61d 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -718,6 +718,35 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, uint return wp/8; } +int write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi_len) +{ + unsigned wp = 0; + + bitvec_write_field(dest, wp,0x0,4); // Skip Indicator + bitvec_write_field(dest, wp,0x6,4); // Protocol Discriminator + bitvec_write_field(dest, wp,0x21,8); // Paging Request Message Type + + bitvec_write_field(dest, wp,0x0,4); // Page Mode + bitvec_write_field(dest, wp,0x0,4); // Channel Needed + + // Mobile Identity + bitvec_write_field(dest, wp,ptmsi_len+1,8); // Mobile Identity length + bitvec_write_field(dest, wp,0xf,4); // unused + bitvec_write_field(dest, wp,0x4,4); // PTMSI type + for (int i = 0; i < ptmsi_len; i++) + { + bitvec_write_field(dest, wp,ptmsi[i],8); // PTMSI + } + bitvec_write_field(dest, wp,0x0,1); // "L" NLN(PCH) = off + bitvec_write_field(dest, wp,0x0,1); // "L" Priority1 = off + bitvec_write_field(dest, wp,0x1,1); // "L" Priority2 = off + bitvec_write_field(dest, wp,0x0,1); // "L" Group Call information = off + bitvec_write_field(dest, wp,0x0,1); // "H" Packet Page Indication 1 = packet paging procedure + bitvec_write_field(dest, wp,0x1,1); // "H" Packet Page Indication 2 = packet paging procedure + bitvec_write_field(dest, wp,0x3,2); // spare padding + return wp/8; +} + void write_packet_uplink_ack(RlcMacDownlink_t * block, uint8_t tfi, uint32_t tlli, uint8_t fi, uint8_t bsn) { // Packet Uplink Ack/Nack TS 44.060 11.2.28 @@ -1158,3 +1187,12 @@ void gprs_rlcmac_packet_downlink_assignment(gprs_rlcmac_tbf *tbf) bitvec_free(packet_downlink_assignment_vec); } +void gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len) +{ + LOGP(DRLCMAC, LOGL_NOTICE, "TX: [PCU -> BTS] Paging Request (CCCH)\n"); + bitvec *paging_request = bitvec_alloc(23); + bitvec_unhex(paging_request, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); + int len = write_paging_request(paging_request, ptmsi, ptmsi_len); + pcu_l1if_tx_pch(paging_request, len); + bitvec_free(paging_request); +} diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 3033973a..ed0850bb 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -154,4 +154,6 @@ void gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf); void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf); void gprs_rlcmac_packet_downlink_assignment(gprs_rlcmac_tbf *tbf); + +void gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len); #endif // GPRS_RLCMAC_H diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 4836e940..4186e292 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -125,6 +125,17 @@ void pcu_l1if_tx_agch(bitvec * block, int len) osmo_wqueue_enqueue(&l1fh->udp_wq, msg); } +void pcu_l1if_tx_pch(bitvec * block, int len) +{ + struct msgb *msg = l1p_msgb_alloc(); + GsmL1_Prim_t *prim = msgb_l1prim(msg); + prim->id = GsmL1_PrimId_PhDataReq; + prim->u.phDataReq.sapi = GsmL1_Sapi_Pch; + bitvec_pack(block, prim->u.phDataReq.msgUnitParam.u8Buffer); + prim->u.phDataReq.msgUnitParam.u8Size = len; + osmo_wqueue_enqueue(&l1fh->udp_wq, msg); +} + int pcu_l1if_rx_pdch(GsmL1_PhDataInd_t *data_ind) { bitvec *block = bitvec_alloc(data_ind->msgUnitParam.u8Size); diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h index 241f4943..82fa8840 100644 --- a/src/pcu_l1_if.h +++ b/src/pcu_l1_if.h @@ -53,6 +53,7 @@ void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, void pcu_l1if_tx_ptcch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, uint32_t fn, uint8_t block_nr); void pcu_l1if_tx_agch(bitvec * block, int len); +void pcu_l1if_tx_pch(bitvec * block, int len); int pcu_l1if_open(void); void pcu_l1if_close(void);