Added paging PS support by Ivan Kluchnikov

Original code: c7e7f6868b
(The code was committed earlier, but got lost somehow.)

I added IMSI, so the paging request is sent in correct paging group.
Also I excluded rest octets from pseudo length.

It is tested and it work.
This commit is contained in:
Andreas Eversberg 2012-10-08 12:30:56 +02:00
parent 00950743d7
commit 8c3680dcc9
4 changed files with 82 additions and 3 deletions

View File

@ -247,6 +247,28 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp)
return 0;
}
int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, struct tlv_parsed *tp)
{
char imsi[16];
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");
if (parse_imsi(tp, imsi))
{
LOGP(DBSSGP, LOGL_ERROR, "No IMSI\n");
return -EINVAL;
}
return gprs_rlcmac_paging_request(ptmsi, ptmsi_len, imsi);
}
/* 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)
{
@ -321,7 +343,8 @@ int gprs_bssgp_pcu_rx_sign(struct msgb *msg, struct tlv_parsed *tp, struct bssgp
bvc_timeout(NULL);
break;
case BSSGP_PDUT_PAGING_PS:
LOGP(DBSSGP, LOGL_DEBUG, "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_DEBUG, "rx BSSGP_PDUT_PAGING_CS\n");
@ -390,7 +413,8 @@ int gprs_bssgp_pcu_rcvmsg(struct msgb *msg)
if (!bctx
&& pdu_type != BSSGP_PDUT_BVC_RESET_ACK
&& pdu_type != BSSGP_PDUT_BVC_UNBLOCK_ACK)
&& pdu_type != BSSGP_PDUT_BVC_UNBLOCK_ACK
&& pdu_type != BSSGP_PDUT_PAGING_PS)
{
LOGP(DBSSGP, LOGL_NOTICE, "NSEI=%u/BVCI=%u Rejecting PDU "
"type %u for unknown BVCI\n", msgb_nsei(msg), ns_bvci,

View File

@ -1573,6 +1573,43 @@ void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi,
block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off
}
/* generate paging request */
int write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi_len)
{
unsigned wp = 0;
int plen;
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
}
if ((wp % 8)) {
LOGP(DRLCMACUL, LOGL_ERROR, "Length of PAG.REQ without rest "
"octets is not multiple of 8 bits, PLEASE FIX!\n");
exit (0);
}
plen = wp / 8;
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
return plen;
}
/* generate uplink ack */
void write_packet_uplink_ack(RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *tbf,
uint8_t final)
@ -1700,3 +1737,16 @@ int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf)
return 0;
}
int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
const char *imsi)
{
LOGP(DRLCMAC, LOGL_NOTICE, "TX: [PCU -> BTS] Paging Request (CCCH)\n");
bitvec *paging_request = bitvec_alloc(23);
bitvec_unhex(paging_request, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
int plen = write_paging_request(paging_request, ptmsi, ptmsi_len);
pcu_l1if_tx_pch(paging_request, plen, (char *)imsi);
bitvec_free(paging_request);
return 0;
}

View File

@ -363,6 +363,9 @@ void gprs_rlcmac_trigger_downlink_assignment(struct gprs_rlcmac_tbf *tbf,
int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final,
uint8_t ssn, uint8_t *rbb);
int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
const char *imsi);
unsigned write_packet_paging_request(bitvec * dest);
unsigned write_repeated_page_info(bitvec * dest, unsigned& wp, uint8_t len,

View File

@ -203,7 +203,9 @@ static int pcu_rx_data_cnf(struct gsm_pcu_if_data *data_cnf)
switch (data_cnf->sapi) {
case PCU_IF_SAPI_PCH:
rc = gprs_rlcmac_imm_ass_cnf(data_cnf->data, data_cnf->fn);
if (data_cnf->data[2] == 0x3f)
rc = gprs_rlcmac_imm_ass_cnf(data_cnf->data,
data_cnf->fn);
break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with "