aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Kluchnikov <kluchnikovi@gmail.com>2012-06-29 22:53:15 +0400
committerIvan Kluchnikov <kluchnikovi@gmail.com>2012-06-29 22:53:15 +0400
commitc7e7f6868b6f24346424dee904f4e76d3f216ff4 (patch)
tree9c6d6fc6dea16ae7e72154d34a7bbc7ed7a53ea8
parentbbbd79d6f1abd4e7f865f72c15878e0f32f252c3 (diff)
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.
-rw-r--r--src/gprs_bssgp_pcu.cpp17
-rw-r--r--src/gprs_rlcmac.cpp38
-rw-r--r--src/gprs_rlcmac.h2
-rw-r--r--src/pcu_l1_if.cpp11
-rw-r--r--src/pcu_l1_if.h1
5 files changed, 68 insertions, 1 deletions
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);