/// <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); } }
/// <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); } }
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("(-)"); }
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); } }
/// <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("(-)"); }
/// <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); } }
/// <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); }