function dcsample
%DCSAMPLE Example use of the DinkeyChange API in MATLAB.

% Copyright Microcosm Ltd.

    % Load the correct library for this platform
    switch computer()
    case 'PCWIN64'  % 64-bit Windows
        loadlibrary('DinkeyChange64.dll', @dinkeychange64proto, 'alias', 'dinkeychange');
    case 'PCWIN'    % 32-bit Windows
        loadlibrary('DinkeyChange.dll', @dinkeychangewin32proto, 'alias', 'dinkeychange');
    case 'GLNXA64'  % 64-bit Linux
        loadlibrary('DinkeyChange64.so', @dinkeychange64proto, 'alias', 'dinkeychange');
    case 'GLNX86'   % 32-bit Linux
        loadlibrary('DinkeyChange.so', @dinkeychange32proto, 'alias', 'dinkeychange');
    case 'MACI64'   % 64-bit Mac OS X
        loadlibrary('DinkeyChange64.dylib', @dinkeychange64proto, 'alias', 'dinkeychange');
    case 'MAC'      % 32-bit Mac OS X
        loadlibrary('DinkeyChange32.dylib', @dinkeychange32proto, 'alias', 'dinkeychange');
    otherwise
        disp('Error! Platform not supported!');
        return
    end

    % Each of the functions below demonstrates different API functionality.
    % Uncomment the appropriate functions to execute the examples.
    % See the comments in each function for more details about the features
    % that they demonstrate.

    getdongleinfo('dinkeychange');
    %writediagnosticfile('dinkeychange');
    %applyshortupdatecode('dinkeychange');
    %applystronglyencryptedupdatecode('dinkeychange');
    %restorefdlite('dinkeychange');
    %getmachineid('dinkeychange');
    %downloadtempsoftwarekey('dinkeychange');
    %downloaddemosoftwarekey('dinkeychange');

    unloadlibrary('dinkeychange');
end

function getdongleinfo(libName)
% Display information about the dongles attached to this computer

    % Possible values for dcgetinfo's typeMask parameter
    TYPE_MASK_PRO = 1;
    TYPE_MASK_FD = 2;
    TYPE_MASK_ALL = bitor(TYPE_MASK_PRO, TYPE_MASK_FD);

    % Possible values for dcgetinfo's modelMask parameter
    MODEL_MASK_LITE = 1;
    MODEL_MASK_PLUS = 2;
    MODEL_MASK_NET = 4;
    MODEL_MASK_ALL = bitor(bitor(MODEL_MASK_LITE, MODEL_MASK_PLUS), MODEL_MASK_NET);
    MODEL_MASK_DEFAULT = bitor(MODEL_MASK_PLUS, MODEL_MASK_NET);

    % Call the DinkeyChange API
    [retCode, dongleArray] = dcgetinfo(libName, TYPE_MASK_ALL, MODEL_MASK_ALL, '');

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, 0);
       return
    end

    for (i = 1:length(dongleArray))
        disp(sprintf('%3d) Dinkey %s %s', i, dongleArray(i).type_as_string, dongleArray(i).model_as_string));
        disp(sprintf('     Product code : %s', dongleArray(i).product_code));
        disp(sprintf('     Dongle number: %u', dongleArray(i).dongle_number));
        disp(sprintf('     Update number: %u', dongleArray(i).update_number));
        disp(sprintf('\n'));
    end
end

function writediagnosticfile(libName)
% Write diagnostic information about the dongles attached to this computer
% to an encrypted file.

    filename = '!!!! REPLACE THIS WITH THE NAME OF THE FILE TO WRITE TO';

    % Call the DinkeyChange API
    retCode = dcgetdiagnosticinfo(libName, filename);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, 0);
       return
    end

    disp(['Successfully wrote diagnostic information to ' filename]);
end

function applyshortupdatecode(libName)
% Update a dongle attached to this computer using a short update code

    % Call the DinkeyChange API
    [retCode, confirmationCode, extErr] = dcdoupdatecodestring(libName, '!!!! REPLACE THIS WITH A VALID UPDATE CODE STRING');

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    disp('Successfully updated dongle');
    disp(['Confirmation code: ' sprintf('%X', confirmationCode)]);
end

function applystronglyencryptedupdatecode(libName)
% Update a dongle attached to this computer using a strongly encrypted
% update code file

    % Call the DinkeyChange API
    [retCode, confirmationCode, extErr] = dcdoupdatecodefromfile(libName, '!!!! REPLACE THIS WITH A VALID UPDATE CODE FILENAME');

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    disp('Successfully updated dongle');
    disp(['Confirmation code: ' sprintf('%X', confirmationCode)]);
end

function restorefdlite(libName)
% Restore the required hidden file on a Dinkey FD Lite dongle.

    % Call the DinkeyChange API
    retCode = dcrestorefdlite(libName);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, 0);
       return
    end

    disp('Successfully restored FD Lite dongle');
end

function getmachineid(libName)
% Display this computer's machine ID

    % Call the DinkeyChange API
    [retCode, machineId, extErr] = dcgetmachineid(libName);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    disp(['The machine ID for this computer is: ' sprintf('%X', machineId)]);
end

function downloadtempsoftwarekey(libName)
% Download and install a temporary software key on this computer

    % First call the DinkeyChange API to get the machine ID
    [retCode, machineId, extErr] = dcgetmachineid(libName);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    % Then call the API again to install the software key
    [retCode, extErr] = dcdownloadtempsoftwarekey(libName, machineId);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    disp('The temporary software key has been succesfully installed.');
end

function downloaddemosoftwarekey(libName)
% Download and install a demo software key on this computer

    % Possible values for dcdownloaddemosoftwarekey's model parameter
    SWKEY_MODEL_DEFAULT = -1;
    SWKEY_MODEL_PRO_LITE = 0;
    SWKEY_MODEL_PRO_PLUS = 1;
    SWKEY_MODEL_PRO_NET = 2;
    SWKEY_MODEL_FD_LITE = 3;
    SWKEY_MODEL_FD_PLUS = 4;
    SWKEY_MODEL_FD_NET = 5;

    % First call the DinkeyChange API to get the machine ID
    [retCode, machineId, extErr] = dcgetmachineid(libName);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    % Then call the API again to install the software key
    [retCode, extErr] = dcdownloaddemosoftwarekey(libName, machineId, '!!!! REPLACE THIS WITH THE PRODUCT CODE OF THE KEY', SWKEY_MODEL_DEFAULT);

    % Check the return value
    if (retCode ~= 0)
       displayerror(retCode, extErr);
       return
    end

    disp('The demo software key has been succesfully installed.');
end

% An example of error reporting
% Displays descriptions for some common error codes
function displayerror(retCode, extErr)
    switch retCode
        case 401
            disp('Error! No dongles detected that meet the search criteria.');
        case 409
            disp('Error! The dongle detected has not been programmed by DinkeyAdd.');
        case 754
            disp('Error! The specified output file could not be written to.');
        case 758
            disp('Error! Cannot open the file specified.');
        case 759
            disp('Error! The file specified is not a valid update code file.');
        case 762
            disp('Error! The update code contains invalid characters.');
        case 763
            disp('Error! Invalid update code.');
        case 764
            disp('Error! The update code was entered incorrectly, or the update code file is corrupt.');
        case 765
            disp('Error! The update code does not match any dongle attached to your computer.');
        case 766
            disp('Error! The update number for this update code is too high. If you have more than one update code, ensure that you apply them in the correct order.');
        case 767
            disp('Error! You have already entered this update code.');
        case 1905
            disp('Error! There is no temporary software key available for download.');
        case 1907
            disp('Error! The temporary software key has expired. Cannot download it.');
        case 1910
            disp('Error! The temporary software key has already been downloaded.');
        otherwise
            str = sprintf('An error occurred checking the dongle. Error: %d, Extended Error: %d', retCode, extErr);
            disp(str);
    end
end
