//-----------------------------------------------------------------------
//
// Copyright © 2012 Nils Hammar. All rights reserved.
//
//-----------------------------------------------------------------------
/*
* Software to access vehicle information via the OBD-II connector.
*
* Copyright © 2012 Nils Hammar
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Alternative licensing is possible, see the licensing document.
*
* The above text may not be removed or modified.
*/
namespace DynamicApiLoading.Api.Dynamic.J2534
{
using System;
using System.Runtime.InteropServices;
///
/// J2534 PassThru API Native Method.s
///
public unsafe class NativeMethods : IDisposable
{
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Name of device [not used, set to 'null']
/// Instance ID for device, out parameter.
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruOpen(void* pName, int* pDeviceID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Instance ID for device
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruClose(int DeviceID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Instance ID for device
/// Protocol ID
/// Connection flags
/// Baudrate for device
/// Channel ID (out parameter)
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruConnect(int DeviceID, int ProtocolID, int Flags, int Baudrate, int* pChannelID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruDisconnect(int ChannelID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Pointer to message struct (out parameter)
/// Pointer to number of messages (out parameter)
/// Timeout value.
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruReadMsgs(int ChannelID, PASSTHRU_MSG* pMsg, int* pNumMsgs, int Timeout);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Pointer to message struct(s).
/// Number of messages.
/// Timeout value.
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruWriteMsgs(int ChannelID, PASSTHRU_MSG* pMsg, int* pNumMsgs, int Timeout);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Pointer to message struct.
/// Message ID (out parameter)
/// Timeout value
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruStartPeriodicMsg(int ChannelID, PASSTHRU_MSG* pMsg, int* pMsgID, int TimeInterval);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Message ID
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruStopPeriodicMsg(int ChannelID, int MsgID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Filter type
/// Mask message
/// Pattern message
/// Flow control message
/// Filter ID
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruStartMsgFilter(
int ChannelID,
int FilterType,
PASSTHRU_MSG* pMaskMsg,
PASSTHRU_MSG* pPatternMsg,
PASSTHRU_MSG* pFlowControlMsg,
int* pMsgID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// Filter ID
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruStopMsgFilter(int ChannelID, int MsgID);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Device ID
/// Connector pin number
/// Voltage to set on pin
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruSetProgrammingVoltage(int DeviceID, int Pin, int Voltage);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Device ID
/// Firmware version (out value)
/// DLL version (out value)
/// API version (out value)
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruReadVersion(int DeviceID, byte* pFirmwareVersion, byte* pDllVersion, byte* pApiVersion);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Error description (out value)
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruGetLastError(sbyte* pErrorDescription);
///
/// Type declaration for dynamically loaded J2534 API.
///
/// Channel ID
/// IOCTL ID
/// Pointer to in data.
/// Pointer to out data.
/// Status code.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate int TPassThruIoctl(
int ChannelID,
int IoctlID,
void* pInput,
void* pOutput);
///
/// Gets PassThruOpen method call interface.
///
internal TPassThruOpen PassThruOpen { get; private set; }
///
/// Gets PassThruClose method call interface.
///
internal TPassThruClose PassThruClose { get; private set; }
///
/// Gets PassThruConnect method call interface.
///
internal TPassThruConnect PassThruConnect { get; private set; }
///
/// Gets PassThruDisconnect method call interface.
///
internal TPassThruDisconnect PassThruDisconnect { get; private set; }
///
/// Gets PassThruReadMsgs method call interface.
///
internal TPassThruReadMsgs PassThruReadMsgs { get; private set; }
///
/// Gets PassThruWriteMsgs method call interface.
///
internal TPassThruWriteMsgs PassThruWriteMsgs { get; private set; }
///
/// Gets PassThruStartPeriodicMsg method call interface.
///
internal TPassThruStartPeriodicMsg PassThruStartPeriodicMsg { get; private set; }
///
/// Gets PassThruStopPeriodicMsg method call interface.
///
internal TPassThruStopPeriodicMsg PassThruStopPeriodicMsg { get; private set; }
///
/// Gets PassThruStartMsgFilter method call interface.
///
internal TPassThruStartMsgFilter PassThruStartMsgFilter { get; private set; }
///
/// Gets PassThruStopMsgFilter method call interface.
///
internal TPassThruStopMsgFilter PassThruStopMsgFilter { get; private set; }
///
/// Gets PassThruSetProgrammingVoltage method call interface.
///
internal TPassThruSetProgrammingVoltage PassThruSetProgrammingVoltage { get; private set; }
///
/// Gets PassThruReadVersion method call interface.
///
internal TPassThruReadVersion PassThruReadVersion { get; private set; }
///
/// Gets PassThruGetLastError method call interface.
///
internal TPassThruGetLastError PassThruGetLastError { get; private set; }
///
/// Gets PassThruIoctl method call interface.
///
internal TPassThruIoctl PassThruIoctl { get; private set; }
///
/// DLL instance handle.
///
private SafeLibraryHandle safeLibraryHandle;
///
/// Name of DLL.
///
private string library;
///
/// Initializes a new instance of the class.
///
/// Name of DLL.
public NativeMethods(string library)
{
this.library = library;
this.safeLibraryHandle = SafeLibraryHandle.LoadLibraryW(library);
if (this.safeLibraryHandle.IsInvalid)
{
throw new DynamicLoaderException("LoadLibrary('" + library + "') failed!");
}
this.PassThruOpen = (TPassThruOpen)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruOpen"), typeof(TPassThruOpen));
this.PassThruClose = (TPassThruClose)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruClose"), typeof(TPassThruClose));
this.PassThruConnect = (TPassThruConnect)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruConnect"), typeof(TPassThruConnect));
this.PassThruDisconnect = (TPassThruDisconnect)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruDisconnect"), typeof(TPassThruDisconnect));
this.PassThruReadMsgs = (TPassThruReadMsgs)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruReadMsgs"), typeof(TPassThruReadMsgs));
this.PassThruWriteMsgs = (TPassThruWriteMsgs)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruWriteMsgs"), typeof(TPassThruWriteMsgs));
this.PassThruStartPeriodicMsg = (TPassThruStartPeriodicMsg)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruStartPeriodicMsg"), typeof(TPassThruStartPeriodicMsg));
this.PassThruStopPeriodicMsg = (TPassThruStopPeriodicMsg)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruStopPeriodicMsg"), typeof(TPassThruStopPeriodicMsg));
this.PassThruStartMsgFilter = (TPassThruStartMsgFilter)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruStartMsgFilter"), typeof(TPassThruStartMsgFilter));
this.PassThruStopMsgFilter = (TPassThruStopMsgFilter)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruStopMsgFilter"), typeof(TPassThruStopMsgFilter));
this.PassThruSetProgrammingVoltage = (TPassThruSetProgrammingVoltage)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruSetProgrammingVoltage"), typeof(TPassThruSetProgrammingVoltage));
this.PassThruReadVersion = (TPassThruReadVersion)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruReadVersion"), typeof(TPassThruReadVersion));
this.PassThruGetLastError = (TPassThruGetLastError)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruGetLastError"), typeof(TPassThruGetLastError));
this.PassThruIoctl = (TPassThruIoctl)Marshal.GetDelegateForFunctionPointer(this.getProcedureAddress("PassThruIoctl"), typeof(TPassThruIoctl));
}
///
/// Dispose instance.
///
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Dispose instance.
///
/// 'true' if call to Dispose() was made, 'false' if the class was finalized.
protected virtual void Dispose(bool disposing)
{
this.safeLibraryHandle.Dispose();
}
///
/// Finalizes an instance of the class.
///
~NativeMethods()
{
this.Dispose(false);
}
///
/// Gets the address of the given procedure, throws Exception when failing.
///
/// Name of procedure to locate.
/// Pointer to function
/// Thrown when unable to get address to function.
private IntPtr getProcedureAddress(string functionName)
{
IntPtr pAddress = this.safeLibraryHandle.GetProcAddress(functionName);
if (pAddress == IntPtr.Zero)
{
throw new DynamicLoaderException("GetProcAddress('" + functionName + "'), library '" + this.library + "' failed!");
}
return pAddress;
}
}
}