aboutsummaryrefslogtreecommitdiffstats
path: root/src/gprs_rlcmac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gprs_rlcmac.cpp')
-rw-r--r--src/gprs_rlcmac.cpp150
1 files changed, 82 insertions, 68 deletions
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp
index 7d28de12..9d2601c8 100644
--- a/src/gprs_rlcmac.cpp
+++ b/src/gprs_rlcmac.cpp
@@ -21,7 +21,6 @@
#include <gprs_bssgp_pcu.h>
#include <pcu_l1_if.h>
#include <gprs_rlcmac.h>
-#include <gsmL1prim.h>
LLIST_HEAD(gprs_rlcmac_tbfs);
void *rlcmac_tall_ctx;
@@ -247,7 +246,7 @@ static void tbf_gsm_timer_cb(void *_tbf)
switch (tbf->fT) {
case 0:
-hier alles überdenken
+hier alles berdenken
// This is timer for delay RLC/MAC data sending after Downlink Immediate Assignment on CCCH.
gprs_rlcmac_segment_llc_pdu(tbf);
LOGP(DRLCMAC, LOGL_NOTICE, "TBF: [DOWNLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
@@ -485,66 +484,79 @@ void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi,
// bitvec_write_field(dest, wp,0x0,1); // Measurement Mapping struct not present
}
+
/* generate downlink assignment */
-void write_packet_downlink_assignment(bitvec * dest, uint8_t old_tfi,
+void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi,
uint8_t old_downlink, uint8_t new_tfi, uint16_t arfcn,
uint8_t tn, uint8_t ta, uint8_t tsc, uint8_t poll)
{
- // TODO We should use our implementation of encode RLC/MAC Control messages.
- unsigned wp = 0;
+ // Packet downlink assignment TS 44.060 11.2.7
+
int i;
- bitvec_write_field(dest, wp,0x1,2); // Payload Type
- bitvec_write_field(dest, wp,0x0,2); // Uplink block with TDMA framenumber (FN+13)
- bitvec_write_field(dest, wp,poll,1); // Suppl/Polling Bit
- bitvec_write_field(dest, wp,0x0,3); // Uplink state flag
- bitvec_write_field(dest, wp,0x2,6); // MESSAGE TYPE
- bitvec_write_field(dest, wp,0x0,2); // Page Mode
- bitvec_write_field(dest, wp,0x0,1); // switch PERSIST_LEVEL: off
- bitvec_write_field(dest, wp,0x0,1); // switch TFI : on
- bitvec_write_field(dest, wp,old_downlink,1); // 0=UPLINK TFI, 1=DL TFI
- bitvec_write_field(dest, wp,old_tfi,5); // TFI
+ block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header
+ block->RRBP = 0x0; // N+13
+ block->SP = poll; // RRBP field is valid
+ block->USF = 0x0; // Uplink state flag
- bitvec_write_field(dest, wp,0x0,1); // Message escape
- bitvec_write_field(dest, wp,0x0,2); // Medium Access Method: Dynamic Allocation
- bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode
+ block->u.Packet_Downlink_Assignment.MESSAGE_TYPE = 0x2; // Packet Downlink Assignment
+ block->u.Packet_Downlink_Assignment.PAGE_MODE = 0x0; // Normal Paging
- bitvec_write_field(dest, wp,old_downlink,1); // the network establishes no new downlink TBF for the mobile station
- bitvec_write_field(dest, wp,0x80 >> tn,8); // timeslot(s)
+ block->u.Packet_Downlink_Assignment.Exist_PERSISTENCE_LEVEL = 0x0; // PERSISTENCE_LEVEL: off
- bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_VALUE = on
- bitvec_write_field(dest, wp,ta,6); // TIMING_ADVANCE_VALUE
- bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off
+ block->u.Packet_Downlink_Assignment.ID.UnionType = 0x0; // TFI = on
+ block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.UnionType = old_downlink; // 0=UPLINK TFI, 1=DL TFI
+ block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.u.UPLINK_TFI = old_tfi; // TFI
- bitvec_write_field(dest, wp,0x0,1); // switch POWER CONTROL = off
- bitvec_write_field(dest, wp,0x1,1); // Frequency Parameters information elements = present
+ block->u.Packet_Downlink_Assignment.MAC_MODE = 0x0; // Dynamic Allocation
+ block->u.Packet_Downlink_Assignment.RLC_MODE = 0x0; // RLC acknowledged mode
+ block->u.Packet_Downlink_Assignment.CONTROL_ACK = old_downlink; // NW establishes no new DL TBF for the MS with running timer T3192
+ block->u.Packet_Downlink_Assignment.TIMESLOT_ALLOCATION = 0x80 >> tn; // timeslot(s)
- bitvec_write_field(dest, wp,tsc,3); // Training Sequence Code (TSC) = 2
- bitvec_write_field(dest, wp,0x0,2); // ARFCN = present
- bitvec_write_field(dest, wp,arfcn,10); // ARFCN
+ block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_TIMING_ADVANCE_VALUE = 0x1; // TIMING_ADVANCE_VALUE = on
+ block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.TIMING_ADVANCE_VALUE = ta; // TIMING_ADVANCE_VALUE
+ block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_IndexAndtimeSlot = 0x0; // TIMING_ADVANCE_INDEX = off
- bitvec_write_field(dest, wp,0x1,1); // switch TFI : on
- bitvec_write_field(dest, wp,new_tfi,5);// TFI
+ block->u.Packet_Downlink_Assignment.Exist_P0_and_BTS_PWR_CTRL_MODE = 0x0; // POWER CONTROL = off
+
+ block->u.Packet_Downlink_Assignment.Exist_Frequency_Parameters = 0x1; // Frequency Parameters = on
+ block->u.Packet_Downlink_Assignment.Frequency_Parameters.TSC = tsc; // Training Sequence Code (TSC)
+ block->u.Packet_Downlink_Assignment.Frequency_Parameters.UnionType = 0x0; // ARFCN = on
+ block->u.Packet_Downlink_Assignment.Frequency_Parameters.u.ARFCN = arfcn; // ARFCN
+
+ block->u.Packet_Downlink_Assignment.Exist_DOWNLINK_TFI_ASSIGNMENT = 0x1; // DOWNLINK TFI ASSIGNMENT = on
+ block->u.Packet_Downlink_Assignment.DOWNLINK_TFI_ASSIGNMENT = new_tfi; // TFI
+
+ block->u.Packet_Downlink_Assignment.Exist_Power_Control_Parameters = 0x1; // Power Control Parameters = on
+ block->u.Packet_Downlink_Assignment.Power_Control_Parameters.ALPHA = 0x0; // ALPHA
- bitvec_write_field(dest, wp,0x1,1); // Power Control Parameters IE = present
- bitvec_write_field(dest, wp,0x0,4); // ALPHA power control parameter
for (i = 0; i < 8; i++)
- bitvec_write_field(dest, wp,(tn == i),1); // switch GAMMA_TN[i] = on or off
- bitvec_write_field(dest, wp,0x0,5); // GAMMA_TN[tn]
+ {
+ if (tn == i)
+ {
+ block->u.Packet_Downlink_Assignment.Power_Control_Parameters.Slot[i].Exist = 0x1; // Slot[i] = on
+ block->u.Packet_Downlink_Assignment.Power_Control_Parameters.Slot[i].GAMMA_TN = 0x0; // GAMMA_TN
+ }
+ else
+ {
+ block->u.Packet_Downlink_Assignment.Power_Control_Parameters.Slot[i].Exist = 0x0; // Slot[i] = off
+ }
+ }
- bitvec_write_field(dest, wp,0x0,1); // TBF Starting TIME IE not present
- bitvec_write_field(dest, wp,0x0,1); // Measurement Mapping struct not present
- bitvec_write_field(dest, wp,0x0,1);
+ block->u.Packet_Downlink_Assignment.Exist_TBF_Starting_Time = 0x0; // TBF Starting TIME = off
+ block->u.Packet_Downlink_Assignment.Exist_Measurement_Mapping = 0x0; // Measurement_Mapping = off
+ block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off
}
/* generate uplink ack */
-void write_packet_uplink_ack(bitvec * dest, struct gprs_rlcmac_tbf *tbf,
+void write_packet_uplink_ack(RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *tbf,
uint8_t final)
{
+ // Packet Uplink Ack/Nack TS 44.060 11.2.28
+
char show_v_n[65];
- // TODO We should use our implementation of encode RLC/MAC Control messages.
- unsigned wp = 0;
+ uint8_t rbb = 0;
uint16_t i, bbn;
uint16_t mod_sns_half = (tbf->sns >> 1) - 1;
char bit;
@@ -552,30 +564,19 @@ void write_packet_uplink_ack(bitvec * dest, struct gprs_rlcmac_tbf *tbf,
LOGP(DRLCMACUL, LOGL_DEBUG, "Sending Ack/Nack for TBF=%d "
"(final=%d)\n", tbf->tfi, final);
- bitvec_write_field(dest, wp,0x1,2); // payload
- bitvec_write_field(dest, wp,0x0,2); // Uplink block with TDMA framenumber (N+13)
- bitvec_write_field(dest, wp,final,1); // Suppl/Polling Bit
- bitvec_write_field(dest, wp,0x0,3); // Uplink state flag
-
- //bitvec_write_field(dest, wp,0x0,1); // Reduced block sequence number
- //bitvec_write_field(dest, wp,BSN+6,5); // Radio transaction identifier
- //bitvec_write_field(dest, wp,0x1,1); // Final segment
- //bitvec_write_field(dest, wp,0x1,1); // Address control
+ block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header
+ block->RRBP = 0x0; // N+13
+ block->SP = final; // RRBP field is valid, if it is final ack
+ block->USF = 0x0; // Uplink state flag
- //bitvec_write_field(dest, wp,0x0,2); // Power reduction: 0
- //bitvec_write_field(dest, wp,TFI,5); // Temporary flow identifier
- //bitvec_write_field(dest, wp,0x1,1); // Direction
+ block->u.Packet_Uplink_Ack_Nack.MESSAGE_TYPE = 0x9; // Packet Downlink Assignment
+ block->u.Packet_Uplink_Ack_Nack.PAGE_MODE = 0x0; // Normal Paging
+ block->u.Packet_Uplink_Ack_Nack.UPLINK_TFI = tbf->tfi; // Uplink TFI
- bitvec_write_field(dest, wp,0x09,6); // MESSAGE TYPE
- bitvec_write_field(dest, wp,0x0,2); // Page Mode
-
- bitvec_write_field(dest, wp,0x0,2);
- bitvec_write_field(dest, wp,tbf->tfi,5); // Uplink TFI
- bitvec_write_field(dest, wp,0x0,1);
-
- bitvec_write_field(dest, wp,0x0,2); // CS1
- bitvec_write_field(dest, wp,final,1); // FINAL_ACK_INDICATION
- bitvec_write_field(dest, wp,tbf->dir.ul.v_r,7); // STARTING_SEQUENCE_NUMBER
+ block->u.Packet_Uplink_Ack_Nack.UnionType = 0x0; // PU_AckNack_GPRS = on
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.CHANNEL_CODING_COMMAND = 0x0; // CS1
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.FINAL_ACK_INDICATION = final; // FINAL ACK INDICATION
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->dir.ul.v_r; // STARTING_SEQUENCE_NUMBER
// RECEIVE_BLOCK_BITMAP
for (i = 0, bbn = (tbf->dir.ul.v_r - 64) & mod_sns_half; i < 64;
i++, bbn = (bbn + 1) & mod_sns_half) {
@@ -583,15 +584,29 @@ void write_packet_uplink_ack(bitvec * dest, struct gprs_rlcmac_tbf *tbf,
if (bit == 0)
bit = ' ';
show_v_n[i] = bit;
- bitvec_write_field(dest, wp,(bit == 'R'),1);
+ if (bit == 'R')
+ rbb = (rbb << 1)|1;
+ else
+ rbb = (rbb << 1);
+ if((i%8) == 7)
+ {
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP[i/8] = rbb;
+ rbb = 0;
+ }
}
show_v_n[64] = '\0';
LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received "
"N=Not-Received\n", show_v_n);
- bitvec_write_field(dest, wp,0x1,1); // CONTENTION_RESOLUTION_TLLI = present
- bitvec_write_field(dest, wp,tbf->tlli,8*4);
- bitvec_write_field(dest, wp,0x00,4); //spare
- bitvec_write_field(dest, wp,0x5,4); //0101
+
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.UnionType = 0x0; // Fixed Allocation Dummy = on
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.u.FixedAllocationDummy = 0x0; // Fixed Allocation Dummy
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off
+
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_CONTENTION_RESOLUTION_TLLI = 0x1;
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.CONTENTION_RESOLUTION_TLLI = tbf->tlli;
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_Packet_Timing_Advance = 0x0;
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_Extension_Bits = 0x0;
+ block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Common_Uplink_Ack_Nack_Data.Exist_Power_Control_Parameters = 0x0;
}
/* Send Uplink unit-data to SGSN. */
@@ -613,4 +628,3 @@ int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf)
return 0;
}
-