int pack_position_data_normal(position_data_normal* data, uint64_t** out, size_t* count) { *out = (uint64_t*)malloc(sizeof(uint64_t*) * 5); *count = 5; (*out)[0] = bit_pack(3, 16, data->lateral_pos[0], 16, data->lateral_pos[1], 16, data->lateral_pos[2]); (*out)[1] = bit_pack(3, 16, data->lateral_pos[3], 16, data->lateral_pos[4], 16, data->lateral_pos[5]); (*out)[2] = bit_pack(3, 16, data->time_stamp[1], 16, data->time_stamp[2], 16, data->time_stamp[3]); (*out)[3] = bit_pack(3, 16, data->time_stamp[3], 16, data->time_stamp[4], 16, data->time_stamp[5]); (*out)[4] = bit_pack(8, 4, data->track_number[0], 4, data->track_number[1], 4, data->track_number[2], 16, data->estimated_speed, 16, data->real_speed, 1, data->missing_magnet_flag[0], 1, data->missing_magnet_flag[1], 1, data->missing_magnet_flag[2]); return 0; }
/** Unpacks MIB from PBCH message. * msg buffer must be 24 byte length at least */ void pbch_mib_pack(pbch_mib_t *mib, char *msg) { int bw, phich_res = 0; bzero(msg, 24); if (mib->nof_prb <= 6) { bw = 0; } else if (mib->nof_prb <= 15) { bw = 1; } else { bw = 1 + mib->nof_prb / 25; } bit_pack(bw, &msg, 3); *msg = mib->phich_length == PHICH_EXT; msg++; switch (mib->phich_resources) { case R_1_6: phich_res = 0; break; case R_1_2: phich_res = 1; break; case R_1: phich_res = 2; break; case R_2: phich_res = 3; break; } bit_pack(phich_res, &msg, 2); bit_pack(mib->sfn >> 2, &msg, 8); }
/* Format 1C for compact scheduling of PDSCH words * */ int dci_format1Cs_pack(ra_pdsch_t *data, dci_msg_t *msg, int nof_prb) { /* pack bits */ char *y = msg->data; if (data->alloc_type != alloc_type2 || data->type2_alloc.mode != t2_dist) { fprintf(stderr, "Format 1C accepts distributed type2 resource allocation only\n"); return -1; } if (nof_prb >= 50) { *y++ = data->type2_alloc.n_gap; } int n_step = ra_type2_n_rb_step(nof_prb); int n_vrb_dl = ra_type2_n_vrb_dl(nof_prb, data->type2_alloc.n_gap == t2_ng1); if (data->type2_alloc.L_crb > ((int) n_vrb_dl / n_step) * n_step) { fprintf(stderr, "L_CRB=%d can not exceed N_vrb_dl=%d for distributed type2\n", data->type2_alloc.L_crb, ((int) n_vrb_dl / n_step) * n_step); return -1; } if (data->type2_alloc.L_crb % n_step) { fprintf(stderr, "L_crb must be multiple of n_step\n"); return -1; } if (data->type2_alloc.RB_start % n_step) { fprintf(stderr, "RB_start must be multiple of n_step\n"); return -1; } int L_p = data->type2_alloc.L_crb / n_step; int RB_p = data->type2_alloc.RB_start / n_step; int n_vrb_p = (int) n_vrb_dl / n_step; uint32_t riv; if (data->type2_alloc.L_crb) { riv = ra_type2_to_riv(L_p, RB_p, n_vrb_p); } else { riv = data->type2_alloc.riv; } bit_pack(riv, &y, riv_nbits((int) n_vrb_dl / n_step)); // in format1C, MCS = TBS according to 7.1.7.2 of 36.213 uint32_t mcs; if (data->mcs.mod == MOD_NULL) { mcs = data->mcs.mcs_idx; } else { if (data->mcs.tbs) { data->mcs.tbs_idx = ra_tbs_to_table_idx_format1c(data->mcs.tbs); } mcs = data->mcs.tbs_idx; } bit_pack(mcs, &y, 5); msg->location.nof_bits = (y - msg->data); return 0; }
static int int_2_bits(uint32_t* src, uint8_t* dst, int nbits) { int n; n=nbits/32; for (int i=0;i<n;i++) { bit_pack(src[i],&dst,32); } bit_pack(src[n],&dst,nbits-n*32); return n; }
void LLVLManager::unpackData(const S32 num_packets) { static LLFrameTimer decode_timer; S32 i; for (i = 0; i < mPacketData.count(); i++) { LLVLData *datap = mPacketData[i]; LLBitPack bit_pack(datap->mData, datap->mSize); LLGroupHeader goph; decode_patch_group_header(bit_pack, &goph); if (LAND_LAYER_CODE == datap->mType) { datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, FALSE); } else if (WIND_LAYER_CODE == datap->mType) { datap->mRegionp->mWind.decompress(bit_pack, &goph); } else if (CLOUD_LAYER_CODE == datap->mType) { datap->mRegionp->mCloudLayer.decompress(bit_pack, &goph); } } for (i = 0; i < mPacketData.count(); i++) { delete mPacketData[i]; } mPacketData.reset(); }
int pack_data_inputs(data_inputs* data, uint64_t* out) { *out = bit_pack(2, 32, data->vehicle_speed, 32, data->magnet_information); return 0; }
int pack_system_command(system_command* data, uint64_t* out) { *out = bit_pack(2, 8, data->command, 8, data->target); return 0; }
int pack_HMI_device_state(HMI_device_state* data, uint64_t* out) { *out = bit_pack(2, 8, data->state, 12, data->devices); return 0; }
int pack_control_computer_status(control_computer_status* data, uint64_t* out) { *out = bit_pack(2, 8, data->id, 8, data->status); return 0; }
int pack_sensor_config(sensor_config* data, uint64_t* out) { *out = bit_pack(3, 8, data->serial, 8, data->type, 8, data->configuration); return 0; }
int pack_HMI_state(HMI_state* data, uint64_t* out) { *out = bit_pack(4, 16, data->id, 5, data->operation_state, 4, data->heartbeat, 8, data->fault_message); return 0; }
int pack_CC_operation_state(CC_operation_state* data, uint64_t* out) { *out = bit_pack(4, 4, data->controller_state, 4, data->transition_state, 4, data->coordination_state, 4, data->reserved_state); return 0; }
int pack_CC_state(CC_state* data, uint64_t* out) { *out = bit_pack(4, 8, data->id, 4, data->state, 4, data->heartbeat, 24, data->fault_message); return 0; }
int pack_position_data_raw(position_data_raw* data, uint64_t** out, size_t* count) { size_t i; *out = (uint64_t*)malloc(sizeof(uint64_t*) * 11); *count = 11; for (i = 0; i < 10; ++i) { (*out)[i] = bit_pack(3, 20, data->magnetic_strengths[i * 3], 20, data->magnetic_strengths[i * 3 + 1], 20, data->magnetic_strengths[i * 3 + 2]); } (*out)[10] = bit_pack(1, 20, data->vehicle_speed); return 0; }
int pack_sensor_state(sensor_state* data, uint64_t* out) { *out = bit_pack(6, 5, data->operation_code, 8, data->fault_message, 10, data->sensor_health[0], 10, data->sensor_health[1], 10, data->sensor_health[2], 5, data->output_type); return 0; }
void LLVLManager::unpackData(const S32 num_packets) { static LLFrameTimer decode_timer; S32 i; for (i = 0; i < mPacketData.size(); i++) { LLVLData *datap = mPacketData[i]; LLBitPack bit_pack(datap->mData, datap->mSize); LLGroupHeader goph; decode_patch_group_header(bit_pack, &goph); if (LAND_LAYER_CODE == datap->mType) { datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, FALSE); } // <FS:CR> Aurora Sim else if (AURORA_LAND_LAYER_CODE == datap->mType) { datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, TRUE); } //else if (WIND_LAYER_CODE == datap->mType) else if (WIND_LAYER_CODE == datap->mType || AURORA_WIND_LAYER_CODE == datap->mType) // </FS:CR> Aurora Sim { datap->mRegionp->mWind.decompress(bit_pack, &goph); } // <FS:CR> Aurora Sim //else if (CLOUD_LAYER_CODE == datap->mType) else if (CLOUD_LAYER_CODE == datap->mType || AURORA_CLOUD_LAYER_CODE == datap->mType) { } else if (WATER_LAYER_CODE == datap->mType || AURORA_WATER_LAYER_CODE == datap->mType) { // </FS:CR> Aurora Sim } } for (i = 0; i < mPacketData.size(); i++) { delete mPacketData[i]; } mPacketData.clear(); }
int pack_position_data_calibration(position_data_calibration* data, uint64_t** out, size_t* count) { size_t i; *out = (uint64_t*)malloc(sizeof(uint64_t*) * 10); *count = 10; for (i = 0; i < 10; ++i) { (*out)[i] = bit_pack(3, 20, data->magnetic_strengths[i * 3], 20, data->magnetic_strengths[i * 3 + 1], 20, data->magnetic_strengths[i * 3 + 2]); } return 0; }
void LLVLManager::unpackData(const S32 num_packets) { static LLFrameTimer decode_timer; U32 i; for (i = 0; i < mPacketData.size(); i++) { LLVLData *datap = mPacketData[i]; LLBitPack bit_pack(datap->mData, datap->mSize); LLGroupHeader goph; decode_patch_group_header(bit_pack, &goph); if (LAND_LAYER_CODE == datap->mType) { datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, FALSE); } else if (WHITECORE_LAND_LAYER_CODE == datap->mType) { datap->mRegionp->getLand().decompressDCTPatch(bit_pack, &goph, TRUE); } else if (WIND_LAYER_CODE == datap->mType || WHITECORE_WIND_LAYER_CODE == datap->mType) { datap->mRegionp->mWind.decompress(bit_pack, &goph); } else if (CLOUD_LAYER_CODE == datap->mType || WHITECORE_CLOUD_LAYER_CODE == datap->mType) { #if ENABLE_CLASSIC_CLOUDS datap->mRegionp->mCloudLayer.decompress(bit_pack, &goph); #endif } } for (i = 0; i < mPacketData.size(); i++) { delete mPacketData[i]; } mPacketData.clear(); }
/* Unpacks DCI format 1A for compact scheduling of PDSCH words according to 36.212 5.3.3.1.3 * */ int dci_format1As_unpack(dci_msg_t *msg, ra_pdsch_t *data, int nof_prb, bool crc_is_crnti) { /* pack bits */ char *y = msg->data; /* Make sure it's a Format0 message */ if (msg->location.nof_bits != dci_format_sizeof(Format1A, nof_prb)) { fprintf(stderr, "Invalid message length for format 1A\n"); return -1; } if (*y++ != 1) { fprintf(stderr, "Invalid format differentiation field value. This is Format0\n"); return -1; } data->alloc_type = alloc_type2; data->type2_alloc.mode = *y++; // by default, set N_gap to 1 data->type2_alloc.n_gap = t2_ng1; /* unpack RIV according to 7.1.6.3 of 36.213 */ int nb_gap = 0; if (crc_is_crnti && data->type2_alloc.mode == t2_dist && nof_prb >= 50) { nb_gap = 1; data->type2_alloc.n_gap = *y++; } int nof_vrb; if (data->type2_alloc.mode == t2_loc) { nof_vrb = nof_prb; } else { nof_vrb = ra_type2_n_vrb_dl(nof_prb, data->type2_alloc.n_gap == t2_ng1); } uint32_t riv = bit_unpack(&y, riv_nbits(nof_prb) - nb_gap); ra_type2_from_riv(riv, &data->type2_alloc.L_crb, &data->type2_alloc.RB_start, nof_prb, nof_vrb); data->type2_alloc.riv = riv; // unpack MCS data->mcs.mcs_idx = bit_unpack(&y, 5); data->harq_process = bit_unpack(&y, 3); if (!crc_is_crnti && nof_prb >= 50 && data->type2_alloc.mode == t2_dist) { data->type2_alloc.n_gap = *y++; } else { y++; // bit reserved } // rv version bit_pack(data->rv_idx, &y, 2); if (crc_is_crnti) { // TPC not implemented y++; y++; } else { y++; // MSB of TPC is reserved data->type2_alloc.n_prb1a = *y++; // LSB indicates N_prb_1a for TBS } data->mcs.tbs_idx = data->mcs.mcs_idx; int n_prb; if (crc_is_crnti) { n_prb = ra_nprb_dl(data, nof_prb); } else { n_prb = data->type2_alloc.n_prb1a == nprb1a_2 ? 2 : 3; } data->mcs.tbs = ra_tbs_from_idx(data->mcs.tbs_idx, n_prb); data->mcs.mod = QPSK; return 0; }
/* Unpacks DCI format 0 data and store result in msg according * to 36.212 5.3.3.1.1 * * TODO: TPC and cyclic shift for DM RS not implemented */ int dci_format0_unpack(dci_msg_t *msg, ra_pusch_t *data, int nof_prb) { /* pack bits */ char *y = msg->data; int n_ul_hop; /* Make sure it's a Format0 message */ if (msg->location.nof_bits != dci_format_sizeof(Format0, nof_prb)) { fprintf(stderr, "Invalid message length for format 0\n"); return -1; } if (*y++ != 0) { fprintf(stderr, "Invalid format differentiation field value. This is Format1A\n"); return -1; } if (*y++ == 0) { data->freq_hop_fl = hop_disabled; n_ul_hop = 0; } else { if (nof_prb < 50) { n_ul_hop = 1; // Table 8.4-1 of 36.213 data->freq_hop_fl = *y++; } else { n_ul_hop = 2; // Table 8.4-1 of 36.213 data->freq_hop_fl = y[0] << 1 | y[1]; y += 2; } } /* unpack RIV according to 8.1 of 36.213 */ uint32_t riv = bit_unpack(&y, riv_nbits(nof_prb) - n_ul_hop); ra_type2_from_riv(riv, &data->type2_alloc.L_crb, &data->type2_alloc.RB_start, nof_prb, nof_prb); bit_pack(riv, &y, riv_nbits(nof_prb) - n_ul_hop); data->type2_alloc.riv = riv; /* unpack MCS according to 8.6 of 36.213 */ uint32_t mcs = bit_unpack(&y, 5); data->ndi = *y++ ? true : false; // TCP and DM RS commands not implemented y += 5; // CQI request data->cqi_request = *y++ ? true : false; // 8.6.2 First paragraph if (mcs <= 28) { ra_mcs_from_idx_ul(mcs, &data->mcs); data->mcs.tbs = ra_tbs_from_idx(data->mcs.tbs_idx, ra_nprb_ul(data, nof_prb)); } // 8.6.1 and 8.6.2 36.213 second paragraph if (mcs == 29 && data->cqi_request && ra_nprb_ul(data, nof_prb) <= 4) { data->mcs.mod = QPSK; } if (mcs > 29) { // Else leave MOD_NULL and use the previously used PUSCH modulation data->mcs.mod = MOD_NULL; data->rv_idx = mcs - 28; } return 0; }
int pack_message_status(message_status* data, uint64_t* out) { *out = bit_pack(1, 8, data->heartbeat); return 0; }
int pack_CC_optional_data(CC_optional_data* data, uint64_t* out) { *out = bit_pack(1, 16, data->steering_command); return 0; }
/* Packs DCI format 1A for compact scheduling of PDSCH words according to 36.212 5.3.3.1.3 * * TODO: RA procedure initiated by PDCCH, TPC commands */ int dci_format1As_pack(ra_pdsch_t *data, dci_msg_t *msg, int nof_prb, bool crc_is_crnti) { /* pack bits */ char *y = msg->data; *y++ = 1; // format differentiation if (data->alloc_type != alloc_type2) { fprintf(stderr, "Format 1A accepts type2 resource allocation only\n"); return -1; } *y++ = data->type2_alloc.mode; // localized or distributed VRB assignment if (data->type2_alloc.mode == t2_loc) { if (data->type2_alloc.L_crb > nof_prb) { fprintf(stderr, "L_CRB=%d can not exceed system BW for localized type2\n", data->type2_alloc.L_crb); return -1; } } else { int n_vrb_dl; if (crc_is_crnti && nof_prb > 50) { n_vrb_dl = 16; } else { n_vrb_dl = ra_type2_n_vrb_dl(nof_prb, data->type2_alloc.n_gap == t2_ng1); } if (data->type2_alloc.L_crb > n_vrb_dl) { fprintf(stderr, "L_CRB=%d can not exceed N_vrb_dl=%d for distributed type2\n", data->type2_alloc.L_crb, n_vrb_dl); return -1; } } /* pack RIV according to 7.1.6.3 of 36.213 */ uint32_t riv; if (data->type2_alloc.L_crb) { riv = ra_type2_to_riv(data->type2_alloc.L_crb, data->type2_alloc.RB_start, nof_prb); } else { riv = data->type2_alloc.riv; } int nb_gap = 0; if (crc_is_crnti && data->type2_alloc.mode == t2_dist && nof_prb >= 50) { nb_gap = 1; *y++ = data->type2_alloc.n_gap; } bit_pack(riv, &y, riv_nbits(nof_prb) - nb_gap); // in format1A, MCS = TBS according to 7.1.7.2 of 36.213 uint32_t mcs; if (data->mcs.mod == MOD_NULL) { mcs = data->mcs.mcs_idx; } else { if (data->mcs.tbs) { // In format 1A, n_prb_1a is 2 or 3 if crc is not scrambled with C-RNTI int n_prb; if (!crc_is_crnti) { n_prb = ra_nprb_dl(data, nof_prb); } else { n_prb = data->type2_alloc.n_prb1a == nprb1a_2 ? 2 : 3; } data->mcs.tbs_idx = ra_tbs_to_table_idx(data->mcs.tbs, n_prb); } mcs = data->mcs.tbs_idx; } bit_pack(mcs, &y, 5); bit_pack(data->harq_process, &y, 3); if (!crc_is_crnti && nof_prb >= 50 && data->type2_alloc.mode == t2_dist) { *y++ = data->type2_alloc.n_gap; } else { y++; // bit reserved } // rv version bit_pack(data->rv_idx, &y, 2); if (crc_is_crnti) { // TPC not implemented *y++ = 0; *y++ = 0; } else { y++; // MSB of TPC is reserved *y++ = data->type2_alloc.n_prb1a; // LSB indicates N_prb_1a for TBS } // Padding with zeros int n = dci_format1A_sizeof(nof_prb); while (y - msg->data < n) { *y++ = 0; } msg->location.nof_bits = (y - msg->data); return 0; }
/* Packs DCI format 0 data to a sequence of bits and store them in msg according * to 36.212 5.3.3.1.1 * * TODO: TPC and cyclic shift for DM RS not implemented */ int dci_format0_pack(ra_pusch_t *data, dci_msg_t *msg, int nof_prb) { /* pack bits */ char *y = msg->data; int n_ul_hop; *y++ = 0; // format differentiation if (data->freq_hop_fl == hop_disabled) { // frequency hopping *y++ = 0; n_ul_hop = 0; } else { *y++ = 1; if (nof_prb < 50) { n_ul_hop = 1; // Table 8.4-1 of 36.213 *y++ = data->freq_hop_fl & 1; } else { n_ul_hop = 2; // Table 8.4-1 of 36.213 *y++ = (data->freq_hop_fl & 2) >> 1; *y++ = data->freq_hop_fl & 1; } } /* pack RIV according to 8.1 of 36.213 */ uint32_t riv; if (data->type2_alloc.L_crb) { riv = ra_type2_to_riv(data->type2_alloc.L_crb, data->type2_alloc.RB_start, nof_prb); } else { riv = data->type2_alloc.riv; } bit_pack(riv, &y, riv_nbits(nof_prb) - n_ul_hop); /* pack MCS according to 8.6.1 of 36.213 */ uint32_t mcs; if (data->cqi_request) { mcs = 29; } else { if (data->rv_idx) { mcs = 28 + data->rv_idx; } else { if (data->mcs.mod == MOD_NULL) { mcs = data->mcs.mcs_idx; } else { if (data->mcs.tbs) { if (data->mcs.tbs) { data->mcs.tbs_idx = ra_tbs_to_table_idx(data->mcs.tbs, ra_nprb_ul(data, nof_prb)); } } mcs = ra_mcs_to_table_idx(&data->mcs); } } } bit_pack(mcs, &y, 5); *y++ = data->ndi; // TCP commands not implemented *y++ = 0; *y++ = 0; // DM RS not implemented *y++ = 0; *y++ = 0; *y++ = 0; // CQI request *y++ = data->cqi_request; // Padding with zeros int n = dci_format0_sizeof(nof_prb); while (y - msg->data < n) { *y++ = 0; } msg->location.nof_bits = (y - msg->data); return 0; }
int dci_format1_pack(ra_pdsch_t *data, dci_msg_t *msg, int nof_prb) { /* pack bits */ char *y = msg->data; if (nof_prb > 10) { *y++ = data->alloc_type; } /* Resource allocation: type0 or type 1 */ int P = ra_type0_P(nof_prb); int alloc_size = (int) ceilf((float) nof_prb / P); switch (data->alloc_type) { case alloc_type0: bit_pack(data->type0_alloc.rbg_bitmask, &y, alloc_size); break; case alloc_type1: bit_pack(data->type1_alloc.rbg_subset, &y, (int) ceilf(log2f(P))); *y++ = data->type1_alloc.shift ? 1 : 0; bit_pack(data->type1_alloc.vrb_bitmask, &y, alloc_size - (int) ceilf(log2f(P)) - 1); break; default: fprintf(stderr, "Format 1 accepts type0 or type1 resource allocation only\n"); return -1; } /* pack MCS according to 7.1.7 of 36.213 */ uint32_t mcs; if (data->mcs.mod == MOD_NULL) { mcs = data->mcs.mcs_idx; } else { if (data->mcs.tbs) { data->mcs.tbs_idx = ra_tbs_to_table_idx(data->mcs.tbs, ra_nprb_dl(data, nof_prb)); } mcs = ra_mcs_to_table_idx(&data->mcs); } bit_pack(mcs, &y, 5); /* harq process number */ bit_pack(data->harq_process, &y, 3); *y++ = data->ndi; // rv version bit_pack(data->rv_idx, &y, 2); // TPC not implemented *y++ = 0; *y++ = 0; // Padding with zeros int n = dci_format1_sizeof(nof_prb); while (y - msg->data < n) { *y++ = 0; } msg->location.nof_bits = (y - msg->data); return 0; }
int pack_HMI_optional_data(HMI_optional_data* data, uint64_t* out) { *out = bit_pack(1, 24, data->recommended_action); return 0; }
int main(int argc, char **argv) { dci_msg_t msg; ra_pdsch_t ra_dl; int len, rlen; int nof_prb; int nwords; int i; char *y; if (argc < 3) { usage(argv[0]); exit(-1); } nof_prb = atoi(argv[1]); len = atoi(argv[2]); nwords = (len - 1) / 32 + 1; if (argc < 3 + nwords) { usage(argv[0]); exit(-1); } y = msg.data; rlen = 0; unsigned int x; for (i = 0; i < nwords; i++) { x = strtoul(argv[i + 3], NULL, 16); if (len - rlen < 32) { bit_pack(x, &y, len - rlen); } else { bit_pack(x, &y, 32); } } printf("DCI message len %d:\n", len); for (i = 0; i < len; i++) { printf("%d, ", msg.data[i]); } printf("\n"); dci_msg_type_t dci_type; msg.nof_bits = len; if (dci_msg_get_type(&msg, &dci_type, nof_prb, SIRNTI, 1234)) { fprintf(stderr, "Can't obtain DCI message type\n"); exit(-1); } printf("\n"); printf("Message type:"); dci_msg_type_fprint(stdout, dci_type); switch (dci_type.type) { case PDSCH_SCHED: bzero(&ra_dl, sizeof(ra_pdsch_t)); dci_msg_unpack_pdsch(&msg, &ra_dl, nof_prb, false); ra_pdsch_fprint(stdout, &ra_dl, nof_prb); break; default: printf("Error expected PDSCH\n"); exit(-1); } printf("\n"); }