//! Lcsf abstraction layer (A) for protocol: Test
//!
//! This file has been auto-generated by LCSF Generator v1.4
//! It shouldn't be edited manually

use crate::lcsf_lib::lcsf_validator;
use crate::lcsf_prot::protocol_test;
use lazy_static::lazy_static;
use lcsf_validator::LcsfAttDesc;
use lcsf_validator::LcsfCmdDesc;
use lcsf_validator::LcsfDataType;
use lcsf_validator::LcsfProtDesc;
use lcsf_validator::LcsfValidAtt;
use lcsf_validator::LcsfValidAttPayload;
use lcsf_validator::LcsfValidCmd;
use std::ffi::CString;

use protocol_test::Ca10AttCa11Payload;
use protocol_test::Ca11AttCa12Payload;
use protocol_test::Ca6AttCa7Payload;
use protocol_test::Ca7AttCa8Payload;
use protocol_test::Cc2AttPayload;
use protocol_test::Cc3AttPayload;
use protocol_test::Cc5AttCa5Payload;
use protocol_test::Cc5AttCa6Payload;
use protocol_test::Cc5AttPayload;
use protocol_test::Cc6AttCa10Payload;
use protocol_test::Cc6AttCa9Payload;
use protocol_test::Cc6AttPayload;
use protocol_test::CmdEnum;
use protocol_test::CmdPayload;

/// Convert command name to lcsf command id
fn cmd_name_to_id(cmd_name: CmdEnum) -> u16 {
    match cmd_name {
        CmdEnum::Sc1 => CMD_ID_SC1,
        CmdEnum::Sc2 => CMD_ID_SC2,
        CmdEnum::Sc3 => CMD_ID_SC3,
        CmdEnum::Cc1 => CMD_ID_CC1,
        CmdEnum::Cc2 => CMD_ID_CC2,
        CmdEnum::Cc3 => CMD_ID_CC3,
        CmdEnum::Cc4 => CMD_ID_CC4,
        CmdEnum::Cc5 => CMD_ID_CC5,
        CmdEnum::Cc6 => CMD_ID_CC6,
    }
}

/// Convert lcsf command id to command name
fn cmd_id_to_name(cmd_id: u16) -> CmdEnum {
    match cmd_id {
        CMD_ID_SC1 => CmdEnum::Sc1,
        CMD_ID_SC2 => CmdEnum::Sc2,
        CMD_ID_SC3 => CmdEnum::Sc3,
        CMD_ID_CC1 => CmdEnum::Cc1,
        CMD_ID_CC2 => CmdEnum::Cc2,
        CMD_ID_CC3 => CmdEnum::Cc3,
        CMD_ID_CC4 => CmdEnum::Cc4,
        CMD_ID_CC5 => CmdEnum::Cc5,
        CMD_ID_CC6 => CmdEnum::Cc6,
        _ => panic!("Unreachable values"),
    }
}

/// Retrieve data of a command from its valid attribute array and store it in a payload
///
/// att_arr command valid attribute array reference
fn cc2_get_data(att_arr: &[LcsfValidAtt]) -> CmdPayload {
    let mut cc2_payload = Cc2AttPayload {
        sa1: 0,
        sa2: 0,
        sa3: 0,
        sa4: Vec::new(),
        sa5: CString::new("").unwrap(),
        is_sa6_here: false,
        sa6: 0,
        is_sa7_here: false,
        sa7: 0,
        is_sa8_here: false,
        sa8: 0,
        is_sa9_here: false,
        sa9: Vec::new(),
        is_sa10_here: false,
        sa10: CString::new("").unwrap(),
        sa11: 0,
        sa12: 0.0,
        sa13: 0.0,
    };
    // Get iterator
    let att_iter = &mut att_arr.iter();
    // Retrieve data of attribute sa1
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa1 = u8::from_le_bytes(data.as_slice().try_into().unwrap());
    }
    // Retrieve data of attribute sa2
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa2 = lcsf_validator::vle_decode(data) as u16;
    }
    // Retrieve data of attribute sa3
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa3 = lcsf_validator::vle_decode(data) as u32;
    }
    // Retrieve data of attribute sa4
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa4 = data.clone();
    }
    // Retrieve data of attribute sa5
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa5 = CString::from_vec_with_nul(data.clone()).unwrap();
    }
    // Retrieve data of attribute sa6
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc2_payload.is_sa6_here = true;
            cc2_payload.sa6 = u8::from_le_bytes(data.as_slice().try_into().unwrap());
        }
    }
    // Retrieve data of attribute sa7
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc2_payload.is_sa7_here = true;
            cc2_payload.sa7 = lcsf_validator::vle_decode(data) as u16;
        }
    }
    // Retrieve data of attribute sa8
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc2_payload.is_sa8_here = true;
            cc2_payload.sa8 = lcsf_validator::vle_decode(data) as u32;
        }
    }
    // Retrieve data of attribute sa9
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc2_payload.is_sa9_here = true;
            cc2_payload.sa9 = data.clone();
        }
    }
    // Retrieve data of attribute sa10
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc2_payload.is_sa10_here = true;
            cc2_payload.sa10 = CString::from_vec_with_nul(data.clone()).unwrap();
        }
    }
    // Retrieve data of attribute sa11
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa11 = lcsf_validator::vle_decode(data);
    }
    // Retrieve data of attribute sa12
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa12 = f32::from_le_bytes(data.as_slice().try_into().unwrap());
    }
    // Retrieve data of attribute sa13
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc2_payload.sa13 = f64::from_le_bytes(data.as_slice().try_into().unwrap());
    }
    CmdPayload::Cc2Payload(cc2_payload)
}

fn cc3_get_data(att_arr: &[LcsfValidAtt]) -> CmdPayload {
    let mut cc3_payload = Cc3AttPayload {
        sa1: 0,
        sa2: 0,
        sa3: 0,
        sa4: Vec::new(),
        sa5: CString::new("").unwrap(),
        is_sa6_here: false,
        sa6: 0,
        is_sa7_here: false,
        sa7: 0,
        is_sa8_here: false,
        sa8: 0,
        is_sa9_here: false,
        sa9: Vec::new(),
        is_sa10_here: false,
        sa10: CString::new("").unwrap(),
        sa11: 0,
        sa12: 0.0,
        sa13: 0.0,
    };
    // Get iterator
    let att_iter = &mut att_arr.iter();
    // Retrieve data of attribute sa1
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa1 = u8::from_le_bytes(data.as_slice().try_into().unwrap());
    }
    // Retrieve data of attribute sa2
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa2 = lcsf_validator::vle_decode(data) as u16;
    }
    // Retrieve data of attribute sa3
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa3 = lcsf_validator::vle_decode(data) as u32;
    }
    // Retrieve data of attribute sa4
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa4 = data.clone();
    }
    // Retrieve data of attribute sa5
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa5 = CString::from_vec_with_nul(data.clone()).unwrap();
    }
    // Retrieve data of attribute sa6
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc3_payload.is_sa6_here = true;
            cc3_payload.sa6 = u8::from_le_bytes(data.as_slice().try_into().unwrap());
        }
    }
    // Retrieve data of attribute sa7
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc3_payload.is_sa7_here = true;
            cc3_payload.sa7 = lcsf_validator::vle_decode(data) as u16;
        }
    }
    // Retrieve data of attribute sa8
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc3_payload.is_sa8_here = true;
            cc3_payload.sa8 = lcsf_validator::vle_decode(data) as u32;
        }
    }
    // Retrieve data of attribute sa9
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc3_payload.is_sa9_here = true;
            cc3_payload.sa9 = data.clone();
        }
    }
    // Retrieve data of attribute sa10
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        if *data != Vec::new() {
            cc3_payload.is_sa10_here = true;
            cc3_payload.sa10 = CString::from_vec_with_nul(data.clone()).unwrap();
        }
    }
    // Retrieve data of attribute sa11
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa11 = lcsf_validator::vle_decode(data);
    }
    // Retrieve data of attribute sa12
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa12 = f32::from_le_bytes(data.as_slice().try_into().unwrap());
    }
    // Retrieve data of attribute sa13
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc3_payload.sa13 = f64::from_le_bytes(data.as_slice().try_into().unwrap());
    }
    CmdPayload::Cc3Payload(cc3_payload)
}

fn cc5_get_data(att_arr: &[LcsfValidAtt]) -> CmdPayload {
    let mut cc5_payload = Cc5AttPayload {
        sa2: 0,
        ca5_payload: Cc5AttCa5Payload {
            sa1: 0,
            sa2: 0,
            is_sa3_here: false,
            sa3: 0,
        },
        is_ca6_here: false,
        ca6_payload: Cc5AttCa6Payload {
            is_sa1_here: false,
            sa1: 0,
            ca7_payload: Ca6AttCa7Payload {
                is_sa1_here: false,
                sa1: 0,
                ca8_payload: Ca7AttCa8Payload { sa4: Vec::new() },
            },
        },
    };
    // Get iterator
    let att_iter = &mut att_arr.iter();
    // Retrieve data of attribute sa2
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc5_payload.sa2 = lcsf_validator::vle_decode(data) as u16;
    }
    // Retrieve data of attribute ca5
    if let LcsfValidAttPayload::SubattArr(subatt_arr) = &att_iter.next().unwrap().payload {
        // Get iterator
        let subatt_iter = &mut subatt_arr.iter();
        // Retrieve data of sub-attribute sa1
        if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
            cc5_payload.ca5_payload.sa1 = u8::from_le_bytes(data.as_slice().try_into().unwrap());
        }
        // Retrieve data of sub-attribute sa2
        if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
            cc5_payload.ca5_payload.sa2 = lcsf_validator::vle_decode(data) as u16;
        }
        // Retrieve data of sub-attribute sa3
        if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
            if *data != Vec::new() {
                cc5_payload.ca5_payload.is_sa3_here = true;
                cc5_payload.ca5_payload.sa3 = lcsf_validator::vle_decode(data) as u32;
            }
        }
    }
    // Retrieve data of attribute ca6
    if let LcsfValidAttPayload::SubattArr(subatt_arr) = &att_iter.next().unwrap().payload {
        if *subatt_arr != Vec::new() {
            cc5_payload.is_ca6_here = true;
            // Get iterator
            let subatt_iter = &mut subatt_arr.iter();
            // Retrieve data of sub-attribute sa1
            if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
                if *data != Vec::new() {
                    cc5_payload.ca6_payload.is_sa1_here = true;
                    cc5_payload.ca6_payload.sa1 =
                        u8::from_le_bytes(data.as_slice().try_into().unwrap());
                }
            }
            // Retrieve data of sub-attribute ca7
            if let LcsfValidAttPayload::SubattArr(subatt_arr) = &subatt_iter.next().unwrap().payload
            {
                // Get iterator
                let subatt_iter = &mut subatt_arr.iter();
                // Retrieve data of sub-attribute sa1
                if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
                    if *data != Vec::new() {
                        cc5_payload.ca6_payload.ca7_payload.is_sa1_here = true;
                        cc5_payload.ca6_payload.ca7_payload.sa1 =
                            u8::from_le_bytes(data.as_slice().try_into().unwrap());
                    }
                }
                // Retrieve data of sub-attribute ca8
                if let LcsfValidAttPayload::SubattArr(subatt_arr) =
                    &subatt_iter.next().unwrap().payload
                {
                    // Get iterator
                    let subatt_iter = &mut subatt_arr.iter();
                    // Retrieve data of sub-attribute sa4
                    if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
                        cc5_payload.ca6_payload.ca7_payload.ca8_payload.sa4 = data.clone();
                    }
                }
            }
        }
    }
    CmdPayload::Cc5Payload(cc5_payload)
}

fn cc6_get_data(att_arr: &[LcsfValidAtt]) -> CmdPayload {
    let mut cc6_payload = Cc6AttPayload {
        sa4: Vec::new(),
        ca9_payload: Cc6AttCa9Payload {
            sa1: 0,
            sa2: 0,
            is_sa3_here: false,
            sa3: 0,
        },
        is_ca10_here: false,
        ca10_payload: Cc6AttCa10Payload {
            is_sa1_here: false,
            sa1: 0,
            ca11_payload: Ca10AttCa11Payload {
                is_sa1_here: false,
                sa1: 0,
                ca12_payload: Ca11AttCa12Payload { sa4: Vec::new() },
            },
        },
    };
    // Get iterator
    let att_iter = &mut att_arr.iter();
    // Retrieve data of attribute sa4
    if let LcsfValidAttPayload::Data(data) = &att_iter.next().unwrap().payload {
        cc6_payload.sa4 = data.clone();
    }
    // Retrieve data of attribute ca9
    if let LcsfValidAttPayload::SubattArr(subatt_arr) = &att_iter.next().unwrap().payload {
        // Get iterator
        let subatt_iter = &mut subatt_arr.iter();
        // Retrieve data of sub-attribute sa1
        if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
            cc6_payload.ca9_payload.sa1 = u8::from_le_bytes(data.as_slice().try_into().unwrap());
        }
        // Retrieve data of sub-attribute sa2
        if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
            cc6_payload.ca9_payload.sa2 = lcsf_validator::vle_decode(data) as u16;
        }
        // Retrieve data of sub-attribute sa3
        if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
            if *data != Vec::new() {
                cc6_payload.ca9_payload.is_sa3_here = true;
                cc6_payload.ca9_payload.sa3 = lcsf_validator::vle_decode(data) as u32;
            }
        }
    }
    // Retrieve data of attribute ca10
    if let LcsfValidAttPayload::SubattArr(subatt_arr) = &att_iter.next().unwrap().payload {
        if *subatt_arr != Vec::new() {
            cc6_payload.is_ca10_here = true;
            // Get iterator
            let subatt_iter = &mut subatt_arr.iter();
            // Retrieve data of sub-attribute sa1
            if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
                if *data != Vec::new() {
                    cc6_payload.ca10_payload.is_sa1_here = true;
                    cc6_payload.ca10_payload.sa1 =
                        u8::from_le_bytes(data.as_slice().try_into().unwrap());
                }
            }
            // Retrieve data of sub-attribute ca11
            if let LcsfValidAttPayload::SubattArr(subatt_arr) = &subatt_iter.next().unwrap().payload
            {
                // Get iterator
                let subatt_iter = &mut subatt_arr.iter();
                // Retrieve data of sub-attribute sa1
                if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
                    if *data != Vec::new() {
                        cc6_payload.ca10_payload.ca11_payload.is_sa1_here = true;
                        cc6_payload.ca10_payload.ca11_payload.sa1 =
                            u8::from_le_bytes(data.as_slice().try_into().unwrap());
                    }
                }
                // Retrieve data of sub-attribute ca12
                if let LcsfValidAttPayload::SubattArr(subatt_arr) =
                    &subatt_iter.next().unwrap().payload
                {
                    // Get iterator
                    let subatt_iter = &mut subatt_arr.iter();
                    // Retrieve data of sub-attribute sa4
                    if let LcsfValidAttPayload::Data(data) = &subatt_iter.next().unwrap().payload {
                        cc6_payload.ca10_payload.ca11_payload.ca12_payload.sa4 = data.clone();
                    }
                }
            }
        }
    }
    CmdPayload::Cc6Payload(cc6_payload)
}

/// Tranform a lcsf valid command into a protocol payload
///
/// valid_cmd: valid command reference
pub fn receive_cmd(valid_cmd: &LcsfValidCmd) -> (CmdEnum, CmdPayload) {
    let cmd_name = cmd_id_to_name(valid_cmd.cmd_id);
    let cmd_payload = match cmd_name {
        CmdEnum::Sc1 => CmdPayload::Empty,
        CmdEnum::Sc2 => CmdPayload::Empty,
        CmdEnum::Sc3 => CmdPayload::Empty,
        CmdEnum::Cc1 => CmdPayload::Empty,
        CmdEnum::Cc2 => cc2_get_data(&valid_cmd.att_arr),
        CmdEnum::Cc3 => cc3_get_data(&valid_cmd.att_arr),
        CmdEnum::Cc4 => CmdPayload::Empty,
        CmdEnum::Cc5 => cc5_get_data(&valid_cmd.att_arr),
        CmdEnum::Cc6 => cc6_get_data(&valid_cmd.att_arr),
    };
    (cmd_name, cmd_payload)
}

/// Fill a command lcsf valid attribute array from its payload
///
/// cmd_payload pointer to the command payload
fn cc1_fill_att(cmd_payload: &CmdPayload) -> Vec<LcsfValidAtt> {
    let mut att_arr: Vec<LcsfValidAtt> = Vec::new();
    if let CmdPayload::Cc1Payload(payload) = &cmd_payload {
        // Fill data of attribute sa1
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa1 as u64)),
        });
        // Fill data of attribute sa2
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa2 as u64)),
        });
        // Fill data of attribute sa3
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa3 as u64)),
        });
        // Fill data of attribute sa4
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa4.clone()),
        });
        // Fill data of attribute sa5
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa5.clone().into_bytes_with_nul()),
        });
        // Fill data of attribute sa6
        if payload.is_sa6_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa6 as u64)),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa7
        if payload.is_sa7_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa7 as u64)),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa8
        if payload.is_sa8_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa8 as u64)),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa9
        if payload.is_sa9_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(payload.sa9.clone()),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa10
        if payload.is_sa10_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(payload.sa10.clone().into_bytes_with_nul()),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa11
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa11)),
        });
        // Fill data of attribute sa12
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa12.to_le_bytes().to_vec()),
        });
        // Fill data of attribute sa13
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa13.to_le_bytes().to_vec()),
        });
    }
    att_arr
}

fn cc3_fill_att(cmd_payload: &CmdPayload) -> Vec<LcsfValidAtt> {
    let mut att_arr: Vec<LcsfValidAtt> = Vec::new();
    if let CmdPayload::Cc3Payload(payload) = &cmd_payload {
        // Fill data of attribute sa1
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa1 as u64)),
        });
        // Fill data of attribute sa2
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa2 as u64)),
        });
        // Fill data of attribute sa3
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa3 as u64)),
        });
        // Fill data of attribute sa4
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa4.clone()),
        });
        // Fill data of attribute sa5
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa5.clone().into_bytes_with_nul()),
        });
        // Fill data of attribute sa6
        if payload.is_sa6_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa6 as u64)),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa7
        if payload.is_sa7_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa7 as u64)),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa8
        if payload.is_sa8_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa8 as u64)),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa9
        if payload.is_sa9_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(payload.sa9.clone()),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa10
        if payload.is_sa10_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(payload.sa10.clone().into_bytes_with_nul()),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::Data(Vec::new()),
            });
        }
        // Fill data of attribute sa11
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa11)),
        });
        // Fill data of attribute sa12
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa12.to_le_bytes().to_vec()),
        });
        // Fill data of attribute sa13
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa13.to_le_bytes().to_vec()),
        });
    }
    att_arr
}

fn cc4_fill_att(cmd_payload: &CmdPayload) -> Vec<LcsfValidAtt> {
    let mut att_arr: Vec<LcsfValidAtt> = Vec::new();
    if let CmdPayload::Cc4Payload(payload) = &cmd_payload {
        // Fill data of attribute sa1
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(payload.sa1 as u64)),
        });
        // Fill data of attribute ca1
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::SubattArr(vec![
                // Fill data of sub-attribute sa1
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                        payload.ca1_payload.sa1 as u64,
                    )),
                },
                // Fill data of sub-attribute sa2
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                        payload.ca1_payload.sa2 as u64,
                    )),
                },
                // Fill data of sub-attribute sa3
                LcsfValidAtt {
                    payload: if payload.ca1_payload.is_sa3_here {
                        LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                            payload.ca1_payload.sa3 as u64,
                        ))
                    } else {
                        LcsfValidAttPayload::Data(Vec::new())
                    },
                },
            ]),
        });
        // Fill data of attribute ca2
        if payload.is_ca2_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::SubattArr(vec![
                    // Fill data of sub-attribute sa1
                    LcsfValidAtt {
                        payload: if payload.ca2_payload.is_sa1_here {
                            LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                                payload.ca2_payload.sa1 as u64,
                            ))
                        } else {
                            LcsfValidAttPayload::Data(Vec::new())
                        },
                    },
                    // Fill data of sub-attribute ca3
                    LcsfValidAtt {
                        payload: LcsfValidAttPayload::SubattArr(vec![
                            // Fill data of sub-attribute sa1
                            LcsfValidAtt {
                                payload: if payload.ca2_payload.ca3_payload.is_sa1_here {
                                    LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                                        payload.ca2_payload.ca3_payload.sa1 as u64,
                                    ))
                                } else {
                                    LcsfValidAttPayload::Data(Vec::new())
                                },
                            },
                            // Fill data of sub-attribute ca4
                            LcsfValidAtt {
                                payload: LcsfValidAttPayload::SubattArr(vec![
                                    // Fill data of sub-attribute sa4
                                    LcsfValidAtt {
                                        payload: LcsfValidAttPayload::Data(
                                            payload.ca2_payload.ca3_payload.ca4_payload.sa4.clone(),
                                        ),
                                    },
                                ]),
                            },
                        ]),
                    },
                ]),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::SubattArr(Vec::new()),
            });
        }
    }
    att_arr
}

fn cc6_fill_att(cmd_payload: &CmdPayload) -> Vec<LcsfValidAtt> {
    let mut att_arr: Vec<LcsfValidAtt> = Vec::new();
    if let CmdPayload::Cc6Payload(payload) = &cmd_payload {
        // Fill data of attribute sa4
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::Data(payload.sa4.clone()),
        });
        // Fill data of attribute ca9
        att_arr.push(LcsfValidAtt {
            payload: LcsfValidAttPayload::SubattArr(vec![
                // Fill data of sub-attribute sa1
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                        payload.ca9_payload.sa1 as u64,
                    )),
                },
                // Fill data of sub-attribute sa2
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                        payload.ca9_payload.sa2 as u64,
                    )),
                },
                // Fill data of sub-attribute sa3
                LcsfValidAtt {
                    payload: if payload.ca9_payload.is_sa3_here {
                        LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                            payload.ca9_payload.sa3 as u64,
                        ))
                    } else {
                        LcsfValidAttPayload::Data(Vec::new())
                    },
                },
            ]),
        });
        // Fill data of attribute ca10
        if payload.is_ca10_here {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::SubattArr(vec![
                    // Fill data of sub-attribute sa1
                    LcsfValidAtt {
                        payload: if payload.ca10_payload.is_sa1_here {
                            LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                                payload.ca10_payload.sa1 as u64,
                            ))
                        } else {
                            LcsfValidAttPayload::Data(Vec::new())
                        },
                    },
                    // Fill data of sub-attribute ca11
                    LcsfValidAtt {
                        payload: LcsfValidAttPayload::SubattArr(vec![
                            // Fill data of sub-attribute sa1
                            LcsfValidAtt {
                                payload: if payload.ca10_payload.ca11_payload.is_sa1_here {
                                    LcsfValidAttPayload::Data(lcsf_validator::vle_encode(
                                        payload.ca10_payload.ca11_payload.sa1 as u64,
                                    ))
                                } else {
                                    LcsfValidAttPayload::Data(Vec::new())
                                },
                            },
                            // Fill data of sub-attribute ca12
                            LcsfValidAtt {
                                payload: LcsfValidAttPayload::SubattArr(vec![
                                    // Fill data of sub-attribute sa4
                                    LcsfValidAtt {
                                        payload: LcsfValidAttPayload::Data(
                                            payload
                                                .ca10_payload
                                                .ca11_payload
                                                .ca12_payload
                                                .sa4
                                                .clone(),
                                        ),
                                    },
                                ]),
                            },
                        ]),
                    },
                ]),
            });
        } else {
            att_arr.push(LcsfValidAtt {
                payload: LcsfValidAttPayload::SubattArr(Vec::new()),
            });
        }
    }
    att_arr
}

/// Tranform a protocol payload into a lcsf valid command
///
/// cmd_name: command name to send
///
/// cmd_payload: protocol payload reference
pub fn send_cmd(cmd_name: CmdEnum, cmd_payload: &CmdPayload) -> LcsfValidCmd {
    let mut send_cmd = LcsfValidCmd {
        cmd_id: cmd_name_to_id(cmd_name),
        att_arr: Vec::new(),
    };
    match cmd_name {
        CmdEnum::Sc1 => {}
        CmdEnum::Sc2 => {}
        CmdEnum::Sc3 => {}
        CmdEnum::Cc1 => send_cmd.att_arr = cc1_fill_att(cmd_payload),
        CmdEnum::Cc2 => {}
        CmdEnum::Cc3 => send_cmd.att_arr = cc3_fill_att(cmd_payload),
        CmdEnum::Cc4 => send_cmd.att_arr = cc4_fill_att(cmd_payload),
        CmdEnum::Cc5 => {}
        CmdEnum::Cc6 => send_cmd.att_arr = cc6_fill_att(cmd_payload),
    }
    send_cmd
}

// *** Protocol lcsf descriptor ***

/// Protocol id
pub const PROT_ID: u16 = 0x55;

/// Commands ids
const CMD_ID_SC1: u16 = 0x0;
const CMD_ID_SC2: u16 = 0x1;
const CMD_ID_SC3: u16 = 0x2;
const CMD_ID_CC1: u16 = 0x3;
const CMD_ID_CC2: u16 = 0x4;
const CMD_ID_CC3: u16 = 0x5;
const CMD_ID_CC4: u16 = 0x6;
const CMD_ID_CC5: u16 = 0x7;
const CMD_ID_CC6: u16 = 0x8;

// Ca1 attribute ids
const CA1_ATT_ID_SA1: u16 = 0x0;
const CA1_ATT_ID_SA2: u16 = 0x1;
const CA1_ATT_ID_SA3: u16 = 0x2;

// Ca10 attribute ids
const CA10_ATT_ID_SA1: u16 = 0x0;
const CA10_ATT_ID_CA11: u16 = 0xb;

// Ca11 attribute ids
const CA11_ATT_ID_SA1: u16 = 0x0;
const CA11_ATT_ID_CA12: u16 = 0xa;

// Ca12 attribute ids
const CA12_ATT_ID_SA4: u16 = 0x3;

// Ca2 attribute ids
const CA2_ATT_ID_SA1: u16 = 0x0;
const CA2_ATT_ID_CA3: u16 = 0xb;

// Ca3 attribute ids
const CA3_ATT_ID_SA1: u16 = 0x0;
const CA3_ATT_ID_CA4: u16 = 0xa;

// Ca4 attribute ids
const CA4_ATT_ID_SA4: u16 = 0x3;

// Ca5 attribute ids
const CA5_ATT_ID_SA1: u16 = 0x0;
const CA5_ATT_ID_SA2: u16 = 0x1;
const CA5_ATT_ID_SA3: u16 = 0x2;

// Ca6 attribute ids
const CA6_ATT_ID_SA1: u16 = 0x0;
const CA6_ATT_ID_CA7: u16 = 0xb;

// Ca7 attribute ids
const CA7_ATT_ID_SA1: u16 = 0x0;
const CA7_ATT_ID_CA8: u16 = 0xa;

// Ca8 attribute ids
const CA8_ATT_ID_SA4: u16 = 0x3;

// Ca9 attribute ids
const CA9_ATT_ID_SA1: u16 = 0x0;
const CA9_ATT_ID_SA2: u16 = 0x1;
const CA9_ATT_ID_SA3: u16 = 0x2;

// Cc1 attribute ids
const CC1_ATT_ID_SA1: u16 = 0x0;
const CC1_ATT_ID_SA2: u16 = 0x1;
const CC1_ATT_ID_SA3: u16 = 0x2;
const CC1_ATT_ID_SA4: u16 = 0x3;
const CC1_ATT_ID_SA5: u16 = 0x4;
const CC1_ATT_ID_SA6: u16 = 0x5;
const CC1_ATT_ID_SA7: u16 = 0x6;
const CC1_ATT_ID_SA8: u16 = 0x7;
const CC1_ATT_ID_SA9: u16 = 0x8;
const CC1_ATT_ID_SA10: u16 = 0x9;
const CC1_ATT_ID_SA11: u16 = 0xa;
const CC1_ATT_ID_SA12: u16 = 0xb;
const CC1_ATT_ID_SA13: u16 = 0xc;

// Cc2 attribute ids
const CC2_ATT_ID_SA1: u16 = 0x0;
const CC2_ATT_ID_SA2: u16 = 0x1;
const CC2_ATT_ID_SA3: u16 = 0x2;
const CC2_ATT_ID_SA4: u16 = 0x3;
const CC2_ATT_ID_SA5: u16 = 0x4;
const CC2_ATT_ID_SA6: u16 = 0x5;
const CC2_ATT_ID_SA7: u16 = 0x6;
const CC2_ATT_ID_SA8: u16 = 0x7;
const CC2_ATT_ID_SA9: u16 = 0x8;
const CC2_ATT_ID_SA10: u16 = 0x9;
const CC2_ATT_ID_SA11: u16 = 0xa;
const CC2_ATT_ID_SA12: u16 = 0xb;
const CC2_ATT_ID_SA13: u16 = 0xc;

// Cc3 attribute ids
const CC3_ATT_ID_SA1: u16 = 0x0;
const CC3_ATT_ID_SA2: u16 = 0x1;
const CC3_ATT_ID_SA3: u16 = 0x2;
const CC3_ATT_ID_SA4: u16 = 0x3;
const CC3_ATT_ID_SA5: u16 = 0x4;
const CC3_ATT_ID_SA6: u16 = 0x5;
const CC3_ATT_ID_SA7: u16 = 0x6;
const CC3_ATT_ID_SA8: u16 = 0x7;
const CC3_ATT_ID_SA9: u16 = 0x8;
const CC3_ATT_ID_SA10: u16 = 0x9;
const CC3_ATT_ID_SA11: u16 = 0xa;
const CC3_ATT_ID_SA12: u16 = 0xb;
const CC3_ATT_ID_SA13: u16 = 0xc;

// Cc4 attribute ids
const CC4_ATT_ID_SA1: u16 = 0x0;
const CC4_ATT_ID_CA1: u16 = 0xa;
const CC4_ATT_ID_CA2: u16 = 0xb;

// Cc5 attribute ids
const CC5_ATT_ID_SA2: u16 = 0x1;
const CC5_ATT_ID_CA5: u16 = 0xa;
const CC5_ATT_ID_CA6: u16 = 0xb;

// Cc6 attribute ids
const CC6_ATT_ID_SA4: u16 = 0x3;
const CC6_ATT_ID_CA9: u16 = 0xa;
const CC6_ATT_ID_CA10: u16 = 0xb;

lazy_static! {
    /// Test protocol descriptor
    pub static ref PROT_DESC:LcsfProtDesc = LcsfProtDesc {cmd_desc_arr: vec![
        (CMD_ID_SC1, LcsfCmdDesc {att_desc_arr: Vec::new()}),
        (CMD_ID_SC2, LcsfCmdDesc {att_desc_arr: Vec::new()}),
        (CMD_ID_SC3, LcsfCmdDesc {att_desc_arr: Vec::new()}),
        (CMD_ID_CC1, LcsfCmdDesc {att_desc_arr: vec![
            (CC1_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA3, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA5, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::String, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA6, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA7, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA8, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA9, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA10, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::String, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA11, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint64, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA12, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Float32, subatt_desc_arr: Vec::new()}),
            (CC1_ATT_ID_SA13, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Float64, subatt_desc_arr: Vec::new()}),
        ]}),
        (CMD_ID_CC2, LcsfCmdDesc {att_desc_arr: vec![
            (CC2_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA3, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA5, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::String, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA6, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA7, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA8, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA9, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA10, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::String, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA11, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint64, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA12, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Float32, subatt_desc_arr: Vec::new()}),
            (CC2_ATT_ID_SA13, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Float64, subatt_desc_arr: Vec::new()}),
        ]}),
        (CMD_ID_CC3, LcsfCmdDesc {att_desc_arr: vec![
            (CC3_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA3, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA5, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::String, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA6, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA7, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA8, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA9, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA10, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::String, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA11, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint64, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA12, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Float32, subatt_desc_arr: Vec::new()}),
            (CC3_ATT_ID_SA13, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Float64, subatt_desc_arr: Vec::new()}),
        ]}),
        (CMD_ID_CC4, LcsfCmdDesc {att_desc_arr: vec![
            (CC4_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
            (CC4_ATT_ID_CA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                (CA1_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                (CA1_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
                (CA1_ATT_ID_SA3, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            ]}),
            (CC4_ATT_ID_CA2, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                (CA2_ATT_ID_SA1, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                (CA2_ATT_ID_CA3, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                    (CA3_ATT_ID_SA1, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                    (CA3_ATT_ID_CA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                        (CA4_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
                    ]}),
                ]}),
            ]}),
        ]}),
        (CMD_ID_CC5, LcsfCmdDesc {att_desc_arr: vec![
            (CC5_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
            (CC5_ATT_ID_CA5, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                (CA5_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                (CA5_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
                (CA5_ATT_ID_SA3, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            ]}),
            (CC5_ATT_ID_CA6, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                (CA6_ATT_ID_SA1, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                (CA6_ATT_ID_CA7, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                    (CA7_ATT_ID_SA1, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                    (CA7_ATT_ID_CA8, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                        (CA8_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
                    ]}),
                ]}),
            ]}),
        ]}),
        (CMD_ID_CC6, LcsfCmdDesc {att_desc_arr: vec![
            (CC6_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
            (CC6_ATT_ID_CA9, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                (CA9_ATT_ID_SA1, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                (CA9_ATT_ID_SA2, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Uint16, subatt_desc_arr: Vec::new()}),
                (CA9_ATT_ID_SA3, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint32, subatt_desc_arr: Vec::new()}),
            ]}),
            (CC6_ATT_ID_CA10, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                (CA10_ATT_ID_SA1, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                (CA10_ATT_ID_CA11, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                    (CA11_ATT_ID_SA1, LcsfAttDesc { is_optional: true, data_type: LcsfDataType::Uint8, subatt_desc_arr: Vec::new()}),
                    (CA11_ATT_ID_CA12, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::Subattributes, subatt_desc_arr: vec![
                        (CA12_ATT_ID_SA4, LcsfAttDesc { is_optional: false, data_type: LcsfDataType::ByteArray, subatt_desc_arr: Vec::new()}),
                    ]}),
                ]}),
            ]}),
        ]}),
    ]};
}

// Note: Unit tests will not be generated by Lcsf_Generator
#[cfg(test)]
mod tests {
    use super::*;
    use protocol_test::Ca2AttCa3Payload;
    use protocol_test::Ca3AttCa4Payload;
    use protocol_test::Cc1AttPayload;
    use protocol_test::Cc4AttCa1Payload;
    use protocol_test::Cc4AttCa2Payload;
    use protocol_test::Cc4AttPayload;

    #[test]
    fn test_receive_cmd() {
        let cc2_payload = Cc2AttPayload {
            is_sa6_here: true,
            is_sa7_here: false,
            is_sa8_here: true,
            is_sa9_here: true,
            is_sa10_here: true,
            sa1: 0,
            sa2: 2000,
            sa3: 100000,
            sa4: vec![5, 4, 3, 2, 1],
            sa5: CString::new("Bob").unwrap(),
            sa6: 3,
            sa7: 0,
            sa8: 149999,
            sa9: vec![1, 2, 3, 4, 5],
            sa10: CString::new("Paul").unwrap(),
            sa11: 5000000000,
            sa12: 1.61803398875,
            sa13: 3.14159265359,
        };
        let cc3_payload = Cc3AttPayload {
            is_sa6_here: true,
            is_sa7_here: true,
            is_sa8_here: true,
            is_sa9_here: false,
            is_sa10_here: true,
            sa1: 0,
            sa2: 2000,
            sa3: 100000,
            sa4: vec![5, 4, 3, 2, 1],
            sa5: CString::new("Bob").unwrap(),
            sa6: 3,
            sa7: 4000,
            sa8: 149999,
            sa9: Vec::new(),
            sa10: CString::new("Paul").unwrap(),
            sa11: 5000000000,
            sa12: 1.61803398875,
            sa13: 3.14159265359,
        };
        let cc5_payload = Cc5AttPayload {
            is_ca6_here: true,
            sa2: 255,
            ca5_payload: Cc5AttCa5Payload {
                is_sa3_here: false,
                sa1: 1,
                sa2: 2000,
                sa3: 0,
            },
            ca6_payload: Cc5AttCa6Payload {
                is_sa1_here: false,
                sa1: 0,
                ca7_payload: Ca6AttCa7Payload {
                    is_sa1_here: true,
                    sa1: 3,
                    ca8_payload: Ca7AttCa8Payload {
                        sa4: vec![10, 20, 30, 40, 50],
                    },
                },
            },
        };
        let cc6_payload = Cc6AttPayload {
            is_ca10_here: true,
            sa4: vec![3, 3],
            ca9_payload: Cc6AttCa9Payload {
                is_sa3_here: false,
                sa1: 1,
                sa2: 2000,
                sa3: 0,
            },
            ca10_payload: Cc6AttCa10Payload {
                is_sa1_here: false,
                sa1: 0,
                ca11_payload: Ca10AttCa11Payload {
                    is_sa1_here: true,
                    sa1: 3,
                    ca12_payload: Ca11AttCa12Payload {
                        sa4: vec![5, 5, 5, 5, 5],
                    },
                },
            },
        };
        let valid_sc2_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_SC2,
            att_arr: Vec::new(),
        };
        let valid_sc3_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_SC3,
            att_arr: Vec::new(),
        };
        let valid_cc2_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC2,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xd0, 0x07]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xa0, 0x86, 0x01, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![5, 4, 3, 2, 1]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x42, 0x6f, 0x62, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![3]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(Vec::new()),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xef, 0x49, 0x02, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![1, 2, 3, 4, 5]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x50, 0x61, 0x75, 0x6c, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x00, 0xf2, 0x05, 0x2a, 0x01]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xbd, 0x1b, 0xcf, 0x3f]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![
                        0xea, 0x2e, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,
                    ]),
                },
            ],
        };
        let valid_cc3_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC3,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xd0, 0x07]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xa0, 0x86, 0x01, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![5, 4, 3, 2, 1]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x42, 0x6f, 0x62, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![3]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xa0, 0x0f]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xef, 0x49, 0x02, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(Vec::new()),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x50, 0x61, 0x75, 0x6c, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x00, 0xf2, 0x05, 0x2a, 0x01]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xbd, 0x1b, 0xcf, 0x3f]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![
                        0xea, 0x2e, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,
                    ]),
                },
            ],
        };
        let valid_cc5_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC5,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xff, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![1]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![0xd0, 0x07]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                    ]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::SubattArr(vec![
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::Data(vec![3]),
                                },
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::SubattArr(vec![LcsfValidAtt {
                                        payload: LcsfValidAttPayload::Data(vec![
                                            10, 20, 30, 40, 50,
                                        ]),
                                    }]),
                                },
                            ]),
                        },
                    ]),
                },
            ],
        };
        let valid_cc6_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC6,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![3, 3]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![1]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![0xd0, 0x07]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                    ]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::SubattArr(vec![
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::Data(vec![3]),
                                },
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::SubattArr(vec![LcsfValidAtt {
                                        payload: LcsfValidAttPayload::Data(vec![5, 5, 5, 5, 5]),
                                    }]),
                                },
                            ]),
                        },
                    ]),
                },
            ],
        };
        let (mut cmd_name, mut payload) = receive_cmd(&valid_sc2_cmd);
        assert_eq!(cmd_name, CmdEnum::Sc2);
        assert_eq!(payload, CmdPayload::Empty);
        (cmd_name, payload) = receive_cmd(&valid_sc3_cmd);
        assert_eq!(cmd_name, CmdEnum::Sc3);
        assert_eq!(payload, CmdPayload::Empty);
        (cmd_name, payload) = receive_cmd(&valid_cc2_cmd);
        assert_eq!(cmd_name, CmdEnum::Cc2);
        assert_eq!(payload, CmdPayload::Cc2Payload(cc2_payload));
        (cmd_name, payload) = receive_cmd(&valid_cc3_cmd);
        assert_eq!(cmd_name, CmdEnum::Cc3);
        assert_eq!(payload, CmdPayload::Cc3Payload(cc3_payload));
        (cmd_name, payload) = receive_cmd(&valid_cc5_cmd);
        assert_eq!(cmd_name, CmdEnum::Cc5);
        assert_eq!(payload, CmdPayload::Cc5Payload(cc5_payload));
        (cmd_name, payload) = receive_cmd(&valid_cc6_cmd);
        assert_eq!(cmd_name, CmdEnum::Cc6);
        assert_eq!(payload, CmdPayload::Cc6Payload(cc6_payload));
    }

    #[test]
    fn test_send_cmd() {
        let cc1_payload = Cc1AttPayload {
            is_sa6_here: true,
            is_sa7_here: false,
            is_sa8_here: true,
            is_sa9_here: true,
            is_sa10_here: true,
            sa1: 1,
            sa2: 2001,
            sa3: 100001,
            sa4: vec![6, 5, 4, 3, 2],
            sa5: CString::new("Cpc").unwrap(),
            sa6: 4,
            sa7: 4001,
            sa8: 150000,
            sa9: vec![2, 3, 4, 5, 6],
            sa10: CString::new("Qbvm").unwrap(),
            sa11: 5000000001,
            sa12: 2.61803398875,
            sa13: 4.14159265359,
        };
        let cc3_payload = Cc3AttPayload {
            is_sa6_here: true,
            is_sa7_here: true,
            is_sa8_here: true,
            is_sa9_here: false,
            is_sa10_here: true,
            sa1: 0,
            sa2: 2000,
            sa3: 100000,
            sa4: vec![5, 4, 3, 2, 1],
            sa5: CString::new("Bob").unwrap(),
            sa6: 3,
            sa7: 4000,
            sa8: 149999,
            sa9: Vec::new(),
            sa10: CString::new("Paul").unwrap(),
            sa11: 5000000000,
            sa12: 1.61803398875,
            sa13: 3.14159265359,
        };
        let cc4_payload = Cc4AttPayload {
            is_ca2_here: true,
            sa1: 0,
            ca1_payload: Cc4AttCa1Payload {
                is_sa3_here: false,
                sa1: 2,
                sa2: 2001,
                sa3: 100001,
            },
            ca2_payload: Cc4AttCa2Payload {
                is_sa1_here: false,
                sa1: 3,
                ca3_payload: Ca2AttCa3Payload {
                    is_sa1_here: true,
                    sa1: 4,
                    ca4_payload: Ca3AttCa4Payload {
                        sa4: vec![11, 21, 31, 41, 51],
                    },
                },
            },
        };
        let cc6_payload = Cc6AttPayload {
            is_ca10_here: true,
            sa4: vec![3, 3],
            ca9_payload: Cc6AttCa9Payload {
                is_sa3_here: false,
                sa1: 1,
                sa2: 2000,
                sa3: 0,
            },
            ca10_payload: Cc6AttCa10Payload {
                is_sa1_here: false,
                sa1: 0,
                ca11_payload: Ca10AttCa11Payload {
                    is_sa1_here: true,
                    sa1: 3,
                    ca12_payload: Ca11AttCa12Payload {
                        sa4: vec![5, 5, 5, 5, 5],
                    },
                },
            },
        };
        let valid_sc1_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_SC1,
            att_arr: Vec::new(),
        };
        let valid_sc3_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_SC3,
            att_arr: Vec::new(),
        };
        let valid_cc1_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC1,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![1]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xd1, 0x07]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xa1, 0x86, 0x01]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![6, 5, 4, 3, 2]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x43, 0x70, 0x63, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![4]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(Vec::new()),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xf0, 0x49, 0x02]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![2, 3, 4, 5, 6]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x51, 0x62, 0x76, 0x6d, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x01, 0xf2, 0x05, 0x2a, 0x01]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xde, 0x8d, 0x27, 0x40]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![
                        0x75, 0x17, 0x22, 0xaa, 0xfd, 0x90, 0x10, 0x40,
                    ]),
                },
            ],
        };
        let valid_cc3_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC3,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xd0, 0x07]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xa0, 0x86, 0x01]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![5, 4, 3, 2, 1]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x42, 0x6f, 0x62, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![3]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xa0, 0x0f]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xef, 0x49, 0x02]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(Vec::new()),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x50, 0x61, 0x75, 0x6c, 0x00]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0x00, 0xf2, 0x05, 0x2a, 0x01]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0xbd, 0x1b, 0xcf, 0x3f]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![
                        0xea, 0x2e, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,
                    ]),
                },
            ],
        };
        let valid_cc4_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC4,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![0]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![2]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![0xd1, 0x07]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                    ]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::SubattArr(vec![
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::Data(vec![4]),
                                },
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::SubattArr(vec![LcsfValidAtt {
                                        payload: LcsfValidAttPayload::Data(vec![
                                            11, 21, 31, 41, 51,
                                        ]),
                                    }]),
                                },
                            ]),
                        },
                    ]),
                },
            ],
        };
        let valid_cc6_cmd = LcsfValidCmd {
            cmd_id: CMD_ID_CC6,
            att_arr: vec![
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::Data(vec![3, 3]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![1]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(vec![0xd0, 0x07]),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                    ]),
                },
                LcsfValidAtt {
                    payload: LcsfValidAttPayload::SubattArr(vec![
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::Data(Vec::new()),
                        },
                        LcsfValidAtt {
                            payload: LcsfValidAttPayload::SubattArr(vec![
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::Data(vec![3]),
                                },
                                LcsfValidAtt {
                                    payload: LcsfValidAttPayload::SubattArr(vec![LcsfValidAtt {
                                        payload: LcsfValidAttPayload::Data(vec![5, 5, 5, 5, 5]),
                                    }]),
                                },
                            ]),
                        },
                    ]),
                },
            ],
        };
        let mut valid_cmd = send_cmd(CmdEnum::Sc1, &CmdPayload::Empty);
        assert_eq!(valid_cmd, valid_sc1_cmd);
        valid_cmd = send_cmd(CmdEnum::Sc3, &CmdPayload::Empty);
        assert_eq!(valid_cmd, valid_sc3_cmd);
        valid_cmd = send_cmd(CmdEnum::Cc1, &CmdPayload::Cc1Payload(cc1_payload));
        assert_eq!(valid_cmd, valid_cc1_cmd);
        valid_cmd = send_cmd(CmdEnum::Cc3, &CmdPayload::Cc3Payload(cc3_payload));
        assert_eq!(valid_cmd, valid_cc3_cmd);
        valid_cmd = send_cmd(CmdEnum::Cc4, &CmdPayload::Cc4Payload(cc4_payload));
        assert_eq!(valid_cmd, valid_cc4_cmd);
        valid_cmd = send_cmd(CmdEnum::Cc6, &CmdPayload::Cc6Payload(cc6_payload));
        assert_eq!(valid_cmd, valid_cc6_cmd);
    }
}
