MAC: correctly decode length of MAC PDU

This commit is contained in:
Harald Welte 2011-04-24 08:07:27 +02:00
parent c547e9f0de
commit 863c31401b
3 changed files with 29 additions and 7 deletions

View File

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <osmocom/core/utils.h>
@ -140,6 +141,28 @@ static int decode_nr_slots(uint8_t in)
return dec_tbl[in & 0xf];
}
#define MACPDU_LEN_2ND_STOLEN -1
#define MACPDU_LEN_START_FRAG -2
static int decode_length(unsigned int length_ind)
{
/* FIXME: Y2/Z2 for non-pi4 DQPSK */
unsigned int y2 = 1, z2 = 1;
if (length_ind == 0 || length_ind == 0x3b || length_ind == 0x3c)
return -EINVAL;
else if (length_ind <= 0x12)
return y2 * length_ind;
else if (length_ind <= 0x3a)
return (18 * y2 + (length_ind - 18) * z2);
else if (length_ind == 0x3e)
return MACPDU_LEN_2ND_STOLEN;
else if (length_ind == 0x3f)
return MACPDU_LEN_START_FRAG;
else
return -EINVAL;
}
/* Section 21.4.3.1 MAC-RESOURCE */
int macpdu_decode_resource(struct tetra_resrc_decoded *rsd, const uint8_t *bits)
{
@ -147,8 +170,7 @@ int macpdu_decode_resource(struct tetra_resrc_decoded *rsd, const uint8_t *bits)
rsd->encryption_mode = bits_to_uint(cur, 2); cur += 2;
rsd->rand_acc_flag = *cur++;
/* FIXME: Y2/... octet calculation */
rsd->length_ind = bits_to_uint(cur, 6); cur += 6;
rsd->macpdu_length = decode_length(bits_to_uint(cur, 6)); cur += 6;
rsd->addr.type = bits_to_uint(cur, 3); cur += 3;
switch (rsd->addr.type) {
case ADDR_TYPE_NULL:

View File

@ -202,7 +202,7 @@ struct tetra_addr {
struct tetra_resrc_decoded {
uint8_t encryption_mode;
uint8_t rand_acc_flag;
uint8_t length_ind;
int macpdu_length;
struct tetra_addr addr;
uint8_t power_control_pres;

View File

@ -114,8 +114,8 @@ static void rx_resrc(struct tetra_tmvsap_prim *tmvp)
memset(&rsd, 0, sizeof(rsd));
tmpdu_offset = macpdu_decode_resource(&rsd, tup->mac_block);
printf("RESOURCE Encr=%u, Length_ind=%u Addr=%s ",
rsd.encryption_mode, rsd.length_ind,
printf("RESOURCE Encr=%u, Length=%d Addr=%s ",
rsd.encryption_mode, rsd.macpdu_length,
tetra_addr_dump(&rsd.addr));
if (rsd.chan_alloc_pres)
@ -125,8 +125,8 @@ static void rx_resrc(struct tetra_tmvsap_prim *tmvp)
printf("SlotGrant=%u/%u\n", rsd.slot_granting.nr_slots,
rsd.slot_granting.delay);
if (rsd.length_ind && rsd.encryption_mode == 0) {
int len_bits = rsd.length_ind*8;
if (rsd.macpdu_length > 0 && rsd.encryption_mode == 0) {
int len_bits = rsd.macpdu_length*8;
if (tup->mac_block + tmpdu_offset + len_bits >
tup->mac_block + tup->mac_block_len)
len_bits = tup->mac_block_len - tmpdu_offset;