-- #####################
-- BEGIN OF EXECUTION --
-- #####################

-- Script V1 : 26_03_30

-- This table represents the CAN IDs to be tried
local AllIDs = {
    {     0x7E0,      0x7E8},
    {0x18DB33F1, 0x18DAF110},
    {0x18DA40F1, 0x18DAF140}
}

-- This table represents the list of SID, DID, begin position, end position for reading VIN
-- Remember that LUA indices start with 1, not 0 like C/C++ !!!
local reqs = {
    {0x09, 0x0002,  1+1,  1+17},
    {0x22, 0xF190,    1,    17},
    {0x22, 0xF1A0, 11+1, 11+17}
}

-- Local variables for info to user
local lastVin = "Not found!"
local remoteCanId = 0
local localCanId = 0
local vinRequest = 0
local canBitRate = 0
local canPacketPadding = true

local rc, currentBR = can.getCurrentBaudrate()
if (currentBR == 0) then
    --Ask the user here, since there is no current CAN baudrate set and validated
    currentBR = ui.inputValue('Set CAN Baudrate', 'u', 1, 500000, 500000)
end

if (currentBR == nil) then 
    error('No CAN Baudrate provided.')
end

rc = can.init(currentBR)
if (rc ~= 0) then
    error("CAN Init failed! Error: " .. rc .. " (Invalid BUS / Invalid CAN baudrate / Key off)")
end

canBitRate = currentBR

-- Loop on the defined CAN IDs
for i = 1, #AllIDs do

    local rID = AllIDs[i][1]
    local lID = AllIDs[i][2]

    can.setFilters(lID)
    can.enableFilters()

    -- Loop on the defined requests
    for r = 1, #reqs do
        local start = reqs[r][3]
        local stop = reqs[r][4]
        
        rc, data = uds.xmit(rID, reqs[r][1], reqs[r][2], "", lID, 100*3)
        if (data ~= nil) then
            local vin = string.sub(data, start, stop)
            -- If we have not enough data to read a full vin, mark the condition in the output
            if string.len(vin) < 17 then
                vin = vin .. '(BAD LEN)'
            end
            -- salva le informazioni da mostrare nel messaggio all'utente            
            lastVin = vin
            remoteCanId = rID
            localCanId = lID
            vinRequest = (reqs[r][1] << 16) + reqs[r][2]
            --canBitRate = 500000
            canPacketPadding = true
            goto endVINfind
        else
            lastVin = "Error!"
        end
        --Stop here if we have the VIN
    end
end

::endVINfind::

can.disableFilters()
can.uninit()

-- #####################
-- SHOW RESULTS --
-- #####################
local title = "VEHICLE INFORMATION"
local message = "Connected VIN#: %s\nRemote CAN ID: %08X\nLocal CAN ID: %08X\nVIN Request: %08X\nCAN Baudrate: %d\nCAN Packet Padding: %s"
local btn1Text = "EXPORT"
local btn2Text = "EXIT"
message = string.format(message, lastVin, remoteCanId, localCanId, vinRequest, canBitRate, canPacketPadding)
local result = ui.messageBox(title, message, "i", btn1Text, btn2Text)
-- Manages the possible storage of the information file
if (result == btn1Text) then
    -- Save the file
    local fileName = "Vehicle.txt"
    file = io.open(fileName, 'w')
    if (file ~= nil) then
        if (file:write(message ..'\n') ~= nil) then
            file:close()
        else
            file:close()
            file = nil
        end
    end
    -- File storage outcome management
    title = "EXPORT INFO - System"
    btn1Text = "EXIT"
    local messageType
    if (file ~= nil) then
        message = "Export info successfully.\nData save in file '%s'"
        message = string.format(message, fileName)
        messageType = "i"
    else
        message = "Export info failed!"
        messageType = "e"
    end
    ui.messageBox(title, message, messageType, btn1Text)
end
