Example #1
0
bptc_196_96_data_bits_t *dmrpacket_csbk_construct(dmrpacket_csbk_t *csbk) {
	static bptc_196_96_data_bits_t data_bits;
	uint8_t data_bytes[sizeof(bptc_196_96_data_bits_t)/8] = {0,};
	uint16_t calculated_crc = 0;
	uint8_t i;

	data_bytes[0] = (csbk->last_block & 0x01) << 7;

	switch (csbk->csbko) {
		case DMRPACKET_CSBKO_BS_OUTBOUND_ACTIVATION:
			data_bytes[0] |= 0b111000;
			break;
		case DMRPACKET_CSBKO_UNIT_TO_UNIT_VOICE_SERVICE_REQUEST:
			data_bytes[0] |= 0b000100;
			data_bytes[2] = csbk->data.unit_to_unit_voice_service_request.service_options;
			break;
		case DMRPACKET_CSBKO_UNIT_TO_UNIT_VOICE_SERVICE_ANSWER_RESPONSE:
			data_bytes[0] |= 0b00000101;
			data_bytes[2] = csbk->data.unit_to_unit_voice_service_answer_response.service_options;
			data_bytes[3] = csbk->data.unit_to_unit_voice_service_answer_response.answer_response;
			break;
		case DMRPACKET_CSBKO_NEGATIVE_ACKNOWLEDGE_RESPONSE:
			data_bytes[0] |= 0b00100110;
			data_bytes[2] = 0b10000000 |
							(csbk->data.negative_acknowledge_response.source_type & 0x01) << 6 |
							(csbk->data.negative_acknowledge_response.service_type & 0b00111111);
			data_bytes[3] = csbk->data.negative_acknowledge_response.reason_code;
			break;
		case DMRPACKET_CSBKO_PREAMBLE:
			data_bytes[0] |= 0b00111101;
			data_bytes[2] = (csbk->data.preamble.data_follows & 0x01) << 7 |
							(csbk->data.preamble.dst_is_group & 0x01) << 6;
			data_bytes[3] = csbk->data.preamble.csbk_blocks_to_follow;
			break;
		default:
			return NULL;
	}

	data_bytes[4] = (csbk->dst_id & 0xff0000) >> 16;
	data_bytes[5] = (csbk->dst_id & 0x00ff00) >> 8;
	data_bytes[6] = (csbk->dst_id & 0x0000ff);
	data_bytes[7] = (csbk->src_id & 0xff0000) >> 16;
	data_bytes[8] = (csbk->src_id & 0x00ff00) >> 8;
	data_bytes[9] = (csbk->src_id & 0x0000ff);

	for (i = 0; i < 10; i++)
		crc_calc_crc16_ccitt(&calculated_crc, data_bytes[i]);
	crc_calc_crc16_ccitt_finish(&calculated_crc);

	// Inverting according to the inversion polynomial.
	calculated_crc = ~calculated_crc;
	// Applying CRC mask, see DMR AI spec. page 143.
	calculated_crc ^= 0xa5a5;

	data_bytes[10] = (calculated_crc & 0xff00) >> 8;
	data_bytes[11] = calculated_crc & 0xff;

	base_bytestobits(data_bytes, sizeof(data_bytes), data_bits.bits, sizeof(bptc_196_96_data_bits_t));
	return &data_bits;
}
Example #2
0
// Swaps given payload bytes and then converts them to an uint8_t array of bits.
dmrpacket_payload_bits_t *ipscpacket_convertpayloadtobits(uint8_t *ipscpacket_payload) {
	static dmrpacket_payload_bits_t payload_bits;
	uint8_t swapped_bytes[IPSCPACKET_PAYLOAD_SIZE] = {0,};
	uint8_t i;

	if (ipscpacket_payload == NULL)
		return NULL;

	// Swapping the bytes.
	for (i = 0; i < IPSCPACKET_PAYLOAD_SIZE-1; i += 2) {
		swapped_bytes[i] = *(ipscpacket_payload + i + 1);
		swapped_bytes[i+1] = *(ipscpacket_payload + i);
	}

	base_bytestobits(swapped_bytes, IPSCPACKET_PAYLOAD_SIZE-1, payload_bits.bits, sizeof(payload_bits.bits));

	return &payload_bits;
}
Example #3
0
void repeaters_play_ambe_data(dmrpacket_payload_voice_bytes_t *voice_bytes, repeater_t *repeater, dmr_timeslot_t ts, dmr_call_type_t calltype, dmr_id_t dstid, dmr_id_t srcid) {
	dmrpacket_payload_voice_bits_t voice_bits;

	if (repeater == NULL || voice_bytes == NULL)
		return;

	base_bytestobits(voice_bytes->bytes, sizeof(dmrpacket_payload_voice_bytes_t), voice_bits.raw.bits, sizeof(dmrpacket_payload_voice_bits_t));

	switch (repeater->slot[ts].ipsc_tx_voice_frame_num) {
		case 0:
			repeaters_add_to_ipsc_packet_buffer(repeater, ts, ipscpacket_construct_raw_packet(&repeater->ipaddr, ipscpacket_construct_raw_payload(repeater->slot[ts].ipsc_tx_seqnum++, ts, IPSCPACKET_SLOT_TYPE_VOICE_DATA_A, calltype, dstid, srcid,
				ipscpacket_construct_payload_voice_frame(IPSCPACKET_SLOT_TYPE_VOICE_DATA_A, &voice_bits, &repeater->slot[ts].ipsc_tx_emb_sig_lc_vbptc_storage))), 0);
			break;
		case 1:
			repeaters_add_to_ipsc_packet_buffer(repeater, ts, ipscpacket_construct_raw_packet(&repeater->ipaddr, ipscpacket_construct_raw_payload(repeater->slot[ts].ipsc_tx_seqnum++, ts, IPSCPACKET_SLOT_TYPE_VOICE_DATA_B, calltype, dstid, srcid,
				ipscpacket_construct_payload_voice_frame(IPSCPACKET_SLOT_TYPE_VOICE_DATA_B, &voice_bits, &repeater->slot[ts].ipsc_tx_emb_sig_lc_vbptc_storage))), 0);
			break;
		case 2:
			repeaters_add_to_ipsc_packet_buffer(repeater, ts, ipscpacket_construct_raw_packet(&repeater->ipaddr, ipscpacket_construct_raw_payload(repeater->slot[ts].ipsc_tx_seqnum++, ts, IPSCPACKET_SLOT_TYPE_VOICE_DATA_C, calltype, dstid, srcid,
				ipscpacket_construct_payload_voice_frame(IPSCPACKET_SLOT_TYPE_VOICE_DATA_C, &voice_bits, &repeater->slot[ts].ipsc_tx_emb_sig_lc_vbptc_storage))), 0);
			break;
		case 3:
			repeaters_add_to_ipsc_packet_buffer(repeater, ts, ipscpacket_construct_raw_packet(&repeater->ipaddr, ipscpacket_construct_raw_payload(repeater->slot[ts].ipsc_tx_seqnum++, ts, IPSCPACKET_SLOT_TYPE_VOICE_DATA_D, calltype, dstid, srcid,
				ipscpacket_construct_payload_voice_frame(IPSCPACKET_SLOT_TYPE_VOICE_DATA_D, &voice_bits, &repeater->slot[ts].ipsc_tx_emb_sig_lc_vbptc_storage))), 0);
			break;
		case 4:
			repeaters_add_to_ipsc_packet_buffer(repeater, ts, ipscpacket_construct_raw_packet(&repeater->ipaddr, ipscpacket_construct_raw_payload(repeater->slot[ts].ipsc_tx_seqnum++, ts, IPSCPACKET_SLOT_TYPE_VOICE_DATA_E, calltype, dstid, srcid,
				ipscpacket_construct_payload_voice_frame(IPSCPACKET_SLOT_TYPE_VOICE_DATA_E, &voice_bits, &repeater->slot[ts].ipsc_tx_emb_sig_lc_vbptc_storage))), 0);
			break;
		case 5:
			repeaters_add_to_ipsc_packet_buffer(repeater, ts, ipscpacket_construct_raw_packet(&repeater->ipaddr, ipscpacket_construct_raw_payload(repeater->slot[ts].ipsc_tx_seqnum++, ts, IPSCPACKET_SLOT_TYPE_VOICE_DATA_F, calltype, dstid, srcid,
				ipscpacket_construct_payload_voice_frame(IPSCPACKET_SLOT_TYPE_VOICE_DATA_F, &voice_bits, &repeater->slot[ts].ipsc_tx_emb_sig_lc_vbptc_storage))), 0);
			break;
		default:
			break;
	}
	repeater->slot[ts].ipsc_tx_voice_frame_num++;
	if (repeater->slot[ts].ipsc_tx_voice_frame_num > 5)
		repeater->slot[ts].ipsc_tx_voice_frame_num = 0;
}