Esempio n. 1
0
 /// <summary>
 /// 启动CAN设备
 /// </summary>
 public void StartCAN()
 {
     try
     {
         if (!_mConnected)
         {
             return;
         }
         if (CanApi.VCI_StartCAN(
                 _mDeviceType, _canSetting.DeviceIndex,
                 _canSetting.CanIndex) != CanApi.STATUS_OK)
         {
             throw new CanException("启动CAN失败");
         }
         //_ReceviedList.Clear();
         //启动接收线程
         _CanReceviedThread = new Thread(new ThreadStart(ReceiveDataProc));
         _CanReceviedThread.IsBackground = true;
         _CanReceviedThread.Start();
     }
     catch (Exception e)
     {
         LogHelper.WriteErrorLog(e.Message);
     }
 }
Esempio n. 2
0
        /// <summary>
        /// 连接CAN设备
        /// </summary>
        public void ConnectCANDevice()
        {
            try
            {
                if (!_mConnected)
                {
                    _openCode = CanApi.VCI_OpenDevice(_mDeviceType, _canSetting.DeviceIndex, 0);    //open device
                    if (_openCode != CanApi.STATUS_OK)
                    {
                        throw new CanException("打开设备失败,VCI_OpenDevice 返回值:" + _openCode);
                    }
                    _CanConfig = _canSetting.GetConfig();
                    _initCode  = CanApi.VCI_InitCAN(
                        _mDeviceType,
                        _canSetting.DeviceIndex,
                        _canSetting.CanIndex,
                        ref _CanConfig);    //init device
                    if (_initCode != CanApi.STATUS_OK)
                    {
                        LogHelper.WriteErrorLog("初始化CAN失败,VCI_InitCAN 返回值:" + _initCode);
                        CanApi.VCI_CloseDevice(_mDeviceType, _canSetting.DeviceIndex);
                    }

                    if (_openCode == CanApi.STATUS_OK && _initCode == CanApi.STATUS_OK)
                    {
                        _mConnected = true;
                    }
                }
            }
            catch (CanException e)
            {
                LogHelper.WriteErrorLog(e.Message);
            }
        }
Esempio n. 3
0
 public void CloseCANDevice()
 {
     try
     {
         _mConnected = false;
         Thread.Sleep(300); //等待接收线程退出
         CanApi.VCI_CloseDevice(_mDeviceType, _canSetting.DeviceIndex);
     }
     catch (Exception e)
     {
         LogHelper.WriteInfoLog("接收线程退出\n" + e.Message);
     }
 }
        public override bool Init()
        {
            log.Info("()");

            bool res = false;

            try
            {
                canIpnsLastSequenceNumber = Config.Configuration.CanIpnsLastSequenceNumber;
                api = new CanApi(Config.Configuration.CanEndPoint, ShutdownSignaling);

                // Construct profile server's contact information CAN object.
                canContactInformation = new CanProfileServerContact()
                {
                    PublicKey   = ProtocolHelper.ByteArrayToByteString(Config.Configuration.Keys.PublicKey),
                    IpAddress   = ProtocolHelper.ByteArrayToByteString(Config.Configuration.ExternalServerAddress.GetAddressBytes()),
                    PrimaryPort = (uint)Config.Configuration.ServerRoles.GetRolePort((uint)ServerRole.Primary)
                };


                initThread = new Thread(new ThreadStart(InitThread));
                initThread.Start();

                RegisterCronJobs();

                res         = true;
                Initialized = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            if (!res)
            {
                ShutdownSignaling.SignalShutdown();

                if ((initThread != null) && !initThreadFinished.WaitOne(25000))
                {
                    log.Error("Init thread did not terminated in 25 seconds.");
                }
            }

            log.Info("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Refreshes profile server's IPNS record.
        /// </summary>
        public async Task IpnsRecordRefreshAsync()
        {
            log.Trace("()");

            if (canContactInformationHash == null)
            {
                log.Debug("No CAN contact information hash, can't refresh IPNS record, will try later.");
                log.Trace("(-)");
                return;
            }

            canIpnsLastSequenceNumber++;
            canIpnsRecord = CanApi.CreateIpnsRecord(canContactInformationHash, canIpnsLastSequenceNumber, IpnsRecordExpirationTimeSeconds);
            CanRefreshIpnsResult cres = await api.RefreshIpnsRecord(canIpnsRecord, Config.Configuration.Keys.PublicKey);

            if (cres.Success)
            {
                using (UnitOfWork unitOfWork = new UnitOfWork())
                {
                    await unitOfWork.AcquireLockAsync(UnitOfWork.SettingsLock);

                    try
                    {
                        Setting setting = new Setting("CanIpnsLastSequenceNumber", canIpnsLastSequenceNumber.ToString());
                        await unitOfWork.SettingsRepository.AddOrUpdate(setting);

                        await unitOfWork.SaveThrowAsync();

                        log.Debug("CanIpnsLastSequenceNumber updated in database to new value {0}.", setting.Value);
                    }
                    catch (Exception e)
                    {
                        log.Error("Unable to update CanIpnsLastSequenceNumber in the database to new value {0}, exception: {1}", canIpnsLastSequenceNumber, e.ToString());
                    }

                    unitOfWork.ReleaseLock(UnitOfWork.SettingsLock);
                }
            }
            else if (cres.Message != "Shutdown")
            {
                log.Error("Failed to refresh profile server's IPNS record.");
            }

            log.Trace("(-)");
        }
Esempio n. 6
0
 public bool SendData(string frameID, string timeStamp,
                      int frameFormat, int frameType, string frameData,
                      int frameSendType)
 {
     if (!_mConnected)
     {
         return(false);
     }
     CanApi.VCI_CAN_OBJ[] frameInfo = new CanApi.VCI_CAN_OBJ[1];
     frameInfo = _frameWrapper.Wrapper(frameID, timeStamp, frameFormat,
                                       frameType, frameData, frameSendType);
     if (
         CanApi.VCI_Transmit(_mDeviceType, _canSetting.DeviceIndex
                             , _canSetting.CanIndex, ref frameInfo[0], 1) == CanApi.STATUS_OK)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Esempio n. 7
0
 /// <summary>
 /// 复位CAN设备
 /// </summary>
 public void ResetCANDevice()
 {
     try
     {
         if (!_mConnected)
         {
             return;
         }
         if (CanApi.VCI_ResetCAN(_mDeviceType, _canSetting.DeviceIndex,
                                 _canSetting.CanIndex) == CanApi.STATUS_OK)
         {
             return;
         }
         else
         {
             throw new CanException("复位CAN失败");
         }
     }
     catch (CanException e)
     {
         LogHelper.WriteErrorLog(e.Message);
     }
 }
        /// <summary>
        /// Thread that is initializes CAN objects during the profile server startup.
        /// </summary>
        private async void InitThread()
        {
            log.Info("()");

            initThreadFinished.Reset();

            if (Config.Configuration.CanProfileServerContactInformationHash != null)
            {
                log.Debug("Old CAN object hash is '{0}', object {1} change.", Config.Configuration.CanProfileServerContactInformationHash.ToBase58(), Config.Configuration.CanProfileServerContactInformationChanged ? "DID" : "did NOT");
            }
            else
            {
                log.Debug("No CAN object found.");
            }

            bool deleteOldObject = Config.Configuration.CanProfileServerContactInformationChanged && (Config.Configuration.CanProfileServerContactInformationHash != null);

            byte[] canObject = canContactInformation.ToByteArray();
            log.Trace("CAN object: {0}", canObject.ToHex());

            while (!ShutdownSignaling.IsShutdown)
            {
                // First delete old CAN object if there is any.
                bool error = false;
                if (deleteOldObject)
                {
                    string          objectPath = CanApi.CreateIpfsPathFromHash(Config.Configuration.CanProfileServerContactInformationHash);
                    CanDeleteResult cres       = await api.CanDeleteObject(objectPath);

                    if (cres.Success)
                    {
                        log.Info("Old CAN object hash '{0}' deleted.", Config.Configuration.CanProfileServerContactInformationHash.ToBase58());
                    }
                    else
                    {
                        log.Warn("Failed to delete old CAN object hash '{0}', error message '{1}', will retry.", Config.Configuration.CanProfileServerContactInformationHash.ToBase58(), cres.Message);
                        error = true;
                    }
                }
                else
                {
                    log.Trace("No old object to delete.");
                }

                if (ShutdownSignaling.IsShutdown)
                {
                    break;
                }
                if (!error)
                {
                    if (Config.Configuration.CanProfileServerContactInformationChanged)
                    {
                        // Now upload the new object.
                        CanUploadResult cres = await api.CanUploadObject(canObject);

                        if (cres.Success)
                        {
                            canContactInformationHash = cres.Hash;
                            log.Info("New CAN object hash '{0}' added.", canContactInformationHash.ToBase58());
                            break;
                        }

                        log.Warn("Unable to add new object to CAN, error message: '{0}'", cres.Message);
                    }
                    else
                    {
                        canContactInformationHash = Config.Configuration.CanProfileServerContactInformationHash;
                        log.Info("CAN object unchanged since last time, hash is '{0}'.", canContactInformationHash.ToBase58());
                        break;
                    }
                }

                // Retry in 10 seconds.
                try
                {
                    await Task.Delay(10000, ShutdownSignaling.ShutdownCancellationTokenSource.Token);
                }
                catch
                {
                    // Catch cancellation exception.
                }
            }


            if (canContactInformationHash != null)
            {
                if (Config.Configuration.CanProfileServerContactInformationChanged)
                {
                    // Save the new data to the database.
                    if (!await SaveProfileServerContactInformation())
                    {
                        log.Error("Failed to save new profile server contact information values to database.");
                    }
                }

                // Finally, start IPNS record refreshing timer.
                await IpnsRecordRefreshAsync();
            }


            initThreadFinished.Set();

            log.Info("(-)");
        }
Esempio n. 9
0
        /// <summary>
        ///  接收数据处理函数
        /// </summary>
        void ReceiveDataProc()
        {
            try
            {
                //接收到数据长度
                int _receivedLen = 0;
                //CAN ERR INFO
                CanApi.VCI_ERR_INFO _CanErrInfo = new CanApi.VCI_ERR_INFO();
                _CanErrInfo.Passive_ErrData = new byte[3];
                //CAN Frames
                CanApi.VCI_CAN_OBJ[] _CanRawFrames = new CanApi.VCI_CAN_OBJ[50];
                while (true)
                {
                    Thread.Sleep(10);
                    if (!_mConnected)
                    {
                        break;
                    }
                    _receivedLen = 0;
                    _receivedLen = (int)CanApi.VCI_Receive(
                        _mDeviceType, _DeviceIndex,
                        _CanIndex,
                        ref _CanRawFrames[0], 50, 200);
                    if (_receivedLen <= 0)
                    {
                        //注意:如果没有读到数据则必须调用此函数来读取出当前的错误码,
                        //千万不能省略这一步(即使你可能不想知道错误码是什么)
                        CanApi.VCI_ReadErrInfo(
                            _mDeviceType, _DeviceIndex,
                            _CanIndex, ref _CanErrInfo);
                    }
                    else
                    {
                        for (int i = 0; i < _receivedLen; i++)
                        {
                            if (i > _CanRawFrames.Length)
                            {
                                break;
                            }
                            _CanRawFrame = _CanRawFrames[i];
                            //ID
                            _frameID = string.Format("{0:X8}", _CanRawFrame.ID);
                            //timestamp
                            if (_CanRawFrame.TimeFlag == 0)
                            {
                                _timestamp = "无";
                            }
                            else
                            {
                                _timestamp = string.Format("{0:X}", _CanRawFrame.TimeStamp);
                            }
                            //FrameFormat
                            if (_CanRawFrame.RemoteFlag == 0)
                            {
                                _frameFormat = "数据帧";
                            }
                            else
                            {
                                _frameFormat = "远程帧";
                            }
                            //FrameType
                            if (_CanRawFrame.ExternFlag == 0)
                            {
                                _frameType = "标准帧";
                            }
                            else
                            {
                                _frameType = "扩展帧";
                            }
                            //Data
                            _stringBuilder.Clear();
                            for (int j = 0; j < _CanRawFrame.DataLen; j++)
                            {
                                if (_CanRawFrame.Data.Length <= j)
                                {
                                    break;
                                }
                                _stringBuilder.AppendFormat("{0:X2}", _CanRawFrame.Data[j]);
                            }
                            _frameData = _stringBuilder.ToString();

                            _ReceviedList.Add(new FrameInfo(_frameID, _timestamp, _frameFormat, _frameType, _frameData));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LogHelper.WriteErrorLog("CANhelper.ReceiveDataProc." + e.Message);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Initializes the database, or loads database configuration if the database already exists.
        /// </summary>
        /// <returns>true if the function succeeds, false otherwise.</returns>
        public bool InitializeDbSettings()
        {
            log.Trace("()");

            bool res = false;

            CanIpnsLastSequenceNumber = 0;
            CanProximityServerContactInformationChanged = false;

            using (UnitOfWork unitOfWork = new UnitOfWork())
            {
                log.Trace("Loading database settings.");
                Setting initialized = unitOfWork.SettingsRepository.Get(s => s.Name == "Initialized").FirstOrDefault();
                if ((initialized != null) && (!string.IsNullOrEmpty(initialized.Value)) && (initialized.Value == "true"))
                {
                    Setting privateKeyHex             = unitOfWork.SettingsRepository.Get(s => s.Name == "PrivateKeyHex").FirstOrDefault();
                    Setting publicKeyHex              = unitOfWork.SettingsRepository.Get(s => s.Name == "PublicKeyHex").FirstOrDefault();
                    Setting expandedPrivateKeyHex     = unitOfWork.SettingsRepository.Get(s => s.Name == "ExpandedPrivateKeyHex").FirstOrDefault();
                    Setting externalServerAddress     = unitOfWork.SettingsRepository.Get(s => s.Name == "ExternalServerAddress").FirstOrDefault();
                    Setting primaryPort               = unitOfWork.SettingsRepository.Get(s => s.Name == "PrimaryPort").FirstOrDefault();
                    Setting canIpnsLastSequenceNumber = unitOfWork.SettingsRepository.Get(s => s.Name == "CanIpnsLastSequenceNumber").FirstOrDefault();
                    Setting canProximityServerContactInformationHash = unitOfWork.SettingsRepository.Get(s => s.Name == "CanProximityServerContactInformationHash").FirstOrDefault();
                    Setting locLocationLatitude  = unitOfWork.SettingsRepository.Get(s => s.Name == "LocLocationLatitude").FirstOrDefault();
                    Setting locLocationLongitude = unitOfWork.SettingsRepository.Get(s => s.Name == "LocLocationLongitude").FirstOrDefault();

                    bool havePrivateKey                = (privateKeyHex != null) && !string.IsNullOrEmpty(privateKeyHex.Value);
                    bool havePublicKey                 = (publicKeyHex != null) && !string.IsNullOrEmpty(publicKeyHex.Value);
                    bool haveExpandedPrivateKey        = (expandedPrivateKeyHex != null) && !string.IsNullOrEmpty(expandedPrivateKeyHex.Value);
                    bool havePrimaryPort               = primaryPort != null;
                    bool haveExternalServerAddress     = (externalServerAddress != null) && !string.IsNullOrEmpty(externalServerAddress.Value);
                    bool haveCanIpnsLastSequenceNumber = canIpnsLastSequenceNumber != null;
                    bool haveCanContactInformationHash = (canProximityServerContactInformationHash != null) && !string.IsNullOrEmpty(canProximityServerContactInformationHash.Value);

                    if (havePrivateKey &&
                        havePublicKey &&
                        haveExpandedPrivateKey &&
                        havePrimaryPort &&
                        haveExternalServerAddress &&
                        haveCanIpnsLastSequenceNumber)
                    {
                        Keys = new KeysEd25519();
                        Keys.PrivateKeyHex = privateKeyHex.Value;
                        Keys.PrivateKey    = Keys.PrivateKeyHex.FromHex();

                        Keys.PublicKeyHex = publicKeyHex.Value;
                        Keys.PublicKey    = Keys.PublicKeyHex.FromHex();

                        Keys.ExpandedPrivateKeyHex = expandedPrivateKeyHex.Value;
                        Keys.ExpandedPrivateKey    = Keys.ExpandedPrivateKeyHex.FromHex();

                        bool error = false;
                        if (!UInt64.TryParse(canIpnsLastSequenceNumber.Value, out CanIpnsLastSequenceNumber))
                        {
                            log.Error("Invalid CanIpnsLastSequenceNumber value '{0}' in the database.", canIpnsLastSequenceNumber.Value);
                            error = true;
                        }

                        if (!error)
                        {
                            if (haveCanContactInformationHash)
                            {
                                CanProximityServerContactInformationHash = Base58Encoding.Encoder.DecodeRaw(canProximityServerContactInformationHash.Value);
                                if (CanProximityServerContactInformationHash == null)
                                {
                                    log.Error("Invalid CanProximityServerContactInformationHash value '{0}' in the database.", canProximityServerContactInformationHash.Value);
                                    error = true;
                                }
                            }
                            else
                            {
                                CanProximityServerContactInformationChanged = true;
                            }
                        }

                        if (!error)
                        {
                            // Database settings contain information on previous external network address and primary port values.
                            // If they are different to what was found in the configuration file, it means the contact
                            // information of the proximity server changed. Such a change must be propagated to proximity server's
                            // CAN records.
                            string configExternalServerAddress = ExternalServerAddress.ToString();
                            if (configExternalServerAddress != externalServerAddress.Value)
                            {
                                log.Info("Network interface address in configuration file is different from the database value.");

                                CanProximityServerContactInformationChanged = true;
                            }

                            string configPrimaryPort = ServerRoles.GetRolePort((uint)ServerRole.Primary).ToString();
                            if (configPrimaryPort != primaryPort.Value)
                            {
                                log.Info("Primary port in configuration file is different from the database value.");

                                CanProximityServerContactInformationChanged = true;
                            }
                        }

                        if (!error)
                        {
                            if ((locLocationLatitude != null) && (locLocationLongitude != null))
                            {
                                decimal lat;
                                decimal lon;
                                if (decimal.TryParse(locLocationLatitude.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out lat) &&
                                    decimal.TryParse(locLocationLongitude.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out lon))
                                {
                                    LocLocation = new GpsLocation(lat, lon);
                                    log.Info("Server GPS location is [{0}].", LocLocation);
                                }
                            }
                        }

                        res = !error;
                    }
                    else
                    {
                        log.Error("Database settings are corrupted, DB has to be reinitialized.");
                        if (!havePrivateKey)
                        {
                            log.Debug("Private key is missing.");
                        }
                        if (!havePublicKey)
                        {
                            log.Debug("Public key is missing.");
                        }
                        if (!haveExpandedPrivateKey)
                        {
                            log.Debug("Expanded private key is missing.");
                        }
                        if (!havePrimaryPort)
                        {
                            log.Debug("Primary port is missing.");
                        }
                        if (!haveExternalServerAddress)
                        {
                            log.Debug("External server address is missing.");
                        }
                        if (!haveCanIpnsLastSequenceNumber)
                        {
                            log.Debug("Last CAN IPNS sequence number is missing.");
                        }
                        if (!haveCanContactInformationHash)
                        {
                            log.Debug("CAN contact information hash is missing.");
                        }
                    }
                }

                if (!res)
                {
                    log.Info("Database settings are not initialized, initializing now ...");

                    unitOfWork.SettingsRepository.Clear();
                    unitOfWork.Save();

                    Keys = Ed25519.GenerateKeys();

                    Setting privateKey = new Setting("PrivateKeyHex", Keys.PrivateKeyHex);
                    unitOfWork.SettingsRepository.Insert(privateKey);

                    Setting publicKey = new Setting("PublicKeyHex", Keys.PublicKeyHex);
                    unitOfWork.SettingsRepository.Insert(publicKey);

                    Setting expandedPrivateKey = new Setting("ExpandedPrivateKeyHex", Keys.ExpandedPrivateKeyHex);
                    unitOfWork.SettingsRepository.Insert(expandedPrivateKey);

                    Setting externalServerAddress = new Setting("ExternalServerAddress", ExternalServerAddress.ToString());
                    unitOfWork.SettingsRepository.Insert(externalServerAddress);

                    Setting primaryPort = new Setting("PrimaryPort", ServerRoles.GetRolePort((uint)ServerRole.Primary).ToString());
                    unitOfWork.SettingsRepository.Insert(primaryPort);

                    Setting canIpnsLastSequenceNumber = new Setting("CanIpnsLastSequenceNumber", "0");
                    unitOfWork.SettingsRepository.Insert(canIpnsLastSequenceNumber);

                    initialized = new Setting("Initialized", "true");
                    unitOfWork.SettingsRepository.Insert(initialized);


                    if (unitOfWork.Save())
                    {
                        log.Info("Database initialized successfully.");

                        CanProximityServerContactInformationChanged = true;
                        res = true;
                    }
                    else
                    {
                        log.Error("Unable to save settings to DB.");
                    }
                }
            }

            if (res)
            {
                Settings["Keys"] = Keys;
                Settings["CanIpnsLastSequenceNumber"] = CanIpnsLastSequenceNumber;
                Settings["CanProximityServerContactInformationHash"]    = CanProximityServerContactInformationHash;
                Settings["CanProximityServerContactInformationChanged"] = CanProximityServerContactInformationChanged;

                log.Debug("Server public key hex is '{0}'.", Keys.PublicKeyHex);
                log.Debug("Server network ID is '{0}'.", Crypto.Sha256(Keys.PublicKey).ToHex());
                log.Debug("Server network ID in CAN encoding is '{0}'.", CanApi.PublicKeyToId(Keys.PublicKey).ToBase58());
                log.Debug("Server primary external contact is '{0}:{1}'.", ExternalServerAddress, ServerRoles.GetRolePort((uint)ServerRole.Primary));
            }

            log.Trace("(-):{0}", res);
            return(res);
        }