Commit fe3378eab125b6f59ae316890f3ed4384b16f114

Authored by Vladyslav_Prykhodko
1 parent 75801045

UI: Add SNMP device transport configuration

... ... @@ -51,6 +51,13 @@ public class SnmpDeviceTransportConfiguration implements DeviceTransportConfigur
51 51 private String privacyPassphrase;
52 52 private String engineId;
53 53
  54 + public SnmpDeviceTransportConfiguration() {
  55 + this.host = "localhost";
  56 + this.port = 161;
  57 + this.protocolVersion = SnmpProtocolVersion.V2C;
  58 + this.community = "public";
  59 + }
  60 +
54 61 @Override
55 62 public DeviceTransportType getType() {
56 63 return DeviceTransportType.SNMP;
... ... @@ -76,7 +83,7 @@ public class SnmpDeviceTransportConfiguration implements DeviceTransportConfigur
76 83 isValid = StringUtils.isNotBlank(username) && StringUtils.isNotBlank(securityName)
77 84 && contextName != null && authenticationProtocol != null
78 85 && StringUtils.isNotBlank(authenticationPassphrase)
79   - && privacyProtocol != null && privacyPassphrase != null && engineId != null;
  86 + && privacyProtocol != null && StringUtils.isNotBlank(privacyPassphrase) && engineId != null;
80 87 break;
81 88 }
82 89 }
... ...
... ... @@ -179,7 +179,7 @@ export class SnmpDeviceProfileCommunicationConfigComponent implements OnInit, On
179 179 if (isUndefinedOrNull(value)) {
180 180 value = {
181 181 spec: this.getFirstUnusedSeverity(),
182   - queryingFrequencyMs: 0,
  182 + queryingFrequencyMs: 5000,
183 183 mappings: null
184 184 };
185 185 }
... ... @@ -196,7 +196,7 @@ export class SnmpDeviceProfileCommunicationConfigComponent implements OnInit, On
196 196 ).subscribe(spec => {
197 197 if (this.isShowFrequency(spec)) {
198 198 form.addControl('queryingFrequencyMs',
199   - this.fb.control(0, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]));
  199 + this.fb.control(5000, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]));
200 200 } else {
201 201 form.removeControl('queryingFrequencyMs');
202 202 }
... ...
... ... @@ -40,6 +40,9 @@
40 40 .mat-form-field-underline {
41 41 bottom: 0;
42 42 }
  43 + .mat-form-field-subscript-wrapper{
  44 + margin-top: 1.8em;
  45 + }
43 46 }
44 47 }
45 48 }
... ...
... ... @@ -86,7 +86,7 @@ export class SnmpDeviceProfileTransportConfigurationComponent implements OnInit,
86 86
87 87 ngOnInit(): void {
88 88 this.snmpDeviceProfileTransportConfigurationFormGroup = this.fb.group({
89   - timeoutMs: [0, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
  89 + timeoutMs: [500, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
90 90 retries: [0, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
91 91 communicationConfigs: [null, Validators.required],
92 92 });
... ...
... ... @@ -15,7 +15,16 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
19 28 import { Store } from '@ngrx/store';
20 29 import { AppState } from '@app/core/core.state';
21 30 import { coerceBooleanProperty } from '@angular/cdk/coercion';
... ... @@ -29,13 +38,20 @@ import {
29 38 selector: 'tb-device-data',
30 39 templateUrl: './device-data.component.html',
31 40 styleUrls: [],
32   - providers: [{
33   - provide: NG_VALUE_ACCESSOR,
34   - useExisting: forwardRef(() => DeviceDataComponent),
35   - multi: true
36   - }]
  41 + providers: [
  42 + {
  43 + provide: NG_VALUE_ACCESSOR,
  44 + useExisting: forwardRef(() => DeviceDataComponent),
  45 + multi: true
  46 + },
  47 + {
  48 + provide: NG_VALIDATORS,
  49 + useExisting: forwardRef(() => DeviceDataComponent),
  50 + multi: true
  51 + },
  52 + ]
37 53 })
38   -export class DeviceDataComponent implements ControlValueAccessor, OnInit {
  54 +export class DeviceDataComponent implements ControlValueAccessor, OnInit, Validator {
39 55
40 56 deviceDataFormGroup: FormGroup;
41 57
... ... @@ -97,6 +113,12 @@ export class DeviceDataComponent implements ControlValueAccessor, OnInit {
97 113 this.deviceDataFormGroup.patchValue({transportConfiguration: value?.transportConfiguration}, {emitEvent: false});
98 114 }
99 115
  116 + validate(): ValidationErrors | null {
  117 + return this.deviceDataFormGroup.valid ? null : {
  118 + deviceDataForm: false
  119 + };
  120 + }
  121 +
100 122 private updateModel() {
101 123 let deviceData: DeviceData = null;
102 124 if (this.deviceDataFormGroup.valid) {
... ...
... ... @@ -15,27 +15,39 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
19 28 import { Store } from '@ngrx/store';
20 29 import { AppState } from '@app/core/core.state';
21 30 import { coerceBooleanProperty } from '@angular/cdk/coercion';
22   -import {
23   - DeviceTransportConfiguration,
24   - DeviceTransportType
25   -} from '@shared/models/device.models';
  31 +import { DeviceTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
26 32 import { deepClone } from '@core/utils';
27 33
28 34 @Component({
29 35 selector: 'tb-device-transport-configuration',
30 36 templateUrl: './device-transport-configuration.component.html',
31 37 styleUrls: [],
32   - providers: [{
33   - provide: NG_VALUE_ACCESSOR,
34   - useExisting: forwardRef(() => DeviceTransportConfigurationComponent),
35   - multi: true
36   - }]
  38 + providers: [
  39 + {
  40 + provide: NG_VALUE_ACCESSOR,
  41 + useExisting: forwardRef(() => DeviceTransportConfigurationComponent),
  42 + multi: true
  43 + },
  44 + {
  45 + provide: NG_VALIDATORS,
  46 + useExisting: forwardRef(() => DeviceTransportConfigurationComponent),
  47 + multi: true
  48 + }]
37 49 })
38   -export class DeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit {
  50 +export class DeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit, Validator {
39 51
40 52 deviceTransportType = DeviceTransportType;
41 53
... ... @@ -92,7 +104,15 @@ export class DeviceTransportConfigurationComponent implements ControlValueAccess
92 104 if (configuration) {
93 105 delete configuration.type;
94 106 }
95   - this.deviceTransportConfigurationFormGroup.patchValue({configuration}, {emitEvent: false});
  107 + setTimeout(() => {
  108 + this.deviceTransportConfigurationFormGroup.patchValue({configuration}, {emitEvent: false});
  109 + }, 0);
  110 + }
  111 +
  112 + validate(): ValidationErrors | null {
  113 + return this.deviceTransportConfigurationFormGroup.valid ? null : {
  114 + deviceTransportConfiguration: false
  115 + };
96 116 }
97 117
98 118 private updateModel() {
... ...
... ... @@ -15,10 +15,119 @@
15 15 limitations under the License.
16 16
17 17 -->
18   -<form [formGroup]="snmpDeviceTransportConfigurationFormGroup" style="padding-bottom: 16px;">
19   - <tb-json-object-edit
20   - [required]="required"
21   - label="{{ 'device-profile.transport-type-snmp-hint' | translate }}"
22   - formControlName="configuration">
23   - </tb-json-object-edit>
  18 +<form [formGroup]="snmpDeviceTransportConfigurationFormGroup" style="padding-bottom: 16px;" fxLayoutGap="8px" fxLayout="column">
  19 + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  20 + <mat-form-field fxFlex>
  21 + <mat-label translate>device-profile.snmp.host</mat-label>
  22 + <input matInput formControlName="host" required>
  23 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('host').hasError('required') ||
  24 + snmpDeviceTransportConfigurationFormGroup.get('host').hasError('pattern')">
  25 + {{ 'device-profile.snmp.host-required' | translate }}
  26 + </mat-error>
  27 + </mat-form-field>
  28 + <mat-form-field fxFlex>
  29 + <mat-label translate>device-profile.snmp.port</mat-label>
  30 + <input matInput formControlName="port" type="number" min="0" required>
  31 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('port').hasError('required')">
  32 + {{ 'device-profile.snmp.port-required' | translate }}
  33 + </mat-error>
  34 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('port').hasError('pattern') ||
  35 + snmpDeviceTransportConfigurationFormGroup.get('port').hasError('min')">
  36 + {{ 'device-profile.snmp.port-format' | translate }}
  37 + </mat-error>
  38 + </mat-form-field>
  39 + </div>
  40 + <mat-form-field class="mat-block" floatLabel="always" hideRequiredMarker>
  41 + <mat-label translate>device-profile.snmp.protocol-version</mat-label>
  42 + <mat-select formControlName="protocolVersion" required>
  43 + <mat-option *ngFor="let snmpDeviceProtocolVersion of snmpDeviceProtocolVersions" [value]="snmpDeviceProtocolVersion">
  44 + {{ snmpDeviceProtocolVersion | lowercase }}
  45 + </mat-option>
  46 + </mat-select>
  47 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('protocolVersion').hasError('required')">
  48 + {{ 'device-profile.snmp.protocol-version-required' | translate }}
  49 + </mat-error>
  50 + </mat-form-field>
  51 + <section *ngIf="!isV3protocolVersion()">
  52 + <mat-form-field class="mat-block">
  53 + <mat-label translate>device-profile.snmp.community</mat-label>
  54 + <input matInput formControlName="community" required>
  55 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('community').hasError('required') ||
  56 + snmpDeviceTransportConfigurationFormGroup.get('community').hasError('pattern')">
  57 + {{ 'device-profile.snmp.community-required' | translate }}
  58 + </mat-error>
  59 + </mat-form-field>
  60 + </section>
  61 + <section *ngIf="isV3protocolVersion()">
  62 + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  63 + <mat-form-field fxFlex>
  64 + <mat-label translate>device-profile.snmp.user-name</mat-label>
  65 + <input matInput formControlName="username" required>
  66 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('username').hasError('required') ||
  67 + snmpDeviceTransportConfigurationFormGroup.get('username').hasError('pattern')">
  68 + {{ 'device-profile.snmp.user-name-required' | translate }}
  69 + </mat-error>
  70 + </mat-form-field>
  71 + <mat-form-field fxFlex>
  72 + <mat-label translate>device-profile.snmp.security-name</mat-label>
  73 + <input matInput formControlName="securityName" required>
  74 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('securityName').hasError('required') ||
  75 + snmpDeviceTransportConfigurationFormGroup.get('securityName').hasError('pattern')">
  76 + {{ 'device-profile.snmp.security-name-required' | translate }}
  77 + </mat-error>
  78 + </mat-form-field>
  79 + </div>
  80 + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  81 + <mat-form-field fxFlex floatLabel="always" hideRequiredMarker>
  82 + <mat-label translate>device-profile.snmp.authentication-protocol</mat-label>
  83 + <mat-select formControlName="authenticationProtocol" required>
  84 + <mat-option *ngFor="let snmpAuthenticationProtocol of snmpAuthenticationProtocols" [value]="snmpAuthenticationProtocol">
  85 + {{ snmpAuthenticationProtocolTranslation.get(snmpAuthenticationProtocol) }}
  86 + </mat-option>
  87 + </mat-select>
  88 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('authenticationProtocol').hasError('required')">
  89 + {{ 'device-profile.snmp.authentication-protocol-required' | translate }}
  90 + </mat-error>
  91 + </mat-form-field>
  92 + <mat-form-field fxFlex>
  93 + <mat-label translate>device-profile.snmp.authentication-passphrase</mat-label>
  94 + <input matInput formControlName="authenticationPassphrase" required>
  95 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('authenticationPassphrase').hasError('required') ||
  96 + snmpDeviceTransportConfigurationFormGroup.get('authenticationPassphrase').hasError('pattern')">
  97 + {{ 'device-profile.snmp.authentication-passphrase-required' | translate }}
  98 + </mat-error>
  99 + </mat-form-field>
  100 + </div>
  101 + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  102 + <mat-form-field fxFlex floatLabel="always" hideRequiredMarker>
  103 + <mat-label translate>device-profile.snmp.privacy-protocol</mat-label>
  104 + <mat-select formControlName="privacyProtocol" required>
  105 + <mat-option *ngFor="let snmpPrivacyProtocol of snmpPrivacyProtocols" [value]="snmpPrivacyProtocol">
  106 + {{ snmpPrivacyProtocolTranslation.get(snmpPrivacyProtocol) }}
  107 + </mat-option>
  108 + </mat-select>
  109 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('privacyProtocol').hasError('required')">
  110 + {{ 'device-profile.snmp.privacy-protocol-required' | translate }}
  111 + </mat-error>
  112 + </mat-form-field>
  113 + <mat-form-field fxFlex>
  114 + <mat-label translate>device-profile.snmp.privacy-passphrase</mat-label>
  115 + <input matInput formControlName="privacyPassphrase" required>
  116 + <mat-error *ngIf="snmpDeviceTransportConfigurationFormGroup.get('privacyPassphrase').hasError('required') ||
  117 + snmpDeviceTransportConfigurationFormGroup.get('privacyPassphrase').hasError('pattern')">
  118 + {{ 'device-profile.snmp.privacy-passphrase-required' | translate }}
  119 + </mat-error>
  120 + </mat-form-field>
  121 + </div>
  122 + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  123 + <mat-form-field fxFlex>
  124 + <mat-label translate>device-profile.snmp.context-name</mat-label>
  125 + <input matInput formControlName="contextName">
  126 + </mat-form-field>
  127 + <mat-form-field fxFlex>
  128 + <mat-label translate>device-profile.snmp.engine-id</mat-label>
  129 + <input matInput formControlName="engineId">
  130 + </mat-form-field>
  131 + </div>
  132 + </section>
24 133 </form>
... ...
... ... @@ -14,31 +14,57 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import {Component, forwardRef, Input, OnInit} from '@angular/core';
18   -import {ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators} from '@angular/forms';
19   -import {Store} from '@ngrx/store';
20   -import {AppState} from '@app/core/core.state';
21   -import {coerceBooleanProperty} from '@angular/cdk/coercion';
  17 +import { Component, forwardRef, Input, OnInit } from '@angular/core';
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
  28 +import { Store } from '@ngrx/store';
  29 +import { AppState } from '@app/core/core.state';
  30 +import { coerceBooleanProperty } from '@angular/cdk/coercion';
22 31 import {
23 32 DeviceTransportConfiguration,
24 33 DeviceTransportType,
25   - SnmpDeviceTransportConfiguration
  34 + SnmpAuthenticationProtocol,
  35 + SnmpAuthenticationProtocolTranslationMap,
  36 + SnmpDeviceProtocolVersion,
  37 + SnmpDeviceTransportConfiguration,
  38 + SnmpPrivacyProtocol,
  39 + SnmpPrivacyProtocolTranslationMap
26 40 } from '@shared/models/device.models';
  41 +import { isDefinedAndNotNull } from '@core/utils';
27 42
28 43 @Component({
29 44 selector: 'tb-snmp-device-transport-configuration',
30 45 templateUrl: './snmp-device-transport-configuration.component.html',
31 46 styleUrls: [],
32   - providers: [{
33   - provide: NG_VALUE_ACCESSOR,
34   - useExisting: forwardRef(() => SnmpDeviceTransportConfigurationComponent),
35   - multi: true
36   - }]
  47 + providers: [
  48 + {
  49 + provide: NG_VALUE_ACCESSOR,
  50 + useExisting: forwardRef(() => SnmpDeviceTransportConfigurationComponent),
  51 + multi: true
  52 + }, {
  53 + provide: NG_VALIDATORS,
  54 + useExisting: forwardRef(() => SnmpDeviceTransportConfigurationComponent),
  55 + multi: true
  56 + }]
37 57 })
38   -export class SnmpDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit {
  58 +export class SnmpDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit, Validator {
39 59
40 60 snmpDeviceTransportConfigurationFormGroup: FormGroup;
41 61
  62 + snmpDeviceProtocolVersions = Object.values(SnmpDeviceProtocolVersion);
  63 + snmpAuthenticationProtocols = Object.values(SnmpAuthenticationProtocol);
  64 + snmpAuthenticationProtocolTranslation = SnmpAuthenticationProtocolTranslationMap;
  65 + snmpPrivacyProtocols = Object.values(SnmpPrivacyProtocol);
  66 + snmpPrivacyProtocolTranslation = SnmpPrivacyProtocolTranslationMap;
  67 +
42 68 private requiredValue: boolean;
43 69
44 70 get required(): boolean {
... ... @@ -53,8 +79,7 @@ export class SnmpDeviceTransportConfigurationComponent implements ControlValueAc
53 79 @Input()
54 80 disabled: boolean;
55 81
56   - private propagateChange = (v: any) => {
57   - };
  82 + private propagateChange = (v: any) => { };
58 83
59 84 constructor(private store: Store<AppState>,
60 85 private fb: FormBuilder) {
... ... @@ -69,13 +94,33 @@ export class SnmpDeviceTransportConfigurationComponent implements ControlValueAc
69 94
70 95 ngOnInit() {
71 96 this.snmpDeviceTransportConfigurationFormGroup = this.fb.group({
72   - configuration: [null, Validators.required]
  97 + host: ['', [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]],
  98 + port: [null, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]],
  99 + protocolVersion: [SnmpDeviceProtocolVersion.V2C, Validators.required],
  100 + community: ['public', [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]],
  101 + username: ['', [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]],
  102 + securityName: ['public', [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]],
  103 + contextName: [null],
  104 + authenticationProtocol: [SnmpAuthenticationProtocol.SHA_512, Validators.required],
  105 + authenticationPassphrase: ['', [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]],
  106 + privacyProtocol: [SnmpPrivacyProtocol.DES, Validators.required],
  107 + privacyPassphrase: ['', [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*')]],
  108 + engineId: ['']
  109 + });
  110 + this.snmpDeviceTransportConfigurationFormGroup.get('protocolVersion').valueChanges.subscribe((protocol: SnmpDeviceProtocolVersion) => {
  111 + this.updateDisabledFormValue(protocol);
73 112 });
74 113 this.snmpDeviceTransportConfigurationFormGroup.valueChanges.subscribe(() => {
75 114 this.updateModel();
76 115 });
77 116 }
78 117
  118 + validate(): ValidationErrors | null {
  119 + return this.snmpDeviceTransportConfigurationFormGroup.valid ? null : {
  120 + snmpDeviceTransportConfiguration: false
  121 + };
  122 + }
  123 +
79 124 setDisabledState(isDisabled: boolean): void {
80 125 this.disabled = isDisabled;
81 126 if (this.disabled) {
... ... @@ -86,13 +131,46 @@ export class SnmpDeviceTransportConfigurationComponent implements ControlValueAc
86 131 }
87 132
88 133 writeValue(value: SnmpDeviceTransportConfiguration | null): void {
89   - this.snmpDeviceTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false});
  134 + if (isDefinedAndNotNull(value)) {
  135 + this.snmpDeviceTransportConfigurationFormGroup.patchValue(value, {emitEvent: false});
  136 + if (this.snmpDeviceTransportConfigurationFormGroup.enabled) {
  137 + this.updateDisabledFormValue(value.protocolVersion || SnmpDeviceProtocolVersion.V2C);
  138 + }
  139 + }
  140 + }
  141 +
  142 + isV3protocolVersion(): boolean {
  143 + return this.snmpDeviceTransportConfigurationFormGroup.get('protocolVersion').value === SnmpDeviceProtocolVersion.V3;
  144 + }
  145 +
  146 + private updateDisabledFormValue(protocol: SnmpDeviceProtocolVersion) {
  147 + if (protocol === SnmpDeviceProtocolVersion.V3) {
  148 + this.snmpDeviceTransportConfigurationFormGroup.get('community').disable({emitEvent: false});
  149 + this.snmpDeviceTransportConfigurationFormGroup.get('username').enable({emitEvent: false});
  150 + this.snmpDeviceTransportConfigurationFormGroup.get('securityName').enable({emitEvent: false});
  151 + this.snmpDeviceTransportConfigurationFormGroup.get('contextName').enable({emitEvent: false});
  152 + this.snmpDeviceTransportConfigurationFormGroup.get('authenticationProtocol').enable({emitEvent: false});
  153 + this.snmpDeviceTransportConfigurationFormGroup.get('authenticationPassphrase').enable({emitEvent: false});
  154 + this.snmpDeviceTransportConfigurationFormGroup.get('privacyProtocol').enable({emitEvent: false});
  155 + this.snmpDeviceTransportConfigurationFormGroup.get('privacyPassphrase').enable({emitEvent: false});
  156 + this.snmpDeviceTransportConfigurationFormGroup.get('engineId').enable({emitEvent: false});
  157 + } else {
  158 + this.snmpDeviceTransportConfigurationFormGroup.get('community').enable({emitEvent: false});
  159 + this.snmpDeviceTransportConfigurationFormGroup.get('username').disable({emitEvent: false});
  160 + this.snmpDeviceTransportConfigurationFormGroup.get('securityName').disable({emitEvent: false});
  161 + this.snmpDeviceTransportConfigurationFormGroup.get('contextName').disable({emitEvent: false});
  162 + this.snmpDeviceTransportConfigurationFormGroup.get('authenticationProtocol').disable({emitEvent: false});
  163 + this.snmpDeviceTransportConfigurationFormGroup.get('authenticationPassphrase').disable({emitEvent: false});
  164 + this.snmpDeviceTransportConfigurationFormGroup.get('privacyProtocol').disable({emitEvent: false});
  165 + this.snmpDeviceTransportConfigurationFormGroup.get('privacyPassphrase').disable({emitEvent: false});
  166 + this.snmpDeviceTransportConfigurationFormGroup.get('engineId').disable({emitEvent: false});
  167 + }
90 168 }
91 169
92 170 private updateModel() {
93 171 let configuration: DeviceTransportConfiguration = null;
94 172 if (this.snmpDeviceTransportConfigurationFormGroup.valid) {
95   - configuration = this.snmpDeviceTransportConfigurationFormGroup.getRawValue().configuration;
  173 + configuration = this.snmpDeviceTransportConfigurationFormGroup.value;
96 174 configuration.type = DeviceTransportType.SNMP;
97 175 }
98 176 this.propagateChange(configuration);
... ...
... ... @@ -362,7 +362,7 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT
362 362 break;
363 363 case DeviceTransportType.SNMP:
364 364 const snmpTransportConfiguration: SnmpDeviceProfileTransportConfiguration = {
365   - timeoutMs: 0,
  365 + timeoutMs: 500,
366 366 retries: 0,
367 367 communicationConfigs: null
368 368 };
... ... @@ -394,7 +394,12 @@ export function createDeviceTransportConfiguration(type: DeviceTransportType): D
394 394 transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M};
395 395 break;
396 396 case DeviceTransportType.SNMP:
397   - const snmpTransportConfiguration: SnmpDeviceTransportConfiguration = {};
  397 + const snmpTransportConfiguration: SnmpDeviceTransportConfiguration = {
  398 + host: 'localhost',
  399 + port: 161,
  400 + protocolVersion: SnmpDeviceProtocolVersion.V2C,
  401 + community: 'public'
  402 + };
398 403 transportConfiguration = {...snmpTransportConfiguration, type: DeviceTransportType.SNMP};
399 404 break;
400 405 }
... ... @@ -572,8 +577,57 @@ export interface Lwm2mDeviceTransportConfiguration {
572 577 [key: string]: any;
573 578 }
574 579
  580 +export enum SnmpDeviceProtocolVersion {
  581 + V1 = 'V1',
  582 + V2C = 'V2C',
  583 + V3 = 'V3'
  584 +}
  585 +
  586 +export enum SnmpAuthenticationProtocol {
  587 + SHA_1 = 'SHA_1',
  588 + SHA_224 = 'SHA_224',
  589 + SHA_256 = 'SHA_256',
  590 + SHA_384 = 'SHA_384',
  591 + SHA_512 = 'SHA_512',
  592 + MD5 = 'MD%'
  593 +}
  594 +
  595 +export const SnmpAuthenticationProtocolTranslationMap = new Map<SnmpAuthenticationProtocol, string>([
  596 + [SnmpAuthenticationProtocol.SHA_1, 'SHA-1'],
  597 + [SnmpAuthenticationProtocol.SHA_224, 'SHA-224'],
  598 + [SnmpAuthenticationProtocol.SHA_256, 'SHA-256'],
  599 + [SnmpAuthenticationProtocol.SHA_384, 'SHA-384'],
  600 + [SnmpAuthenticationProtocol.SHA_512, 'SHA-512'],
  601 + [SnmpAuthenticationProtocol.MD5, 'MD5']
  602 +]);
  603 +
  604 +export enum SnmpPrivacyProtocol {
  605 + DES = 'DES',
  606 + AES_128 = 'AES_128',
  607 + AES_192 = 'AES_192',
  608 + AES_256 = 'AES_256'
  609 +}
  610 +
  611 +export const SnmpPrivacyProtocolTranslationMap = new Map<SnmpPrivacyProtocol, string>([
  612 + [SnmpPrivacyProtocol.DES, 'DES'],
  613 + [SnmpPrivacyProtocol.AES_128, 'AES-128'],
  614 + [SnmpPrivacyProtocol.AES_192, 'AES-192'],
  615 + [SnmpPrivacyProtocol.AES_256, 'AES-256'],
  616 +]);
  617 +
575 618 export interface SnmpDeviceTransportConfiguration {
576   - [key: string]: any;
  619 + host?: string;
  620 + port?: number;
  621 + protocolVersion?: SnmpDeviceProtocolVersion;
  622 + community?: string;
  623 + username?: string;
  624 + securityName?: string;
  625 + contextName?: string;
  626 + authenticationProtocol?: SnmpAuthenticationProtocol;
  627 + authenticationPassphrase?: string;
  628 + privacyProtocol?: SnmpPrivacyProtocol;
  629 + privacyPassphrase?: string;
  630 + engineId?: string;
577 631 }
578 632
579 633 export type DeviceTransportConfigurations = DefaultDeviceTransportConfiguration &
... ...
... ... @@ -1301,16 +1301,35 @@
1301 1301 "snmp": {
1302 1302 "add-communication-config": "Add communication config",
1303 1303 "add-mapping": "Add mapping",
  1304 + "authentication-passphrase": "Authentication passphrase",
  1305 + "authentication-passphrase-required": "Authentication passphrase is required.",
  1306 + "authentication-protocol": "Authentication protocol",
  1307 + "authentication-protocol-required": "Authentication protocol is required.",
1304 1308 "communication-configs": "Communication configs",
  1309 + "community": "Community string",
  1310 + "community-required": "Community string is required.",
  1311 + "context-name": "Context name",
1305 1312 "data-key": "Data key",
1306 1313 "data-key-required": "Data key is required.",
1307 1314 "data-type": "Data type",
1308 1315 "data-type-required": "Data type is required.",
  1316 + "engine-id": "Engine ID",
  1317 + "host": "Host",
  1318 + "host-required": "Host is required.",
1309 1319 "oid": "OID",
1310 1320 "oid-pattern": "Invalid OID format.",
1311 1321 "oid-required": "OID is required.",
1312 1322 "please-add-communication-config": "Please add communication config",
1313 1323 "please-add-mapping-config": "Please add mapping config",
  1324 + "port": "Port",
  1325 + "port-format": "Invalid port format.",
  1326 + "port-required": "Port is required.",
  1327 + "privacy-passphrase": "Privacy passphrase",
  1328 + "privacy-passphrase-required": "Privacy passphrase is required.",
  1329 + "privacy-protocol": "Privacy protocol",
  1330 + "privacy-protocol-required": "Privacy protocol is required.",
  1331 + "protocol-version": "Protocol version",
  1332 + "protocol-version-required": "Protocol version is required.",
1314 1333 "querying-frequency": "Querying frequency, ms",
1315 1334 "querying-frequency-invalid-format": "Querying frequency must be a positive integer.",
1316 1335 "querying-frequency-required": "Querying frequency is required.",
... ... @@ -1319,9 +1338,13 @@
1319 1338 "retries-required": "Retries is required.",
1320 1339 "scope": "Scope",
1321 1340 "scope-required": "Scope is required.",
  1341 + "security-name": "Security name",
  1342 + "security-name-required": "Security name is required.",
1322 1343 "timeout-ms": "Timeout, ms",
1323 1344 "timeout-ms-invalid-format": "Timeout must be a positive integer.",
1324   - "timeout-ms-required": "Timeout is required."
  1345 + "timeout-ms-required": "Timeout is required.",
  1346 + "user-name": "User name",
  1347 + "user-name-required": "User name is required."
1325 1348 }
1326 1349 },
1327 1350 "dialog": {
... ...