/* * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause */ import React, { useEffect, useState } from 'react'; import type { AutoDetectTypes } from '@serialport/bindings-cpp'; import { type SerialPortOpenOptions } from 'serialport'; import { ConfirmationDialog } from '../Dialog/Dialog'; import logger from '../logging'; import classNames from '../utils/classNames'; import { createSerialPort, getSerialPortOptions, type SerialPort, } from './SerialPort'; const getCurrentOptions = async ( portPath: string, setSettings: (options: SerialPortOpenOptions) => void, ) => { try { const options = await getSerialPortOptions(portPath); if (options) { setSettings(options); } } catch (err) { console.error(err); } }; interface ConflictingSettingsDialog { isVisible: boolean; onOverwrite: () => void; onCancel: () => void; localSettings: SerialPortOpenOptions; setSerialPortCallback: (serialPort: SerialPort) => void; } const ConflictingSettingsDialog = ({ isVisible, onOverwrite, onCancel, localSettings, setSerialPortCallback, }: ConflictingSettingsDialog) => { const [activeSettings, setSettings] = useState>(); useEffect(() => { if (isVisible) { getCurrentOptions(localSettings.path, setSettings); } }, [isVisible, localSettings.path]); const connectToSelectedSerialPort = async ( overwrite: boolean, newSettings: SerialPortOpenOptions, ) => { try { const port = await createSerialPort(newSettings, { overwrite, settingsLocked: false, }); setSerialPortCallback(port); } catch (error) { const msg = (error as Error).message; if (msg.includes('FAILED_DIFFERENT_SETTINGS')) { onCancel(); } else { console.error( 'Port could not be opened. Verify it is not used by other applications.', ); } } }; return ( { onCancel(); if (activeSettings) { connectToSelectedSerialPort(true, activeSettings); } else { logger.error( 'Could not get the active serial port settings.', ); } }} >

You are about to connect to{' '} {localSettings.path}. This port is already active with different serial settings - most likely it is opened by another nRF Connect app running on your computer.

You may continue with the active serial port settings or choose to overwrite these with the settings you have selected. If you choose to overwrite the active settings, the port will be closed and reopened with the new settings. Alternatively, you can close the port in the other app and try again.

The serial settings depend on the attached device and it's embedded application, and normally the serial port settings for all nRF Connect apps should be the same for a given serial port.

); }; type DisplayConflictingSettings = { activeSettings?: SerialPortOpenOptions; localSettings: SerialPortOpenOptions; }; const DisplayConflictingSettings = ({ activeSettings, localSettings, }: DisplayConflictingSettings) => { const allKeys = Object.keys(localSettings); if (activeSettings) { Object.keys(activeSettings).forEach(key => { if (!allKeys.includes(key)) { allKeys.push(key); } }); } allKeys.splice(allKeys.indexOf('path'), 1); const conflictingSettings = activeSettings ? allKeys.filter( key => activeSettings[key as keyof typeof activeSettings] !== localSettings[key as keyof typeof localSettings], ) : []; return (
{activeSettings ? (
  • Active settings
  • {allKeys.map(key => (
  • {`${key}: `} {prettifyValue( activeSettings[ key as keyof typeof activeSettings ], )}
  • ))}
) : (

Could not retrieve the current settings.

)}
  • Selected settings
  • {allKeys.map(key => (
  • {`${key}: `} {prettifyValue( localSettings[ key as keyof typeof localSettings ], )}
  • ))}
); }; const prettifyValue = (value: unknown) => { if (typeof value === 'boolean') { return value ? 'on' : 'off'; } if (typeof value === 'string' || typeof value === 'number') { return value; } if (value == null) { return 'N/A'; } return JSON.stringify(value); }; export default ConflictingSettingsDialog;