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.
This commit is contained in:
Ivan Kluchnikov 2012-06-29 22:53:15 +04:00
parent bbbd79d6f1
commit c7e7f6868b
5 changed files with 68 additions and 1 deletions

View File

@ -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); 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 */ /* 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) 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"); LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP_PDUT_BVC_RESET_ACK\n");
break; break;
case BSSGP_PDUT_PAGING_PS: 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; break;
case BSSGP_PDUT_PAGING_CS: case BSSGP_PDUT_PAGING_CS:
LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP_PDUT_PAGING_CS\n"); LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP_PDUT_PAGING_CS\n");

View File

@ -718,6 +718,35 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, uint
return wp/8; 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) 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 // 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); 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);
}

View File

@ -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_downlink_assignment(gprs_rlcmac_tbf *tbf);
void gprs_rlcmac_packet_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 #endif // GPRS_RLCMAC_H

View File

@ -125,6 +125,17 @@ void pcu_l1if_tx_agch(bitvec * block, int len)
osmo_wqueue_enqueue(&l1fh->udp_wq, msg); 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) int pcu_l1if_rx_pdch(GsmL1_PhDataInd_t *data_ind)
{ {
bitvec *block = bitvec_alloc(data_ind->msgUnitParam.u8Size); bitvec *block = bitvec_alloc(data_ind->msgUnitParam.u8Size);

View File

@ -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, void pcu_l1if_tx_ptcch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn,
uint32_t fn, uint8_t block_nr); uint32_t fn, uint8_t block_nr);
void pcu_l1if_tx_agch(bitvec * block, int len); void pcu_l1if_tx_agch(bitvec * block, int len);
void pcu_l1if_tx_pch(bitvec * block, int len);
int pcu_l1if_open(void); int pcu_l1if_open(void);
void pcu_l1if_close(void); void pcu_l1if_close(void);