
function bcon_dissector(buffer, pinfo, tree, BCON_PROTOCOL, offset, tm_len)


-- Define the fields for the protocol based on the structure
local f_bcon_msg = ProtoField.string("BCON_PROTOCOL.bcon_msg", "Bcon Msg")
local f_utc_tim = ProtoField.uint32("BCON_PROTOCOL.utc_tim", "UTC Time", base.DEC)
local f_utc_gps_tim_sts = ProtoField.uint8("BCON_PROTOCOL.utc_gps_tim_sts", "UTC GPS Time Status", base.DEC)
local f_latitude = ProtoField.float("BCON_PROTOCOL.latitude", "Latitude", base.DEC)
local f_longitude = ProtoField.float("BCON_PROTOCOL.longitude", "Longitude", base.DEC)
local f_altitude = ProtoField.float("BCON_PROTOCOL.altitude", "Altitude", base.DEC)
local f_x_pos = ProtoField.double("BCON_PROTOCOL.x_pos", "X Position", base.DEC)
local f_y_pos = ProtoField.double("BCON_PROTOCOL.y_pos", "Y Position", base.DEC)
local f_z_pos = ProtoField.double("BCON_PROTOCOL.z_pos", "Z Position", base.DEC)
local f_x_vel = ProtoField.double("BCON_PROTOCOL.x_vel", "X Velocity", base.DEC)
local f_y_vel = ProtoField.double("BCON_PROTOCOL.y_vel", "Y Velocity", base.DEC)
local f_z_vel = ProtoField.double("BCON_PROTOCOL.z_vel", "Z Velocity", base.DEC)
local f_fsm_state = ProtoField.uint8("BCON_PROTOCOL.fsm_state", "FSM State", base.DEC)
local f_num_resets = ProtoField.uint8("BCON_PROTOCOL.num_resets", "Number of Resets", base.DEC)
local f_zio_err = ProtoField.uint16("BCON_PROTOCOL.zio_err", "ZIO Error", base.DEC)
local f_sys_err = ProtoField.uint8("BCON_PROTOCOL.sys_err", "System Error", base.DEC)
local f_obc_volt_sensor = ProtoField.uint8("BCON_PROTOCOL.obc_volt_sensor", "OBC Volt Sensor", base.DEC)
local f_ps_volt_sensor = ProtoField.uint8("BCON_PROTOCOL.ps_volt_sensor", "PS Volt Sensor", base.DEC)
local f_temp_obc = ProtoField.uint8("BCON_PROTOCOL.temp_obc", "OBC Temperature", base.DEC)
local f_temp_ps = ProtoField.uint8("BCON_PROTOCOL.temp_ps", "PS Temperature", base.DEC)
local f_temp_es = ProtoField.uint8("BCON_PROTOCOL.temp_es", "ES Temperature", base.DEC)
local f_temp_gps = ProtoField.uint8("BCON_PROTOCOL.temp_gps", "GPS Temperature", base.DEC)
local f_totl_btry_volt = ProtoField.uint8("BCON_PROTOCOL.totl_btry_volt", "Total Battery Voltage", base.DEC)
local f_totl_panel_pwr = ProtoField.uint8("BCON_PROTOCOL.totl_panel_pwr", "Total Panel Power", base.DEC)
local f_chnl_sts = ProtoField.uint16("BCON_PROTOCOL.chnl_sts", "Channel Status", base.DEC)
local f_overcrnt_err_flg_byte1 = ProtoField.uint8("BCON_PROTOCOL.overcrnt_err_flg_byte1", "Overcurrent Error Flag Byte1", base.DEC)
local f_overcrnt_err_flg_byte2 = ProtoField.uint16("BCON_PROTOCOL.overcrnt_err_flg_byte2", "Overcurrent Error Flag Byte2", base.DEC)
local f_fsm_state_mode = ProtoField.uint8("BCON_PROTOCOL.fsm_state_mode", "FSM State Mode", base.DEC)
local f_sns_actr_pwr_sts = ProtoField.uint16("BCON_PROTOCOL.sns_actr_pwr_sts", "Sensor Actuator Power Status", base.DEC)
local f_actrs_run_sts = ProtoField.uint8("BCON_PROTOCOL.actrs_run_sts", "Actuators Run Status", base.DEC)

local f_sdr_fsm_st = ProtoField.uint8("BCON_PROTOCOL.sdr_fsm_st", "SDR FSM State", base.DEC)
local f_rssi0 = ProtoField.uint8("BCON_PROTOCOL.rssi0", "RSSI0", base.DEC)
local f_rssi1 = ProtoField.uint8("BCON_PROTOCOL.rssi1", "RSSI1", base.DEC)
local f_rx_err_cnt = ProtoField.uint32("BCON_PROTOCOL.rx_err_cnt", "RX Error Count", base.DEC)
local f_tx_frm_cnt = ProtoField.uint32("BCON_PROTOCOL.tx_frm_cnt", "TX Frame Count", base.DEC)
local f_rx_freq = ProtoField.uint32("BCON_PROTOCOL.rx_freq", "RX Frequency", base.DEC)
local f_symb_freq = ProtoField.uint16("BCON_PROTOCOL.symb_freq", "Symbol Frequency", base.DEC)
local f_mod = ProtoField.uint16("BCON_PROTOCOL.mod", "Modulation", base.DEC)
local f_roll_off = ProtoField.uint16("BCON_PROTOCOL.roll_off", "Roll Off", base.DEC)
local f_rand_enb = ProtoField.uint16("BCON_PROTOCOL.rand_enb", "Random Enable", base.DEC)
local f_cc_enb = ProtoField.uint16("BCON_PROTOCOL.cc_enb", "CC Enable", base.DEC)
local f_ors_enb = ProtoField.uint16("BCON_PROTOCOL.ors_enb", "ORS Enable", base.DEC)
local f_crc_enb = ProtoField.uint16("BCON_PROTOCOL.crc_enb", "CRC Enable", base.DEC)
local f_dc_filter_enb = ProtoField.uint16("BCON_PROTOCOL.dc_filter_enb", "DC Filter Enable", base.DEC)
local f_manchester_coding_en = ProtoField.uint16("BCON_PROTOCOL.manchester_coding_en", "Manchester Coding Enable", base.DEC)

-- Add the fields to the protocol
BCON_PROTOCOL.fields = {
    f_bcon_msg, f_utc_tim, f_utc_gps_tim_sts, f_latitude, f_longitude, f_altitude,
    f_x_pos, f_y_pos, f_z_pos, f_x_vel, f_y_vel, f_z_vel, f_fsm_state, f_num_resets, 
    f_zio_err, f_sys_err, f_obc_volt_sensor, f_ps_volt_sensor, f_temp_obc, f_temp_ps, 
    f_temp_es, f_temp_gps, f_totl_btry_volt, f_totl_panel_pwr, f_chnl_sts, 
    f_overcrnt_err_flg_byte1, f_overcrnt_err_flg_byte2, f_fsm_state_mode, f_sns_actr_pwr_sts, 
    f_actrs_run_sts, f_sdr_fsm_st, f_rssi0, f_rssi1, f_rx_err_cnt, f_tx_frm_cnt, 
    f_rx_freq, f_symb_freq, f_mod, f_roll_off, f_rand_enb, f_cc_enb, f_ors_enb, 
    f_crc_enb, f_dc_filter_enb, f_manchester_coding_en
}
local subtree = tree:add(BCON_PROTOCOL, buffer(), "BEACON")

-- dissect bcon_msg

local bcon_msg = buffer(offset, 18):string()
subtree:add(f_bcon_msg, bcon_msg)
offset = offset + 18


-- dissect utc_tim
local utc_tim = buffer(offset, 4):le_uint()
subtree:add(f_utc_tim, utc_tim)
offset = offset + 4

-- dissect utc_gps_tim_sts
local utc_gps_tim_sts = buffer(offset, 1):le_uint()
subtree:add(f_utc_gps_tim_sts, utc_gps_tim_sts)
offset = offset + 1

-- dissect latitude
local latitude = buffer(offset, 4):le_float()
subtree:add(f_latitude, latitude)
offset = offset + 4

-- dissect longitude
local longitude = buffer(offset, 4):le_float()
subtree:add(f_longitude, longitude)
offset = offset + 4

-- dissect altitude
local altitude = buffer(offset, 4):le_float()
subtree:add(f_altitude, altitude)
offset = offset + 4

-- dissect x_pos
	local high = buffer(offset, 4):le_uint()  -- First 4 bytes
	local low = buffer(offset + 4, 4):le_uint() -- Next 4 bytes

	-- Combine and unpack as a double (64-bit floating-point number)
	local x_pos = string.unpack("d", string.pack("<II", low, high))	
	subtree:add(f_x_pos, x_pos)
	offset = offset + 8
	
	--local x_pos = buffer(offset, 8):le_uint()
	--subtree:add(f_x_pos, x_pos)
	--offset = offset + 8

-- dissect y_pos
local high_y_pos = buffer(offset, 4):le_uint()  -- First 4 bytes for y_pos
local low_y_pos = buffer(offset + 4, 4):le_uint() -- Next 4 bytes for y_pos
local y_pos = string.unpack("d", string.pack("<II", low_y_pos, high_y_pos))
subtree:add(f_y_pos, y_pos)
offset = offset + 8

-- dissect z_pos
local high_z_pos = buffer(offset, 4):le_uint()  -- First 4 bytes for z_pos
local low_z_pos = buffer(offset + 4, 4):le_uint() -- Next 4 bytes for z_pos
local z_pos = string.unpack("d", string.pack("<II", low_z_pos, high_z_pos))
subtree:add(f_z_pos, z_pos)
offset = offset + 8

-- dissect x_vel
local high_x_vel = buffer(offset, 4):le_uint()  -- First 4 bytes for x_vel
local low_x_vel = buffer(offset + 4, 4):le_uint() -- Next 4 bytes for x_vel
local x_vel = string.unpack("d", string.pack("<II", low_x_vel, high_x_vel))
subtree:add(f_x_vel, x_vel)
offset = offset + 8

-- dissect y_vel
local high_y_vel = buffer(offset, 4):le_uint()  -- First 4 bytes for y_vel
local low_y_vel = buffer(offset + 4, 4):le_uint() -- Next 4 bytes for y_vel
local y_vel = string.unpack("d", string.pack("<II", low_y_vel, high_y_vel))
subtree:add(f_y_vel, y_vel)
offset = offset + 8

-- dissect z_vel
local high_z_vel = buffer(offset, 4):le_uint()  -- First 4 bytes for z_vel
local low_z_vel = buffer(offset + 4, 4):le_uint() -- Next 4 bytes for z_vel
local z_vel = string.unpack("d", string.pack("<II", low_z_vel, high_z_vel))
subtree:add(f_z_vel, z_vel)
offset = offset + 8

-- dissect fsm_state
local fsm_state = buffer(offset, 1):le_uint()
subtree:add(f_fsm_state, fsm_state)
offset = offset + 1

-- dissect num_resets
local num_resets = buffer(offset, 1):le_uint()
subtree:add(f_num_resets, num_resets)
offset = offset + 1

-- dissect zio_err
local zio_err = buffer(offset, 2):le_uint()
subtree:add(f_zio_err, zio_err)
offset = offset + 2

-- dissect sys_err
local sys_err = buffer(offset, 1):le_uint()
subtree:add(f_sys_err, sys_err)
offset = offset + 1

-- dissect obc_volt_sensor
local obc_volt_sensor = buffer(offset, 1):le_uint()
subtree:add(f_obc_volt_sensor, obc_volt_sensor)
offset = offset + 1

-- dissect ps_volt_sensor
local ps_volt_sensor = buffer(offset, 1):le_uint()
subtree:add(f_ps_volt_sensor, ps_volt_sensor)
offset = offset + 1

-- dissect temp_obc
local temp_obc = buffer(offset, 1):le_uint()
subtree:add(f_temp_obc, temp_obc)
offset = offset + 1

-- dissect temp_ps
local temp_ps = buffer(offset, 1):le_uint()
subtree:add(f_temp_ps, temp_ps)
offset = offset + 1

-- dissect temp_es
local temp_es = buffer(offset, 1):le_uint()
subtree:add(f_temp_es, temp_es)
offset = offset + 1

-- dissect temp_gps
local temp_gps = buffer(offset, 1):le_uint()
subtree:add(f_temp_gps, temp_gps)
offset = offset + 1

-- dissect totl_btry_volt
local totl_btry_volt = buffer(offset, 1):le_uint()
subtree:add(f_totl_btry_volt, totl_btry_volt)
offset = offset + 1

-- dissect totl_panel_pwr
local totl_panel_pwr = buffer(offset, 1):le_uint()
subtree:add(f_totl_panel_pwr, totl_panel_pwr)
offset = offset + 1

-- dissect chnl_sts
local chnl_sts = buffer(offset, 2):le_uint()
subtree:add(f_chnl_sts, chnl_sts)
offset = offset + 2

-- dissect overcrnt_err_flg_byte1
local overcrnt_err_flg_byte1 = buffer(offset, 1):le_uint()
subtree:add(f_overcrnt_err_flg_byte1, overcrnt_err_flg_byte1)
offset = offset + 1

-- dissect overcrnt_err_flg_byte2
local overcrnt_err_flg_byte2 = buffer(offset, 2):le_uint()
subtree:add(f_overcrnt_err_flg_byte2, overcrnt_err_flg_byte2)
offset = offset + 2

-- dissect fsm_state_mode
local fsm_state_mode = buffer(offset, 1):le_uint()
subtree:add(f_fsm_state_mode, fsm_state_mode)
offset = offset + 1

-- dissect sns_actr_pwr_sts
local sns_actr_pwr_sts = buffer(offset, 2):le_uint()
subtree:add(f_sns_actr_pwr_sts, sns_actr_pwr_sts)
offset = offset + 2

-- dissect actrs_run_sts
local actrs_run_sts = buffer(offset, 1):le_uint()
subtree:add(f_actrs_run_sts, actrs_run_sts)
offset = offset + 1

-- dissect sdr_fsm_st
local byte = buffer(offset, 1):le_uint()  -- Read the full byte (8 bits)
--local sdr_fsm_st = (byte >> 4) & 0x0F
local sdr_fsm_st = byte  & 0x0F
subtree:add(f_sdr_fsm_st, sdr_fsm_st)  ------------------------------------bit logic
--offset = offset + 1

-- dissect rssi0
byte = buffer(offset, 1):le_uint() 
local rssi0 = (byte >> 4) & 0x03
subtree:add(f_rssi0, rssi0)
--offset = offset + 1

-- dissect rssi1
byte = buffer(offset, 1):le_uint()
local rssi1 = (byte >> 6) &0x03
subtree:add(f_rssi1, rssi1)
offset = offset + 1
-------------------------------------------one byte

-- dissect rx_err_cnt
local rx_err_cnt = buffer(offset, 4):le_uint()
subtree:add(f_rx_err_cnt, rx_err_cnt)
offset = offset + 4

-- dissect tx_frm_cnt
local tx_frm_cnt = buffer(offset, 4):le_uint()
subtree:add(f_tx_frm_cnt, tx_frm_cnt)
offset = offset + 4

-- dissect rx_freq
local rx_freq = buffer(offset, 4):le_uint()
subtree:add(f_rx_freq, rx_freq)
offset = offset + 4

-- dissect symb_freq
local symb_freq = buffer(offset, 1):le_uint()
subtree:add(f_symb_freq, symb_freq)
offset = offset + 1
-------------------------------------------------------
-- dissect mod
byte = buffer(offset, 1):le_uint()
local mod = byte & 0x03
subtree:add(f_mod, mod)
--offset = offset + 2

-- dissect roll_off
byte = buffer(offset, 1):le_uint()
local roll_off = (byte >> 2) & 0x03
subtree:add(f_roll_off, roll_off)
--offset = offset + 2

-- dissect rand_enb
byte = buffer(offset, 1):le_uint()
local rand_enb = (byte >> 4) & 0x03
subtree:add(f_rand_enb, rand_enb)
--offset = offset + 2

-- dissect cc_enb
byte = buffer(offset, 1):le_uint()
local cc_enb = (byte >> 6) &0x01
subtree:add(f_cc_enb, cc_enb)
--offset = offset + 2

-- dissect ors_enb
byte = buffer(offset, 1):le_uint()
local ors_enb = (byte >> 7) & 0x01
subtree:add(f_ors_enb, ors_enb)
offset = offset + 1
------------------------------------------------------------
-- dissect sdr_fsm_st
byte = buffer(offset, 1):le_uint()
local x = byte  & 0x0F
subtree:add(f_sdr_fsm_st, x)

-- dissect rssi0
byte = buffer(offset, 1):le_uint()
local rssi0 = (byte >> 4) & 0x03
subtree:add(f_rssi0, rssi0)
--offset = offset + 1

-- dissect rssi1
byte = buffer(offset, 1):le_uint()
local rssi1 = (byte >> 6) & 0x03
subtree:add(f_rssi1, rssi1)
offset = offset + 1
-----------------------------------------------------1byte

-- dissect rx_err_cnt
local rx_err_cnt = buffer(offset, 4):le_uint()
subtree:add(f_rx_err_cnt, rx_err_cnt)
offset = offset + 4

-- dissect tx_frm_cnt
local tx_frm_cnt = buffer(offset, 4):le_uint()
subtree:add(f_tx_frm_cnt, tx_frm_cnt)
offset = offset + 4

-- dissect rx_freq
local rx_freq = buffer(offset, 4):le_uint()
subtree:add(f_rx_freq, rx_freq)
offset = offset + 4
---------------------------------------------------------------
-- dissect symb_freq
byte = buffer(offset, 1):le_uint()
local symb_freq = byte & 0x0f
subtree:add(f_symb_freq, symb_freq)
--offset = offset + 2

-- dissect mod
byte = buffer(offset, 1):le_uint()
local mod = (byte >> 4) & 0x01
subtree:add(f_mod, mod)
--offset = offset + 2

-- dissect roll_off
byte = buffer(offset, 1):le_uint()
local roll_off = (byte >> 5) & 0x01
subtree:add(f_roll_off, roll_off)
--offset = offset + 2

-- dissect crc_enb
byte = buffer(offset, 1):le_uint()
local crc_enb = (byte >> 6) &0x03
subtree:add(f_crc_enb, crc_enb)
offset = offset + 1
--------------------------------------------------------------------

-- dissect dc_filter_enb
byte = buffer(offset, 1):le_uint()
--byte = 0x2c
local dc_filter_enb = byte & 0x03
subtree:add(f_dc_filter_enb, dc_filter_enb)
--offset = offset + 2

byte = buffer(offset, 1):le_uint()
--byte = 0x2c
local cc_enb = (byte >> 2) & 0x03 
subtree:add(f_cc_enb, cc_enb)
--offset = offset + 2

-- dissect rand_enb (2 bits)
byte = buffer(offset, 1):le_uint()
--byte = 0x2c
local rand_enb = (byte >> 4) & 0x03 
subtree:add(f_rand_enb, rand_enb)
--offset = offset + 2

-- dissect manchester_coding_en
byte = buffer(offset, 1):le_uint()
--byte = 0x2c
local manchester_coding_en = (byte >>6) & 0x03
subtree:add(f_manchester_coding_en, manchester_coding_en)
--offset = offset + 2

end