Commit 51814f4017b5971e01e60b9204d57d59583e87dc
1 parent
26bc7841
UI: Refactoring lwm2m device profile: security server config and ota update strategy
Showing
11 changed files
with
419 additions
and
499 deletions
... | ... | @@ -17,7 +17,6 @@ package org.thingsboard.server.controller; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | 19 | import lombok.extern.slf4j.Slf4j; |
20 | -import org.eclipse.leshan.core.SecurityMode; | |
21 | 20 | import org.springframework.security.access.prepost.PreAuthorize; |
22 | 21 | import org.springframework.web.bind.annotation.PathVariable; |
23 | 22 | import org.springframework.web.bind.annotation.RequestBody; |
... | ... | @@ -45,14 +44,11 @@ import java.util.Map; |
45 | 44 | public class Lwm2mController extends BaseController { |
46 | 45 | |
47 | 46 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
48 | - @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{securityMode}/{bootstrapServerIs}", method = RequestMethod.GET) | |
47 | + @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{isBootstrapServer}", method = RequestMethod.GET) | |
49 | 48 | @ResponseBody |
50 | - public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("securityMode") String strSecurityMode, | |
51 | - @PathVariable("bootstrapServerIs") boolean bootstrapServer) throws ThingsboardException { | |
52 | - checkNotNull(strSecurityMode); | |
49 | + public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("isBootstrapServer") boolean bootstrapServer) throws ThingsboardException { | |
53 | 50 | try { |
54 | - SecurityMode securityMode = SecurityMode.valueOf(strSecurityMode); | |
55 | - return lwM2MServerSecurityInfoRepository.getServerSecurityInfo(securityMode, bootstrapServer); | |
51 | + return lwM2MServerSecurityInfoRepository.getServerSecurityInfo(bootstrapServer); | |
56 | 52 | } catch (Exception e) { |
57 | 53 | throw handleException(e); |
58 | 54 | } | ... | ... |
... | ... | @@ -18,7 +18,6 @@ package org.thingsboard.server.service.lwm2m; |
18 | 18 | |
19 | 19 | import lombok.RequiredArgsConstructor; |
20 | 20 | import lombok.extern.slf4j.Slf4j; |
21 | -import org.eclipse.leshan.core.SecurityMode; | |
22 | 21 | import org.eclipse.leshan.core.util.Hex; |
23 | 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
24 | 23 | import org.springframework.stereotype.Service; |
... | ... | @@ -50,40 +49,20 @@ public class LwM2MServerSecurityInfoRepository { |
50 | 49 | private final LwM2MTransportServerConfig serverConfig; |
51 | 50 | private final LwM2MTransportBootstrapConfig bootstrapConfig; |
52 | 51 | |
53 | - /** | |
54 | - * @param securityMode | |
55 | - * @param bootstrapServer | |
56 | - * @return ServerSecurityConfig more value is default: Important - port, host, publicKey | |
57 | - */ | |
58 | - public ServerSecurityConfig getServerSecurityInfo(SecurityMode securityMode, boolean bootstrapServer) { | |
59 | - ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig, securityMode); | |
52 | + public ServerSecurityConfig getServerSecurityInfo(boolean bootstrapServer) { | |
53 | + ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig); | |
60 | 54 | result.setBootstrapServerIs(bootstrapServer); |
61 | 55 | return result; |
62 | 56 | } |
63 | 57 | |
64 | - private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig, SecurityMode securityMode) { | |
58 | + private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig) { | |
65 | 59 | ServerSecurityConfig bsServ = new ServerSecurityConfig(); |
66 | 60 | bsServ.setServerId(serverConfig.getId()); |
67 | - switch (securityMode) { | |
68 | - case NO_SEC: | |
69 | - bsServ.setHost(serverConfig.getHost()); | |
70 | - bsServ.setPort(serverConfig.getPort()); | |
71 | - bsServ.setServerPublicKey(""); | |
72 | - break; | |
73 | - case PSK: | |
74 | - bsServ.setHost(serverConfig.getSecureHost()); | |
75 | - bsServ.setPort(serverConfig.getSecurePort()); | |
76 | - bsServ.setServerPublicKey(""); | |
77 | - break; | |
78 | - case RPK: | |
79 | - case X509: | |
80 | - bsServ.setHost(serverConfig.getSecureHost()); | |
81 | - bsServ.setPort(serverConfig.getSecurePort()); | |
82 | - bsServ.setServerPublicKey(getPublicKey(serverConfig.getCertificateAlias(), this.serverConfig.getPublicX(), this.serverConfig.getPublicY())); | |
83 | - break; | |
84 | - default: | |
85 | - break; | |
86 | - } | |
61 | + bsServ.setHost(serverConfig.getHost()); | |
62 | + bsServ.setPort(serverConfig.getPort()); | |
63 | + bsServ.setSecurityHost(serverConfig.getSecureHost()); | |
64 | + bsServ.setSecurityPort(serverConfig.getSecurePort()); | |
65 | + bsServ.setServerPublicKey(getPublicKey(serverConfig.getCertificateAlias(), this.serverConfig.getPublicX(), this.serverConfig.getPublicY())); | |
87 | 66 | return bsServ; |
88 | 67 | } |
89 | 68 | ... | ... |
... | ... | @@ -20,7 +20,9 @@ import lombok.Data; |
20 | 20 | @Data |
21 | 21 | public class ServerSecurityConfig { |
22 | 22 | String host; |
23 | + String securityHost; | |
23 | 24 | Integer port; |
25 | + Integer securityPort; | |
24 | 26 | String serverPublicKey; |
25 | 27 | boolean bootstrapServerIs = true; |
26 | 28 | Integer clientHoldOffTime = 1; | ... | ... |
... | ... | @@ -18,20 +18,22 @@ import { Injectable } from '@angular/core'; |
18 | 18 | import { HttpClient } from '@angular/common/http'; |
19 | 19 | import { PageLink } from '@shared/models/page/page-link'; |
20 | 20 | import { defaultHttpOptionsFromConfig, RequestConfig } from './http-utils'; |
21 | -import { Observable, throwError } from 'rxjs'; | |
21 | +import { Observable, of, throwError } from 'rxjs'; | |
22 | 22 | import { PageData } from '@shared/models/page/page-data'; |
23 | 23 | import { DeviceProfile, DeviceProfileInfo, DeviceTransportType } from '@shared/models/device.models'; |
24 | 24 | import { isDefinedAndNotNull, isEmptyStr } from '@core/utils'; |
25 | 25 | import { ObjectLwM2M, ServerSecurityConfig } from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models'; |
26 | 26 | import { SortOrder } from '@shared/models/page/sort-order'; |
27 | 27 | import { OtaPackageService } from '@core/http/ota-package.service'; |
28 | -import { mergeMap } from 'rxjs/operators'; | |
28 | +import { mergeMap, tap } from 'rxjs/operators'; | |
29 | 29 | |
30 | 30 | @Injectable({ |
31 | 31 | providedIn: 'root' |
32 | 32 | }) |
33 | 33 | export class DeviceProfileService { |
34 | 34 | |
35 | + private lwm2mBootstrapSecurityInfoInMemoryCache = new Map<boolean, ServerSecurityConfig>(); | |
36 | + | |
35 | 37 | constructor( |
36 | 38 | private http: HttpClient, |
37 | 39 | private otaPackageService: OtaPackageService |
... | ... | @@ -58,12 +60,18 @@ export class DeviceProfileService { |
58 | 60 | return this.http.get<Array<ObjectLwM2M>>(url, defaultHttpOptionsFromConfig(config)); |
59 | 61 | } |
60 | 62 | |
61 | - public getLwm2mBootstrapSecurityInfo(securityMode: string, bootstrapServerIs: boolean, | |
62 | - config?: RequestConfig): Observable<ServerSecurityConfig> { | |
63 | - return this.http.get<ServerSecurityConfig>( | |
64 | - `/api/lwm2m/deviceProfile/bootstrap/${securityMode}/${bootstrapServerIs}`, | |
65 | - defaultHttpOptionsFromConfig(config) | |
66 | - ); | |
63 | + public getLwm2mBootstrapSecurityInfo(isBootstrapServer: boolean, config?: RequestConfig): Observable<ServerSecurityConfig> { | |
64 | + const securityConfig = this.lwm2mBootstrapSecurityInfoInMemoryCache.get(isBootstrapServer); | |
65 | + if (securityConfig) { | |
66 | + return of(securityConfig); | |
67 | + } else { | |
68 | + return this.http.get<ServerSecurityConfig>( | |
69 | + `/api/lwm2m/deviceProfile/bootstrap/${isBootstrapServer}`, | |
70 | + defaultHttpOptionsFromConfig(config) | |
71 | + ).pipe( | |
72 | + tap(serverConfig => this.lwm2mBootstrapSecurityInfoInMemoryCache.set(isBootstrapServer, serverConfig)) | |
73 | + ); | |
74 | + } | |
67 | 75 | } |
68 | 76 | |
69 | 77 | public getLwm2mObjectsPage(pageLink: PageLink, config?: RequestConfig): Observable<Array<ObjectLwM2M>> { | ... | ... |
... | ... | @@ -28,60 +28,45 @@ |
28 | 28 | </mat-form-field> |
29 | 29 | <mat-form-field fxFlex> |
30 | 30 | <mat-label>{{ 'device-profile.lwm2m.server-host' | translate }}</mat-label> |
31 | - <input matInput type="text" formControlName="host" required | |
32 | - matTooltip="{{'device-profile.lwm2m.server-host-tip' | translate}}" | |
33 | - matTooltipPosition="above"> | |
31 | + <input matInput type="text" formControlName="host" required> | |
34 | 32 | <mat-error *ngIf="serverFormGroup.get('host').hasError('required')"> |
35 | - {{ 'device-profile.lwm2m.server-host' | translate }} | |
36 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
33 | + {{ 'device-profile.lwm2m.server-host-required' | translate }} | |
37 | 34 | </mat-error> |
38 | 35 | </mat-form-field> |
39 | 36 | <mat-form-field fxFlex> |
40 | 37 | <mat-label>{{ 'device-profile.lwm2m.server-port' | translate }}</mat-label> |
41 | - <input matInput type="number" formControlName="port" required | |
42 | - matTooltip="{{'device-profile.lwm2m.server-port-tip' | translate}}" | |
43 | - matTooltipPosition="above"> | |
38 | + <input matInput type="number" formControlName="port" required min="0"> | |
44 | 39 | <mat-error *ngIf="serverFormGroup.get('port').hasError('required')"> |
45 | - {{ 'device-profile.lwm2m.server-port' | translate }} | |
46 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
40 | + {{ 'device-profile.lwm2m.server-port-required' | translate }} | |
47 | 41 | </mat-error> |
48 | 42 | </mat-form-field> |
43 | + </div> | |
44 | + <div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px"> | |
49 | 45 | <mat-form-field fxFlex> |
50 | 46 | <mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label> |
51 | - <input matInput type="number" formControlName="serverId" required | |
52 | - matTooltip="{{'device-profile.lwm2m.short-id-tip' | translate}}" | |
53 | - matTooltipPosition="above"> | |
47 | + <input matInput type="number" formControlName="serverId" required min="0"> | |
54 | 48 | <mat-error *ngIf="serverFormGroup.get('serverId').hasError('required')"> |
55 | - {{ 'device-profile.lwm2m.short-id' | translate }} | |
56 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
49 | + {{ 'device-profile.lwm2m.short-id-required' | translate }} | |
57 | 50 | </mat-error> |
58 | 51 | </mat-form-field> |
59 | - </div> | |
60 | - <div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px"> | |
61 | 52 | <mat-form-field fxFlex> |
62 | 53 | <mat-label>{{ 'device-profile.lwm2m.client-hold-off-time' | translate }}</mat-label> |
63 | - <input matInput type="number" formControlName="clientHoldOffTime" required | |
64 | - matTooltip="{{'device-profile.lwm2m.client-hold-off-time-tip' | translate}}" | |
54 | + <input matInput type="number" formControlName="clientHoldOffTime" required min="0" | |
55 | + matTooltip="{{'device-profile.lwm2m.client-hold-off-time-tooltip' | translate}}" | |
65 | 56 | matTooltipPosition="above"> |
66 | 57 | <mat-error *ngIf="serverFormGroup.get('clientHoldOffTime').hasError('required')"> |
67 | - {{ 'device-profile.lwm2m.client-hold-off-time' | translate }} | |
68 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
58 | + {{ 'device-profile.lwm2m.client-hold-off-time-required' | translate }} | |
69 | 59 | </mat-error> |
70 | 60 | </mat-form-field> |
71 | 61 | <mat-form-field fxFlex> |
72 | - <mat-label>{{ 'device-profile.lwm2m.bootstrap-server-account-timeout' | translate }}</mat-label> | |
73 | - <input matInput type="number" formControlName="bootstrapServerAccountTimeout" required | |
74 | - matTooltip="{{'device-profile.lwm2m.bootstrap-server-account-timeout-tip' | translate}}" | |
62 | + <mat-label>{{ 'device-profile.lwm2m.account-after-timeout' | translate }}</mat-label> | |
63 | + <input matInput type="number" formControlName="bootstrapServerAccountTimeout" required min="0" | |
64 | + matTooltip="{{'device-profile.lwm2m.account-after-timeout-tooltip' | translate}}" | |
75 | 65 | matTooltipPosition="above"> |
76 | 66 | <mat-error *ngIf="serverFormGroup.get('bootstrapServerAccountTimeout').hasError('required')"> |
77 | - {{ 'device-profile.lwm2m.bootstrap-server-account-timeout' | translate }} | |
78 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
67 | + {{ 'device-profile.lwm2m.account-after-timeout-required' | translate }} | |
79 | 68 | </mat-error> |
80 | 69 | </mat-form-field> |
81 | - <mat-checkbox fxFlex formControlName="bootstrapServerIs" color="primary"> | |
82 | - {{ 'device-profile.lwm2m.bootstrap-server' | translate }} | |
83 | - </mat-checkbox> | |
84 | - <div fxFlex></div> | |
85 | 70 | </div> |
86 | 71 | <div *ngIf="serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK || |
87 | 72 | serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509"> |
... | ... | @@ -89,32 +74,22 @@ |
89 | 74 | <mat-label>{{ 'device-profile.lwm2m.server-public-key' | translate }}</mat-label> |
90 | 75 | <textarea matInput |
91 | 76 | #serverPublicKey |
92 | - maxlength="{{lenMaxServerPublicKey}}" | |
77 | + maxlength="{{maxLengthPublicKey}}" | |
93 | 78 | cdkTextareaAutosize |
94 | 79 | cdkAutosizeMinRows="1" |
95 | 80 | cols="1" required |
96 | - style="overflow:hidden" | |
97 | 81 | formControlName="serverPublicKey" |
98 | - matTooltip="{{'device-profile.lwm2m.server-public-key-tip' | translate}}" | |
99 | 82 | ></textarea> |
100 | - <mat-hint align="end">{{serverPublicKey.value?.length || 0}}/{{lenMaxServerPublicKey}}</mat-hint> | |
83 | + <mat-hint align="end">{{serverPublicKey.value?.length || 0}}/{{maxLengthPublicKey}}</mat-hint> | |
101 | 84 | <mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('required')"> |
102 | - {{ 'device-profile.lwm2m.server-public-key' | translate }} | |
103 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
85 | + {{ 'device-profile.lwm2m.server-public-key-required' | translate }} | |
104 | 86 | </mat-error> |
105 | - <mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('pattern') && | |
106 | - (serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK || | |
107 | - serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509)"> | |
108 | - {{ 'device-profile.lwm2m.server-public-key' | translate }} | |
109 | - <strong>{{ 'device-profile.lwm2m.pattern_hex_dec' | translate: { | |
110 | - count: 0} }}</strong> | |
87 | + <mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('pattern')"> | |
88 | + {{ 'device-profile.lwm2m.server-public-key-pattern' | translate }} | |
111 | 89 | </mat-error> |
112 | - <mat-error *ngIf="(serverFormGroup.get('serverPublicKey').hasError('maxlength') || | |
113 | - serverFormGroup.get('serverPublicKey').hasError('minlength')) && | |
114 | - serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK"> | |
115 | - {{ 'device-profile.lwm2m.server-public-key' | translate }} | |
116 | - <strong>{{ 'device-profile.lwm2m.pattern_hex_dec' | translate: { | |
117 | - count: lenMaxServerPublicKey } }}</strong> | |
90 | + <mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('maxlength') || | |
91 | + serverFormGroup.get('serverPublicKey').hasError('minlength')"> | |
92 | + {{ 'device-profile.lwm2m.server-public-key-length' | translate: {count: maxLengthPublicKey } }} | |
118 | 93 | </mat-error> |
119 | 94 | </mat-form-field> |
120 | 95 | </div> | ... | ... |
... | ... | @@ -14,26 +14,24 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import { Component, forwardRef, Inject, Input } from '@angular/core'; | |
17 | +import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; | |
18 | 18 | import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; |
19 | 19 | import { |
20 | - DEFAULT_CLIENT_HOLD_OFF_TIME, | |
21 | - DEFAULT_ID_SERVER, | |
22 | 20 | DEFAULT_PORT_BOOTSTRAP_NO_SEC, |
23 | 21 | DEFAULT_PORT_SERVER_NO_SEC, |
24 | 22 | KEY_REGEXP_HEX_DEC, |
25 | 23 | LEN_MAX_PUBLIC_KEY_RPK, |
26 | 24 | LEN_MAX_PUBLIC_KEY_X509, |
27 | - SECURITY_CONFIG_MODE, | |
28 | - SECURITY_CONFIG_MODE_NAMES, | |
25 | + securityConfigMode, | |
26 | + securityConfigModeNames, | |
29 | 27 | ServerSecurityConfig |
30 | 28 | } from './lwm2m-profile-config.models'; |
31 | -import { coerceBooleanProperty } from '@angular/cdk/coercion'; | |
32 | -import { WINDOW } from '@core/services/window.service'; | |
33 | -import { pairwise, startWith } from 'rxjs/operators'; | |
34 | 29 | import { DeviceProfileService } from '@core/http/device-profile.service'; |
30 | +import { of, Subject } from 'rxjs'; | |
31 | +import { map, mergeMap, takeUntil, tap } from 'rxjs/operators'; | |
32 | +import { Observable } from 'rxjs/internal/Observable'; | |
33 | +import { deepClone } from '@core/utils'; | |
35 | 34 | |
36 | -// @dynamic | |
37 | 35 | @Component({ |
38 | 36 | selector: 'tb-profile-lwm2m-device-config-server', |
39 | 37 | templateUrl: './lwm2m-device-config-server.component.html', |
... | ... | @@ -46,127 +44,78 @@ import { DeviceProfileService } from '@core/http/device-profile.service'; |
46 | 44 | ] |
47 | 45 | }) |
48 | 46 | |
49 | -export class Lwm2mDeviceConfigServerComponent implements ControlValueAccessor { | |
47 | +export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAccessor, OnDestroy { | |
50 | 48 | |
51 | - private requiredValue: boolean; | |
52 | 49 | private disabled = false; |
50 | + private destroy$ = new Subject(); | |
51 | + | |
52 | + private securityDefaultConfig: ServerSecurityConfig; | |
53 | 53 | |
54 | - valuePrev = null; | |
55 | 54 | serverFormGroup: FormGroup; |
56 | - securityConfigLwM2MType = SECURITY_CONFIG_MODE; | |
57 | - securityConfigLwM2MTypes = Object.keys(SECURITY_CONFIG_MODE); | |
58 | - credentialTypeLwM2MNamesMap = SECURITY_CONFIG_MODE_NAMES; | |
59 | - lenMinServerPublicKey = 0; | |
60 | - lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK; | |
55 | + securityConfigLwM2MType = securityConfigMode; | |
56 | + securityConfigLwM2MTypes = Object.keys(securityConfigMode); | |
57 | + credentialTypeLwM2MNamesMap = securityConfigModeNames; | |
58 | + maxLengthPublicKey = LEN_MAX_PUBLIC_KEY_RPK; | |
61 | 59 | currentSecurityMode = null; |
62 | 60 | |
63 | 61 | @Input() |
64 | - bootstrapServerIs: boolean; | |
62 | + isBootstrapServer = false; | |
65 | 63 | |
66 | - get required(): boolean { | |
67 | - return this.requiredValue; | |
68 | - } | |
64 | + private propagateChange = (v: any) => { }; | |
69 | 65 | |
70 | - @Input() | |
71 | - set required(value: boolean) { | |
72 | - this.requiredValue = coerceBooleanProperty(value); | |
66 | + constructor(public fb: FormBuilder, | |
67 | + private deviceProfileService: DeviceProfileService) { | |
73 | 68 | } |
74 | 69 | |
75 | - constructor(public fb: FormBuilder, | |
76 | - private deviceProfileService: DeviceProfileService, | |
77 | - @Inject(WINDOW) private window: Window) { | |
78 | - this.serverFormGroup = this.initServerGroup(); | |
70 | + ngOnInit(): void { | |
71 | + this.serverFormGroup = this.fb.group({ | |
72 | + host: ['', Validators.required], | |
73 | + port: [this.isBootstrapServer ? DEFAULT_PORT_BOOTSTRAP_NO_SEC : DEFAULT_PORT_SERVER_NO_SEC, [Validators.required, Validators.min(0)]], | |
74 | + securityMode: [securityConfigMode.NO_SEC], | |
75 | + serverPublicKey: ['', Validators.required], | |
76 | + clientHoldOffTime: ['', [Validators.required, Validators.min(0)]], | |
77 | + serverId: ['', [Validators.required, Validators.min(0)]], | |
78 | + bootstrapServerAccountTimeout: ['', [Validators.required, Validators.min(0)]], | |
79 | + }); | |
79 | 80 | this.serverFormGroup.get('securityMode').valueChanges.pipe( |
80 | - startWith(null), | |
81 | - pairwise() | |
82 | - ).subscribe(([previousValue, currentValue]) => { | |
83 | - if (previousValue === null || previousValue !== currentValue) { | |
84 | - this.getLwm2mBootstrapSecurityInfo(currentValue); | |
85 | - this.updateValidate(currentValue); | |
86 | - this.serverFormGroup.updateValueAndValidity(); | |
87 | - } | |
88 | - | |
81 | + tap(securityMode => this.updateValidate(securityMode)), | |
82 | + mergeMap(securityMode => this.getLwm2mBootstrapSecurityInfo(securityMode)), | |
83 | + takeUntil(this.destroy$) | |
84 | + ).subscribe(serverSecurityConfig => { | |
85 | + this.serverFormGroup.patchValue(serverSecurityConfig, {emitEvent: false}); | |
89 | 86 | }); |
90 | - this.serverFormGroup.valueChanges.subscribe(value => { | |
91 | - if (this.disabled !== undefined && !this.disabled) { | |
92 | - this.propagateChangeState(value); | |
93 | - } | |
87 | + this.serverFormGroup.valueChanges.pipe( | |
88 | + takeUntil(this.destroy$) | |
89 | + ).subscribe(value => { | |
90 | + this.propagateChangeState(value); | |
94 | 91 | }); |
95 | 92 | } |
96 | 93 | |
97 | - private updateValueFields = (serverData: ServerSecurityConfig): void => { | |
98 | - serverData.bootstrapServerIs = this.bootstrapServerIs; | |
99 | - this.serverFormGroup.patchValue(serverData, {emitEvent: false}); | |
100 | - this.serverFormGroup.get('bootstrapServerIs').disable(); | |
101 | - const securityMode = this.serverFormGroup.get('securityMode').value as SECURITY_CONFIG_MODE; | |
102 | - this.updateValidate(securityMode); | |
94 | + ngOnDestroy(): void { | |
95 | + this.destroy$.next(); | |
96 | + this.destroy$.complete(); | |
103 | 97 | } |
104 | 98 | |
105 | - private updateValidate = (securityMode: SECURITY_CONFIG_MODE): void => { | |
106 | - switch (securityMode) { | |
107 | - case SECURITY_CONFIG_MODE.NO_SEC: | |
108 | - this.setValidatorsNoSecPsk(); | |
109 | - break; | |
110 | - case SECURITY_CONFIG_MODE.PSK: | |
111 | - this.setValidatorsNoSecPsk(); | |
112 | - break; | |
113 | - case SECURITY_CONFIG_MODE.RPK: | |
114 | - this.lenMinServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK; | |
115 | - this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK; | |
116 | - this.setValidatorsRpkX509(); | |
117 | - break; | |
118 | - case SECURITY_CONFIG_MODE.X509: | |
119 | - this.lenMinServerPublicKey = 0; | |
120 | - this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_X509; | |
121 | - this.setValidatorsRpkX509(); | |
122 | - break; | |
99 | + writeValue(serverData: ServerSecurityConfig): void { | |
100 | + if (serverData) { | |
101 | + this.serverFormGroup.patchValue(serverData, {emitEvent: false}); | |
102 | + this.updateValidate(serverData.securityMode); | |
123 | 103 | } |
124 | - this.serverFormGroup.updateValueAndValidity(); | |
125 | - } | |
126 | - | |
127 | - private setValidatorsNoSecPsk = (): void => { | |
128 | - this.serverFormGroup.get('serverPublicKey').setValidators([]); | |
129 | - } | |
130 | - | |
131 | - private setValidatorsRpkX509 = (): void => { | |
132 | - this.serverFormGroup.get('serverPublicKey').setValidators([Validators.required, | |
133 | - Validators.pattern(KEY_REGEXP_HEX_DEC), | |
134 | - Validators.minLength(this.lenMinServerPublicKey), | |
135 | - Validators.maxLength(this.lenMaxServerPublicKey)]); | |
136 | - } | |
137 | - | |
138 | - writeValue(value: ServerSecurityConfig): void { | |
139 | - if (value) { | |
140 | - this.updateValueFields(value); | |
104 | + if (!this.securityDefaultConfig){ | |
105 | + this.getLwm2mBootstrapSecurityInfo().subscribe(value => { | |
106 | + if (!serverData) { | |
107 | + this.serverFormGroup.patchValue(value); | |
108 | + } | |
109 | + }); | |
141 | 110 | } |
142 | 111 | } |
143 | 112 | |
144 | - private propagateChange = (v: any) => {}; | |
145 | - | |
146 | 113 | registerOnChange(fn: any): void { |
147 | 114 | this.propagateChange = fn; |
148 | 115 | } |
149 | 116 | |
150 | - private propagateChangeState = (value: any): void => { | |
151 | - if (value !== undefined) { | |
152 | - if (this.valuePrev === null) { | |
153 | - this.valuePrev = 'init'; | |
154 | - } else if (this.valuePrev === 'init') { | |
155 | - this.valuePrev = value; | |
156 | - } else if (JSON.stringify(value) !== JSON.stringify(this.valuePrev)) { | |
157 | - this.valuePrev = value; | |
158 | - if (this.serverFormGroup.valid) { | |
159 | - this.propagateChange(value); | |
160 | - } else { | |
161 | - this.propagateChange(null); | |
162 | - } | |
163 | - } | |
164 | - } | |
165 | - } | |
166 | - | |
167 | 117 | setDisabledState(isDisabled: boolean): void { |
168 | 118 | this.disabled = isDisabled; |
169 | - this.valuePrev = null; | |
170 | 119 | if (isDisabled) { |
171 | 120 | this.serverFormGroup.disable({emitEvent: false}); |
172 | 121 | } else { |
... | ... | @@ -177,33 +126,76 @@ export class Lwm2mDeviceConfigServerComponent implements ControlValueAccessor { |
177 | 126 | registerOnTouched(fn: any): void { |
178 | 127 | } |
179 | 128 | |
180 | - private initServerGroup = (): FormGroup => { | |
181 | - const port = this.bootstrapServerIs ? DEFAULT_PORT_BOOTSTRAP_NO_SEC : DEFAULT_PORT_SERVER_NO_SEC; | |
182 | - return this.fb.group({ | |
183 | - host: [this.window.location.hostname, this.required ? Validators.required : ''], | |
184 | - port: [port, this.required ? Validators.required : ''], | |
185 | - bootstrapServerIs: [this.bootstrapServerIs, ''], | |
186 | - securityMode: [this.fb.control(SECURITY_CONFIG_MODE.NO_SEC)], | |
187 | - serverPublicKey: ['', this.required ? Validators.required : ''], | |
188 | - clientHoldOffTime: [DEFAULT_CLIENT_HOLD_OFF_TIME, this.required ? Validators.required : ''], | |
189 | - serverId: [DEFAULT_ID_SERVER, this.required ? Validators.required : ''], | |
190 | - bootstrapServerAccountTimeout: ['', this.required ? Validators.required : ''], | |
191 | - }); | |
129 | + private updateValidate(securityMode: securityConfigMode): void { | |
130 | + switch (securityMode) { | |
131 | + case securityConfigMode.NO_SEC: | |
132 | + case securityConfigMode.PSK: | |
133 | + this.clearValidators(); | |
134 | + break; | |
135 | + case securityConfigMode.RPK: | |
136 | + this.maxLengthPublicKey = LEN_MAX_PUBLIC_KEY_RPK; | |
137 | + this.setValidators(LEN_MAX_PUBLIC_KEY_RPK); | |
138 | + break; | |
139 | + case securityConfigMode.X509: | |
140 | + this.maxLengthPublicKey = LEN_MAX_PUBLIC_KEY_X509; | |
141 | + this.setValidators(0); | |
142 | + break; | |
143 | + } | |
144 | + this.serverFormGroup.get('serverPublicKey').updateValueAndValidity({emitEvent: false}); | |
145 | + } | |
146 | + | |
147 | + private clearValidators(): void { | |
148 | + this.serverFormGroup.get('serverPublicKey').clearValidators(); | |
149 | + } | |
150 | + | |
151 | + private setValidators(minLengthKey: number): void { | |
152 | + this.serverFormGroup.get('serverPublicKey').setValidators([ | |
153 | + Validators.required, | |
154 | + Validators.pattern(KEY_REGEXP_HEX_DEC), | |
155 | + Validators.minLength(minLengthKey), | |
156 | + Validators.maxLength(this.maxLengthPublicKey) | |
157 | + ]); | |
192 | 158 | } |
193 | 159 | |
194 | - private getLwm2mBootstrapSecurityInfo = (mode: string): void => { | |
195 | - this.deviceProfileService.getLwm2mBootstrapSecurityInfo(mode, this.serverFormGroup.get('bootstrapServerIs').value).subscribe( | |
196 | - (serverSecurityConfig) => { | |
197 | - this.serverFormGroup.patchValue({ | |
198 | - host: serverSecurityConfig.host, | |
199 | - port: serverSecurityConfig.port, | |
200 | - serverPublicKey: serverSecurityConfig.serverPublicKey, | |
201 | - clientHoldOffTime: serverSecurityConfig.clientHoldOffTime, | |
202 | - serverId: serverSecurityConfig.serverId, | |
203 | - bootstrapServerAccountTimeout: serverSecurityConfig.bootstrapServerAccountTimeout | |
204 | - }, | |
205 | - {emitEvent: true}); | |
160 | + private propagateChangeState = (value: ServerSecurityConfig): void => { | |
161 | + if (value !== undefined) { | |
162 | + if (this.serverFormGroup.valid) { | |
163 | + this.propagateChange(value); | |
164 | + } else { | |
165 | + this.propagateChange(null); | |
206 | 166 | } |
167 | + } | |
168 | + } | |
169 | + | |
170 | + private getLwm2mBootstrapSecurityInfo(securityMode = securityConfigMode.NO_SEC): Observable<ServerSecurityConfig> { | |
171 | + if (this.securityDefaultConfig) { | |
172 | + return of(this.processingBootstrapSecurityInfo(this.securityDefaultConfig, securityMode)); | |
173 | + } | |
174 | + return this.deviceProfileService.getLwm2mBootstrapSecurityInfo(this.isBootstrapServer).pipe( | |
175 | + map(securityInfo => { | |
176 | + this.securityDefaultConfig = securityInfo; | |
177 | + return this.processingBootstrapSecurityInfo(securityInfo, securityMode); | |
178 | + }) | |
207 | 179 | ); |
208 | 180 | } |
181 | + | |
182 | + private processingBootstrapSecurityInfo(securityConfig: ServerSecurityConfig, securityMode: securityConfigMode): ServerSecurityConfig { | |
183 | + const config = deepClone(securityConfig); | |
184 | + switch (securityMode) { | |
185 | + case securityConfigMode.PSK: | |
186 | + config.port = config.securityPort; | |
187 | + config.host = config.securityHost; | |
188 | + config.serverPublicKey = ''; | |
189 | + break; | |
190 | + case securityConfigMode.RPK: | |
191 | + case securityConfigMode.X509: | |
192 | + config.port = config.securityPort; | |
193 | + config.host = config.securityHost; | |
194 | + break; | |
195 | + case securityConfigMode.NO_SEC: | |
196 | + config.serverPublicKey = ''; | |
197 | + break; | |
198 | + } | |
199 | + return config; | |
200 | + } | |
209 | 201 | } | ... | ... |
... | ... | @@ -15,231 +15,172 @@ |
15 | 15 | limitations under the License. |
16 | 16 | |
17 | 17 | --> |
18 | -<section style="padding-bottom: 16px; margin: 0" mat-dialog-content> | |
18 | +<section style="padding-bottom: 16px; margin: 0"> | |
19 | 19 | <mat-tab-group dynamicHeight> |
20 | 20 | <mat-tab label="{{ 'device-profile.lwm2m.model-tab' | translate }}"> |
21 | 21 | <ng-template matTabContent> |
22 | 22 | <section [formGroup]="lwm2mDeviceProfileFormGroup"> |
23 | - <div class="mat-padding" style="padding-top: 0"> | |
24 | - <tb-profile-lwm2m-object-list | |
25 | - (addList)="addObjectsList($event)" | |
26 | - (removeList)="removeObjectsList($event)" | |
27 | - [required]="required" | |
28 | - formControlName="objectIds"> | |
29 | - </tb-profile-lwm2m-object-list> | |
30 | - </div> | |
31 | - <div class="mat-padding"> | |
32 | - <tb-profile-lwm2m-observe-attr-telemetry | |
33 | - [required]="required" | |
34 | - formControlName="observeAttrTelemetry"> | |
35 | - </tb-profile-lwm2m-observe-attr-telemetry> | |
36 | - </div> | |
37 | - </section> | |
38 | - </ng-template> | |
39 | - </mat-tab> | |
40 | - <mat-tab label="{{ 'device-profile.lwm2m.bootstrap-tab' | translate }}"> | |
41 | - <ng-template matTabContent> | |
42 | - <section [formGroup]="lwm2mDeviceProfileFormGroup"> | |
43 | - <div class="mat-padding"> | |
44 | - <mat-accordion multi="true" class="mat-body-1"> | |
45 | - <mat-expansion-panel> | |
46 | - <mat-expansion-panel-header> | |
47 | - <mat-panel-title> | |
48 | - <div class="tb-panel-title">{{ 'device-profile.lwm2m.servers' | translate | uppercase }}</div> | |
49 | - </mat-panel-title> | |
50 | - </mat-expansion-panel-header> | |
51 | - <ng-template matExpansionPanelContent> | |
52 | - <div fxLayout="column"> | |
53 | - <div fxLayout="row" fxLayoutGap="8px"> | |
54 | - <mat-form-field fxFlex> | |
55 | - <mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label> | |
56 | - <input matInput type="number" formControlName="shortId" required> | |
57 | - <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('shortId').hasError('required')"> | |
58 | - {{ 'device-profile.lwm2m.short-id' | translate }} | |
59 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
60 | - </mat-error> | |
61 | - </mat-form-field> | |
62 | - <mat-form-field fxFlex> | |
63 | - <mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label> | |
64 | - <input matInput type="number" formControlName="lifetime" required> | |
65 | - <mat-error | |
66 | - *ngIf="lwm2mDeviceProfileFormGroup.get('lifetime').hasError('required')"> | |
67 | - {{ 'device-profile.lwm2m.lifetime' | translate }} | |
68 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
69 | - </mat-error> | |
70 | - </mat-form-field> | |
71 | - <mat-form-field fxFlex> | |
72 | - <mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label> | |
73 | - <input matInput type="number" formControlName="defaultMinPeriod" required> | |
74 | - <mat-error | |
75 | - *ngIf="lwm2mDeviceProfileFormGroup.get('defaultMinPeriod').hasError('required')"> | |
76 | - {{ 'device-profile.lwm2m.default-min-period' | translate }} | |
77 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
78 | - </mat-error> | |
79 | - </mat-form-field> | |
80 | - </div> | |
81 | - <div fxLayout="row" fxLayoutGap="8px"> | |
82 | - <mat-form-field class="mat-block" fxFlex="100"> | |
83 | - <mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label> | |
84 | - <mat-select formControlName="binding"> | |
85 | - <mat-option *ngFor="let bindingMode of bindingModeTypes" | |
86 | - [value]="bindingMode"> | |
87 | - {{ bindingModeTypeNamesMap.get(bindingModeType[bindingMode]) }} | |
88 | - </mat-option> | |
89 | - </mat-select> | |
90 | - </mat-form-field> | |
91 | - </div> | |
92 | - <div> | |
93 | - <mat-checkbox formControlName="notifIfDisabled" color="primary"> | |
94 | - {{ 'device-profile.lwm2m.notif-if-disabled' | translate }} | |
95 | - </mat-checkbox> | |
96 | - </div> | |
97 | - </div> | |
98 | - </ng-template> | |
99 | - </mat-expansion-panel> | |
100 | - </mat-accordion> | |
101 | - <mat-accordion multi="true" class="mat-body-1"> | |
102 | - <mat-expansion-panel> | |
103 | - <mat-expansion-panel-header> | |
104 | - <mat-panel-title> | |
105 | - <div | |
106 | - class="tb-panel-title">{{ 'device-profile.lwm2m.bootstrap-server' | translate | uppercase }}</div> | |
107 | - </mat-panel-title> | |
108 | - </mat-expansion-panel-header> | |
109 | - <ng-template matExpansionPanelContent> | |
110 | - <div class="mat-padding"> | |
111 | - <tb-profile-lwm2m-device-config-server | |
112 | - [required]="required" | |
113 | - formControlName="bootstrapServer" | |
114 | - [bootstrapServerIs]=true> | |
115 | - </tb-profile-lwm2m-device-config-server> | |
116 | - </div> | |
117 | - </ng-template> | |
118 | - </mat-expansion-panel> | |
119 | - </mat-accordion> | |
120 | - <mat-accordion multi="true" class="mat-body-1"> | |
121 | - <mat-expansion-panel> | |
122 | - <mat-expansion-panel-header> | |
123 | - <mat-panel-title> | |
124 | - <div class="tb-panel-title">{{ 'device-profile.lwm2m.lwm2m-server' | translate | uppercase }}</div> | |
125 | - </mat-panel-title> | |
126 | - </mat-expansion-panel-header> | |
127 | - <ng-template matExpansionPanelContent> | |
128 | - <div class="mat-padding"> | |
129 | - <tb-profile-lwm2m-device-config-server | |
130 | - [required]="required" | |
131 | - formControlName="lwm2mServer" | |
132 | - [bootstrapServerIs]=false> | |
133 | - </tb-profile-lwm2m-device-config-server> | |
134 | - </div> | |
135 | - </ng-template> | |
136 | - </mat-expansion-panel> | |
137 | - </mat-accordion> | |
138 | - </div> | |
23 | + <tb-profile-lwm2m-object-list | |
24 | + (addList)="addObjectsList($event)" | |
25 | + (removeList)="removeObjectsList($event)" | |
26 | + [required]="required" | |
27 | + formControlName="objectIds"> | |
28 | + </tb-profile-lwm2m-object-list> | |
29 | + <tb-profile-lwm2m-observe-attr-telemetry | |
30 | + [required]="required" | |
31 | + formControlName="observeAttrTelemetry"> | |
32 | + </tb-profile-lwm2m-observe-attr-telemetry> | |
139 | 33 | </section> |
140 | 34 | </ng-template> |
141 | 35 | </mat-tab> |
142 | - <mat-tab label="{{ 'device-profile.lwm2m.others-tab' | translate }}"> | |
36 | + <mat-tab label="{{ 'device-profile.lwm2m.servers' | translate }}"> | |
143 | 37 | <ng-template matTabContent> |
144 | - <section [formGroup]="lwm2mDeviceProfileFormGroup"> | |
145 | - <mat-accordion multi="true" class="mat-body-1"> | |
146 | - <div *ngIf="false"> | |
147 | - <mat-expansion-panel> | |
148 | - <mat-expansion-panel-header> | |
149 | - <mat-panel-title> | |
150 | - <div | |
151 | - class="tb-panel-title">{{ 'device-profile.lwm2m.client-strategy' | translate | uppercase }}</div> | |
152 | - </mat-panel-title> | |
153 | - </mat-expansion-panel-header> | |
154 | - <ng-template matExpansionPanelContent> | |
155 | - <div fxLayout="column"> | |
156 | - <mat-form-field class="mat-block"> | |
157 | - <mat-label>{{ 'device-profile.lwm2m.client-strategy-label' | translate }}</mat-label> | |
158 | - <mat-select formControlName="clientStrategy" | |
159 | - matTooltip="{{ 'device-profile.lwm2m.client-strategy-tip' | translate: | |
160 | - { count: +lwm2mDeviceProfileFormGroup.get('clientStrategy').value } }}" | |
161 | - matTooltipPosition="above"> | |
162 | - <mat-option value=1>{{ 'device-profile.lwm2m.client-strategy-connect' | translate: | |
163 | - {count: 1} }}</mat-option> | |
164 | - <mat-option value=2>{{ 'device-profile.lwm2m.client-strategy-connect' | translate: | |
165 | - {count: 2} }}</mat-option> | |
166 | - </mat-select> | |
167 | - </mat-form-field> | |
168 | - </div> | |
169 | - </ng-template> | |
170 | - </mat-expansion-panel> | |
171 | - </div> | |
38 | + <section [formGroup]="lwm2mDeviceProfileFormGroup" style="padding: 4px 2px"> | |
39 | + <mat-accordion multi="true"> | |
172 | 40 | <mat-expansion-panel> |
173 | 41 | <mat-expansion-panel-header> |
174 | - <mat-panel-title> | |
175 | - <div | |
176 | - class="tb-panel-title">{{ 'device-profile.lwm2m.ota-update-strategy' | translate | uppercase }}</div> | |
177 | - </mat-panel-title> | |
42 | + <mat-panel-title>{{ 'device-profile.lwm2m.servers' | translate }}</mat-panel-title> | |
178 | 43 | </mat-expansion-panel-header> |
179 | 44 | <ng-template matExpansionPanelContent> |
180 | - <div fxLayout="column"> | |
181 | - <mat-form-field class="mat-block" fxFlex> | |
182 | - <mat-label>{{ 'device-profile.lwm2m.fw-update-strategy-label' | translate }}</mat-label> | |
183 | - <mat-select formControlName="fwUpdateStrategy" (selectionChange)="changeFwUpdateStrategy($event)"> | |
184 | - <mat-option value=1>{{ 'device-profile.lwm2m.fw-update-strategy' | translate: | |
185 | - {count: 1} }}</mat-option> | |
186 | - <mat-option value=2>{{ 'device-profile.lwm2m.fw-update-strategy' | translate: | |
187 | - {count: 2} }}</mat-option> | |
188 | - <mat-option value=3>{{ 'device-profile.lwm2m.fw-update-strategy' | translate: | |
189 | - {count: 3} }}</mat-option> | |
190 | - </mat-select> | |
45 | + <div fxLayout="row" fxLayout.xs="column" fxLayoutGap="8px" fxLayoutGap.xs="0px"> | |
46 | + <mat-form-field fxFlex> | |
47 | + <mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label> | |
48 | + <input matInput type="number" formControlName="shortId" required> | |
49 | + <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('shortId').hasError('required')"> | |
50 | + {{ 'device-profile.lwm2m.short-id' | translate }} | |
51 | + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
52 | + </mat-error> | |
191 | 53 | </mat-form-field> |
192 | - <mat-form-field class="mat-block" fxFlex> | |
193 | - <mat-label>{{ 'device-profile.lwm2m.sw-update-strategy-label' | translate }}</mat-label> | |
194 | - <mat-select formControlName="swUpdateStrategy" (selectionChange)="changeSwUpdateStrategy($event)"> | |
195 | - <mat-option value=1>{{ 'device-profile.lwm2m.sw-update-strategy' | translate: | |
196 | - {count: 1} }}</mat-option> | |
197 | - <mat-option value=2>{{ 'device-profile.lwm2m.sw-update-strategy' | translate: | |
198 | - {count: 2} }}</mat-option> | |
199 | - </mat-select> | |
54 | + <mat-form-field fxFlex> | |
55 | + <mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label> | |
56 | + <input matInput type="number" formControlName="lifetime" required> | |
57 | + <mat-error | |
58 | + *ngIf="lwm2mDeviceProfileFormGroup.get('lifetime').hasError('required')"> | |
59 | + {{ 'device-profile.lwm2m.lifetime' | translate }} | |
60 | + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
61 | + </mat-error> | |
62 | + </mat-form-field> | |
63 | + <mat-form-field fxFlex> | |
64 | + <mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label> | |
65 | + <input matInput type="number" formControlName="defaultMinPeriod" required> | |
66 | + <mat-error | |
67 | + *ngIf="lwm2mDeviceProfileFormGroup.get('defaultMinPeriod').hasError('required')"> | |
68 | + {{ 'device-profile.lwm2m.default-min-period' | translate }} | |
69 | + <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
70 | + </mat-error> | |
200 | 71 | </mat-form-field> |
201 | 72 | </div> |
73 | + <mat-form-field class="mat-block"> | |
74 | + <mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label> | |
75 | + <mat-select formControlName="binding"> | |
76 | + <mat-option *ngFor="let bindingMode of bindingModeTypes" | |
77 | + [value]="bindingMode"> | |
78 | + {{ bindingModeTypeNamesMap.get(bindingModeType[bindingMode]) }} | |
79 | + </mat-option> | |
80 | + </mat-select> | |
81 | + </mat-form-field> | |
82 | + <mat-checkbox formControlName="notifIfDisabled" color="primary"> | |
83 | + {{ 'device-profile.lwm2m.notif-if-disabled' | translate }} | |
84 | + </mat-checkbox> | |
202 | 85 | </ng-template> |
203 | 86 | </mat-expansion-panel> |
204 | - <mat-expansion-panel *ngIf="isFwUpdateStrategy || isSwUpdateStrategy"> | |
87 | + <mat-expansion-panel> | |
205 | 88 | <mat-expansion-panel-header> |
206 | - <mat-panel-title> | |
207 | - <div | |
208 | - class="tb-panel-title">{{ 'device-profile.lwm2m.ota-update-recourse' | translate | uppercase }}</div> | |
209 | - </mat-panel-title> | |
89 | + <mat-panel-title>{{ 'device-profile.lwm2m.bootstrap-server' | translate }}</mat-panel-title> | |
210 | 90 | </mat-expansion-panel-header> |
211 | 91 | <ng-template matExpansionPanelContent> |
212 | - <div fxLayout="column"> | |
213 | - <div *ngIf="isFwUpdateStrategy"> | |
214 | - <mat-form-field class="mat-block" fxFlex> | |
215 | - <mat-label>{{ 'device-profile.lwm2m.fw-update-recourse' | translate }}</mat-label> | |
216 | - <input matInput formControlName="fwUpdateRecourse" required> | |
217 | - <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').hasError('required')"> | |
218 | - {{ 'device-profile.lwm2m.fw-update-recourse' | translate }} | |
219 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
220 | - </mat-error> | |
221 | - </mat-form-field> | |
222 | - </div> | |
223 | - <div *ngIf="isSwUpdateStrategy"> | |
224 | - <mat-form-field class="mat-block" fxFlex> | |
225 | - <mat-label>{{ 'device-profile.lwm2m.sw-update-recourse' | translate }}</mat-label> | |
226 | - <input matInput formControlName="swUpdateRecourse" required> | |
227 | - <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').hasError('required')"> | |
228 | - {{ 'device-profile.lwm2m.sw-update-recourse' | translate }} | |
229 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | |
230 | - </mat-error> | |
231 | - </mat-form-field> | |
232 | - </div> | |
233 | - </div> | |
92 | + <tb-profile-lwm2m-device-config-server | |
93 | + [required]="required" | |
94 | + formControlName="bootstrapServer" | |
95 | + [isBootstrapServer]="true"> | |
96 | + </tb-profile-lwm2m-device-config-server> | |
97 | + </ng-template> | |
98 | + </mat-expansion-panel> | |
99 | + <mat-expansion-panel> | |
100 | + <mat-expansion-panel-header> | |
101 | + <mat-panel-title>{{ 'device-profile.lwm2m.lwm2m-server' | translate }}</mat-panel-title> | |
102 | + </mat-expansion-panel-header> | |
103 | + <ng-template matExpansionPanelContent> | |
104 | + <tb-profile-lwm2m-device-config-server | |
105 | + [required]="required" | |
106 | + formControlName="lwm2mServer" | |
107 | + [isBootstrapServer]="false"> | |
108 | + </tb-profile-lwm2m-device-config-server> | |
234 | 109 | </ng-template> |
235 | 110 | </mat-expansion-panel> |
236 | 111 | </mat-accordion> |
237 | 112 | </section> |
238 | 113 | </ng-template> |
239 | 114 | </mat-tab> |
115 | + <mat-tab label="{{ 'device-profile.lwm2m.others-tab' | translate }}"> | |
116 | + <ng-template matTabContent> | |
117 | + <section [formGroup]="lwm2mDeviceProfileFormGroup"> | |
118 | + <fieldset class="fields-group"> | |
119 | + <legend class="group-title" translate>device-profile.lwm2m.fw-update</legend> | |
120 | + <mat-form-field class="mat-block" fxFlex> | |
121 | + <mat-label>{{ 'device-profile.lwm2m.fw-update-strategy' | translate }}</mat-label> | |
122 | + <mat-select formControlName="fwUpdateStrategy"> | |
123 | + <mat-option [value]=1>{{ 'device-profile.lwm2m.fw-update-strategy-package' | translate }}</mat-option> | |
124 | + <mat-option [value]=2>{{ 'device-profile.lwm2m.fw-update-strategy-package-uri' | translate }}</mat-option> | |
125 | + <mat-option [value]=3>{{ 'device-profile.lwm2m.fw-update-strategy-data' | translate }}</mat-option> | |
126 | + </mat-select> | |
127 | + </mat-form-field> | |
128 | + <mat-form-field class="mat-block" fxFlex *ngIf="isFwUpdateStrategy"> | |
129 | + <mat-label>{{ 'device-profile.lwm2m.fw-update-recourse' | translate }}</mat-label> | |
130 | + <input matInput formControlName="fwUpdateRecourse" required> | |
131 | + <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').hasError('required')"> | |
132 | + {{ 'device-profile.lwm2m.fw-update-recourse-required' | translate }} | |
133 | + </mat-error> | |
134 | + </mat-form-field> | |
135 | + </fieldset> | |
136 | + <fieldset class="fields-group"> | |
137 | + <legend class="group-title" translate>device-profile.lwm2m.sw-update</legend> | |
138 | + <mat-form-field class="mat-block" fxFlex> | |
139 | + <mat-label>{{ 'device-profile.lwm2m.sw-update-strategy' | translate }}</mat-label> | |
140 | + <mat-select formControlName="swUpdateStrategy"> | |
141 | + <mat-option [value]=1>{{ 'device-profile.lwm2m.sw-update-strategy-package' | translate }}</mat-option> | |
142 | + <mat-option [value]=2>{{ 'device-profile.lwm2m.sw-update-strategy-package-uri' | translate }}</mat-option> | |
143 | + </mat-select> | |
144 | + </mat-form-field> | |
145 | + <mat-form-field class="mat-block" fxFlex *ngIf="isSwUpdateStrategy"> | |
146 | + <mat-label>{{ 'device-profile.lwm2m.sw-update-recourse' | translate }}</mat-label> | |
147 | + <input matInput formControlName="swUpdateRecourse" required> | |
148 | + <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').hasError('required')"> | |
149 | + {{ 'device-profile.lwm2m.sw-update-recourse-required' | translate }} | |
150 | + </mat-error> | |
151 | + </mat-form-field> | |
152 | + </fieldset> | |
153 | +<!-- <mat-accordion multi="true">--> | |
154 | +<!-- <div *ngIf="false">--> | |
155 | +<!-- <mat-expansion-panel>--> | |
156 | +<!-- <mat-expansion-panel-header>--> | |
157 | +<!-- <mat-panel-title>{{ 'device-profile.lwm2m.client-strategy' | translate }}</mat-panel-title>--> | |
158 | +<!-- </mat-expansion-panel-header>--> | |
159 | +<!-- <ng-template matExpansionPanelContent>--> | |
160 | +<!-- <div fxLayout="column">--> | |
161 | +<!-- <mat-form-field class="mat-block">--> | |
162 | +<!-- <mat-label>{{ 'device-profile.lwm2m.client-strategy-label' | translate }}</mat-label>--> | |
163 | +<!-- <mat-select formControlName="clientStrategy"--> | |
164 | +<!-- matTooltip="{{ 'device-profile.lwm2m.client-strategy-tip' | translate:--> | |
165 | +<!-- { count: +lwm2mDeviceProfileFormGroup.get('clientStrategy').value } }}"--> | |
166 | +<!-- matTooltipPosition="above">--> | |
167 | +<!-- <mat-option value=1>{{ 'device-profile.lwm2m.client-strategy-connect' | translate:--> | |
168 | +<!-- {count: 1} }}</mat-option>--> | |
169 | +<!-- <mat-option value=2>{{ 'device-profile.lwm2m.client-strategy-connect' | translate:--> | |
170 | +<!-- {count: 2} }}</mat-option>--> | |
171 | +<!-- </mat-select>--> | |
172 | +<!-- </mat-form-field>--> | |
173 | +<!-- </div>--> | |
174 | +<!-- </ng-template>--> | |
175 | +<!-- </mat-expansion-panel>--> | |
176 | +<!-- </div>--> | |
177 | +<!-- </mat-accordion>--> | |
178 | + </section> | |
179 | + </ng-template> | |
180 | + </mat-tab> | |
240 | 181 | <mat-tab label="{{ 'device-profile.lwm2m.config-json-tab' | translate }}"> |
241 | 182 | <ng-template matTabContent> |
242 | - <section [formGroup]="lwm2mDeviceConfigFormGroup" class="mat-padding"> | |
183 | + <section [formGroup]="lwm2mDeviceConfigFormGroup" style="padding: 8px 0"> | |
243 | 184 | <tb-json-object-edit |
244 | 185 | [required]="required" |
245 | 186 | [sort]="sortFunction" | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2021 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +:host{ | |
17 | + .fields-group { | |
18 | + padding: 8px; | |
19 | + margin: 10px 0; | |
20 | + border: 1px groove rgba(0, 0, 0, .25); | |
21 | + border-radius: 4px; | |
22 | + | |
23 | + legend { | |
24 | + color: rgba(0, 0, 0, .7); | |
25 | + } | |
26 | + } | |
27 | +} | ... | ... |
... | ... | @@ -43,11 +43,11 @@ import { Direction } from '@shared/models/page/sort-order'; |
43 | 43 | import _ from 'lodash'; |
44 | 44 | import { Subject } from 'rxjs'; |
45 | 45 | import { takeUntil } from 'rxjs/operators'; |
46 | -import { MatSelectChange } from '@angular/material/select'; | |
47 | 46 | |
48 | 47 | @Component({ |
49 | 48 | selector: 'tb-profile-lwm2m-device-transport-configuration', |
50 | 49 | templateUrl: './lwm2m-device-profile-transport-configuration.component.html', |
50 | + styleUrls: ['./lwm2m-device-profile-transport-configuration.component.scss'], | |
51 | 51 | providers: [{ |
52 | 52 | provide: NG_VALUE_ACCESSOR, |
53 | 53 | useExisting: forwardRef(() => Lwm2mDeviceProfileTransportConfigurationComponent), |
... | ... | @@ -100,12 +100,38 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
100 | 100 | clientStrategy: [1, []], |
101 | 101 | fwUpdateStrategy: [1, []], |
102 | 102 | swUpdateStrategy: [1, []], |
103 | - fwUpdateRecourse: ['', []], | |
104 | - swUpdateRecourse: ['', []] | |
103 | + fwUpdateRecourse: [{value: '', disabled: true}, []], | |
104 | + swUpdateRecourse: [{value: '', disabled: true}, []] | |
105 | 105 | }); |
106 | 106 | this.lwm2mDeviceConfigFormGroup = this.fb.group({ |
107 | 107 | configurationJson: [null, Validators.required] |
108 | 108 | }); |
109 | + this.lwm2mDeviceProfileFormGroup.get('fwUpdateStrategy').valueChanges.pipe( | |
110 | + takeUntil(this.destroy$) | |
111 | + ).subscribe((fwStrategy) => { | |
112 | + if (fwStrategy === 2) { | |
113 | + this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').enable({emitEvent: false}); | |
114 | + this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').patchValue(DEFAULT_FW_UPDATE_RESOURCE, {emitEvent: false}); | |
115 | + this.isFwUpdateStrategy = true; | |
116 | + } else { | |
117 | + this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').disable({emitEvent: false}); | |
118 | + this.isFwUpdateStrategy = false; | |
119 | + } | |
120 | + this.otaUpdateFwStrategyValidate(true); | |
121 | + }); | |
122 | + this.lwm2mDeviceProfileFormGroup.get('swUpdateStrategy').valueChanges.pipe( | |
123 | + takeUntil(this.destroy$) | |
124 | + ).subscribe((swStrategy) => { | |
125 | + if (swStrategy === 2) { | |
126 | + this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').enable({emitEvent: false}); | |
127 | + this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').patchValue(DEFAULT_SW_UPDATE_RESOURCE, {emitEvent: false}); | |
128 | + this.isSwUpdateStrategy = true; | |
129 | + } else { | |
130 | + this.isSwUpdateStrategy = false; | |
131 | + this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').disable({emitEvent: false}); | |
132 | + } | |
133 | + this.otaUpdateSwStrategyValidate(true); | |
134 | + }); | |
109 | 135 | this.lwm2mDeviceProfileFormGroup.valueChanges.pipe( |
110 | 136 | takeUntil(this.destroy$) |
111 | 137 | ).subscribe((value) => { |
... | ... | @@ -176,11 +202,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
176 | 202 | } |
177 | 203 | |
178 | 204 | private updateWriteValue = (value: ModelValue): void => { |
179 | - let fwResource = this.configurationValue.clientLwM2mSettings.fwUpdateStrategy === '2' && | |
180 | - isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateRecourse) ? | |
205 | + const fwResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateRecourse) ? | |
181 | 206 | this.configurationValue.clientLwM2mSettings.fwUpdateRecourse : ''; |
182 | - let swResource = this.configurationValue.clientLwM2mSettings.swUpdateStrategy === '2' && | |
183 | - isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateRecourse) ? | |
207 | + const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateRecourse) ? | |
184 | 208 | this.configurationValue.clientLwM2mSettings.swUpdateRecourse : ''; |
185 | 209 | this.lwm2mDeviceProfileFormGroup.patchValue({ |
186 | 210 | objectIds: value, |
... | ... | @@ -193,16 +217,16 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
193 | 217 | bootstrapServer: this.configurationValue.bootstrap.bootstrapServer, |
194 | 218 | lwm2mServer: this.configurationValue.bootstrap.lwm2mServer, |
195 | 219 | clientStrategy: this.configurationValue.clientLwM2mSettings.clientStrategy, |
196 | - fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy, | |
197 | - swUpdateStrategy: this.configurationValue.clientLwM2mSettings.swUpdateStrategy, | |
220 | + fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy || 1, | |
221 | + swUpdateStrategy: this.configurationValue.clientLwM2mSettings.swUpdateStrategy || 1, | |
198 | 222 | fwUpdateRecourse: fwResource, |
199 | 223 | swUpdateRecourse: swResource |
200 | 224 | }, |
201 | 225 | {emitEvent: false}); |
202 | 226 | this.configurationValue.clientLwM2mSettings.fwUpdateRecourse = fwResource; |
203 | 227 | this.configurationValue.clientLwM2mSettings.swUpdateRecourse = swResource; |
204 | - this.isFwUpdateStrategy = this.configurationValue.clientLwM2mSettings.fwUpdateStrategy === '2'; | |
205 | - this.isSwUpdateStrategy = this.configurationValue.clientLwM2mSettings.swUpdateStrategy === '2'; | |
228 | + this.isFwUpdateStrategy = this.configurationValue.clientLwM2mSettings.fwUpdateStrategy === 2; | |
229 | + this.isSwUpdateStrategy = this.configurationValue.clientLwM2mSettings.swUpdateStrategy === 2; | |
206 | 230 | this.otaUpdateSwStrategyValidate(); |
207 | 231 | this.otaUpdateFwStrategyValidate(); |
208 | 232 | } |
... | ... | @@ -239,8 +263,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
239 | 263 | this.configurationValue.clientLwM2mSettings.fwUpdateRecourse = config.fwUpdateRecourse; |
240 | 264 | this.configurationValue.clientLwM2mSettings.swUpdateRecourse = config.swUpdateRecourse; |
241 | 265 | this.upDateJsonAllConfig(); |
242 | - this.updateModel(); | |
243 | 266 | } |
267 | + this.updateModel(); | |
244 | 268 | } |
245 | 269 | |
246 | 270 | private getObserveAttrTelemetryObjects = (objectList: ObjectLwM2M[]): object => { |
... | ... | @@ -513,53 +537,22 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
513 | 537 | }); |
514 | 538 | } |
515 | 539 | |
516 | - changeFwUpdateStrategy($event: MatSelectChange) { | |
517 | - if ($event.value === '2') { | |
518 | - this.isFwUpdateStrategy = true; | |
519 | - if (isEmpty(this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').value)) { | |
520 | - this.lwm2mDeviceProfileFormGroup.patchValue({ | |
521 | - fwUpdateRecourse: DEFAULT_FW_UPDATE_RESOURCE | |
522 | - }, | |
523 | - {emitEvent: false}); | |
524 | - } | |
525 | - } else { | |
526 | - this.isFwUpdateStrategy = false; | |
527 | - } | |
528 | - this.otaUpdateFwStrategyValidate(); | |
529 | - } | |
530 | - | |
531 | - changeSwUpdateStrategy($event: MatSelectChange) { | |
532 | - if ($event.value === '2') { | |
533 | - this.isSwUpdateStrategy = true; | |
534 | - if (isEmpty(this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').value)) { | |
535 | - this.lwm2mDeviceProfileFormGroup.patchValue({ | |
536 | - swUpdateRecourse: DEFAULT_SW_UPDATE_RESOURCE | |
537 | - }, | |
538 | - {emitEvent: false}); | |
539 | - | |
540 | - } | |
541 | - } else { | |
542 | - this.isSwUpdateStrategy = false; | |
543 | - } | |
544 | - this.otaUpdateSwStrategyValidate(); | |
545 | - } | |
546 | - | |
547 | - private otaUpdateFwStrategyValidate(): void { | |
540 | + private otaUpdateFwStrategyValidate(updated = false): void { | |
548 | 541 | if (this.isFwUpdateStrategy) { |
549 | 542 | this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').setValidators([Validators.required]); |
550 | 543 | } else { |
551 | 544 | this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').clearValidators(); |
552 | 545 | } |
553 | - this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').updateValueAndValidity(); | |
546 | + this.lwm2mDeviceProfileFormGroup.get('fwUpdateRecourse').updateValueAndValidity({emitEvent: updated}); | |
554 | 547 | } |
555 | 548 | |
556 | - private otaUpdateSwStrategyValidate(): void { | |
549 | + private otaUpdateSwStrategyValidate(updated = false): void { | |
557 | 550 | if (this.isSwUpdateStrategy) { |
558 | 551 | this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').setValidators([Validators.required]); |
559 | 552 | } else { |
560 | 553 | this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').clearValidators(); |
561 | 554 | } |
562 | - this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').updateValueAndValidity(); | |
555 | + this.lwm2mDeviceProfileFormGroup.get('swUpdateRecourse').updateValueAndValidity({emitEvent: updated}); | |
563 | 556 | } |
564 | 557 | |
565 | 558 | } | ... | ... |
... | ... | @@ -20,7 +20,6 @@ export const INSTANCE = 'instance'; |
20 | 20 | export const RESOURCES = 'resources'; |
21 | 21 | export const ATTRIBUTE_LWM2M = 'attributeLwm2m'; |
22 | 22 | export const CLIENT_LWM2M = 'clientLwM2M'; |
23 | -export const CLIENT_LWM2M_SETTINGS = 'clientLwM2mSettings'; | |
24 | 23 | export const OBSERVE_ATTR_TELEMETRY = 'observeAttrTelemetry'; |
25 | 24 | export const OBSERVE = 'observe'; |
26 | 25 | export const ATTRIBUTE = 'attribute'; |
... | ... | @@ -43,9 +42,9 @@ export const KEY_REGEXP_HEX_DEC = /^[-+]?[0-9A-Fa-f]+\.?[0-9A-Fa-f]*?$/; |
43 | 42 | export const KEY_REGEXP_NUMBER = /^(\-?|\+?)\d*$/; |
44 | 43 | export const INSTANCES_ID_VALUE_MIN = 0; |
45 | 44 | export const INSTANCES_ID_VALUE_MAX = 65535; |
46 | -export const DEFAULT_OTA_UPDATE_PROTOCOL = "coap://"; | |
47 | -export const DEFAULT_FW_UPDATE_RESOURCE = DEFAULT_OTA_UPDATE_PROTOCOL + DEFAULT_LOCAL_HOST_NAME + ":"+ DEFAULT_PORT_SERVER_NO_SEC; | |
48 | -export const DEFAULT_SW_UPDATE_RESOURCE = DEFAULT_OTA_UPDATE_PROTOCOL + DEFAULT_LOCAL_HOST_NAME + ":"+ DEFAULT_PORT_SERVER_NO_SEC; | |
45 | +export const DEFAULT_OTA_UPDATE_PROTOCOL = 'coap://'; | |
46 | +export const DEFAULT_FW_UPDATE_RESOURCE = DEFAULT_OTA_UPDATE_PROTOCOL + DEFAULT_LOCAL_HOST_NAME + ':' + DEFAULT_PORT_SERVER_NO_SEC; | |
47 | +export const DEFAULT_SW_UPDATE_RESOURCE = DEFAULT_OTA_UPDATE_PROTOCOL + DEFAULT_LOCAL_HOST_NAME + ':' + DEFAULT_PORT_SERVER_NO_SEC; | |
49 | 48 | |
50 | 49 | |
51 | 50 | export enum BINDING_MODE { |
... | ... | @@ -113,19 +112,19 @@ export const ATTRIBUTE_LWM2M_MAP = new Map<ATTRIBUTE_LWM2M_ENUM, string>( |
113 | 112 | |
114 | 113 | export const ATTRIBUTE_KEYS = Object.keys(ATTRIBUTE_LWM2M_ENUM) as string[]; |
115 | 114 | |
116 | -export enum SECURITY_CONFIG_MODE { | |
115 | +export enum securityConfigMode { | |
117 | 116 | PSK = 'PSK', |
118 | 117 | RPK = 'RPK', |
119 | 118 | X509 = 'X509', |
120 | 119 | NO_SEC = 'NO_SEC' |
121 | 120 | } |
122 | 121 | |
123 | -export const SECURITY_CONFIG_MODE_NAMES = new Map<SECURITY_CONFIG_MODE, string>( | |
122 | +export const securityConfigModeNames = new Map<securityConfigMode, string>( | |
124 | 123 | [ |
125 | - [SECURITY_CONFIG_MODE.PSK, 'Pre-Shared Key'], | |
126 | - [SECURITY_CONFIG_MODE.RPK, 'Raw Public Key'], | |
127 | - [SECURITY_CONFIG_MODE.X509, 'X.509 Certificate'], | |
128 | - [SECURITY_CONFIG_MODE.NO_SEC, 'No Security'] | |
124 | + [securityConfigMode.PSK, 'Pre-Shared Key'], | |
125 | + [securityConfigMode.RPK, 'Raw Public Key'], | |
126 | + [securityConfigMode.X509, 'X.509 Certificate'], | |
127 | + [securityConfigMode.NO_SEC, 'No Security'] | |
129 | 128 | ] |
130 | 129 | ); |
131 | 130 | |
... | ... | @@ -144,9 +143,10 @@ export interface BootstrapServersSecurityConfig { |
144 | 143 | |
145 | 144 | export interface ServerSecurityConfig { |
146 | 145 | host?: string; |
146 | + securityHost?: string; | |
147 | 147 | port?: number; |
148 | - bootstrapServerIs?: boolean; | |
149 | - securityMode: string; | |
148 | + securityPort?: number; | |
149 | + securityMode: securityConfigMode; | |
150 | 150 | clientPublicKeyOrId?: string; |
151 | 151 | clientSecretKey?: string; |
152 | 152 | serverPublicKey?: string; |
... | ... | @@ -169,8 +169,8 @@ export interface Lwm2mProfileConfigModels { |
169 | 169 | |
170 | 170 | export interface ClientLwM2mSettings { |
171 | 171 | clientStrategy: string; |
172 | - fwUpdateStrategy: string; | |
173 | - swUpdateStrategy: string; | |
172 | + fwUpdateStrategy: number; | |
173 | + swUpdateStrategy: number; | |
174 | 174 | fwUpdateRecourse: string; |
175 | 175 | swUpdateRecourse: string; |
176 | 176 | } |
... | ... | @@ -193,12 +193,11 @@ export function getDefaultBootstrapServersSecurityConfig(): BootstrapServersSecu |
193 | 193 | }; |
194 | 194 | } |
195 | 195 | |
196 | -export function getDefaultBootstrapServerSecurityConfig(hostname: any): ServerSecurityConfig { | |
196 | +export function getDefaultBootstrapServerSecurityConfig(hostname: string): ServerSecurityConfig { | |
197 | 197 | return { |
198 | 198 | host: hostname, |
199 | 199 | port: DEFAULT_PORT_BOOTSTRAP_NO_SEC, |
200 | - bootstrapServerIs: true, | |
201 | - securityMode: SECURITY_CONFIG_MODE.NO_SEC.toString(), | |
200 | + securityMode: securityConfigMode.NO_SEC, | |
202 | 201 | serverPublicKey: '', |
203 | 202 | clientHoldOffTime: DEFAULT_CLIENT_HOLD_OFF_TIME, |
204 | 203 | serverId: DEFAULT_ID_BOOTSTRAP, |
... | ... | @@ -208,7 +207,6 @@ export function getDefaultBootstrapServerSecurityConfig(hostname: any): ServerSe |
208 | 207 | |
209 | 208 | export function getDefaultLwM2MServerSecurityConfig(hostname): ServerSecurityConfig { |
210 | 209 | const DefaultLwM2MServerSecurityConfig = getDefaultBootstrapServerSecurityConfig(hostname); |
211 | - DefaultLwM2MServerSecurityConfig.bootstrapServerIs = false; | |
212 | 210 | DefaultLwM2MServerSecurityConfig.port = DEFAULT_PORT_SERVER_NO_SEC; |
213 | 211 | DefaultLwM2MServerSecurityConfig.serverId = DEFAULT_ID_SERVER; |
214 | 212 | return DefaultLwM2MServerSecurityConfig; |
... | ... | @@ -242,9 +240,9 @@ export function getDefaultProfileConfig(hostname?: any): Lwm2mProfileConfigModel |
242 | 240 | |
243 | 241 | function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings { |
244 | 242 | return { |
245 | - clientStrategy: "1", | |
246 | - fwUpdateStrategy: "1", | |
247 | - swUpdateStrategy: "1", | |
243 | + clientStrategy: '1', | |
244 | + fwUpdateStrategy: 1, | |
245 | + swUpdateStrategy: 1, | |
248 | 246 | fwUpdateRecourse: DEFAULT_FW_UPDATE_RESOURCE, |
249 | 247 | swUpdateRecourse: DEFAULT_SW_UPDATE_RESOURCE |
250 | 248 | }; | ... | ... |
... | ... | @@ -1243,7 +1243,7 @@ |
1243 | 1243 | "pattern_hex_dec": "{ count, plural, 0 {must be hex decimal format} other {must be # characters} }", |
1244 | 1244 | "servers": "Servers", |
1245 | 1245 | "short-id": "Short ID", |
1246 | - "short-id-tip": "Short Server ID", | |
1246 | + "short-id-required": "Short ID is required.", | |
1247 | 1247 | "lifetime": "Lifetime of the registration for this LwM2M client", |
1248 | 1248 | "default-min-period": "Minimum Period between two notifications (sec)", |
1249 | 1249 | "notif-if-disabled": "Notification Storing When Disabled or Offline", |
... | ... | @@ -1252,28 +1252,37 @@ |
1252 | 1252 | "bootstrap-server": "Bootstrap Server", |
1253 | 1253 | "lwm2m-server": "LwM2M Server", |
1254 | 1254 | "server-host": "Host", |
1255 | - "server-host-tip": "Server Host", | |
1255 | + "server-host-required": "Host is required.", | |
1256 | 1256 | "server-port": "Port", |
1257 | - "server-port-tip": "Server Port", | |
1257 | + "server-port-required": "Port is required.", | |
1258 | 1258 | "server-public-key": "Server Public Key", |
1259 | - "server-public-key-tip": "Server Public Key only for X509, RPK", | |
1259 | + "server-public-key-required": "Server Public Key is required.", | |
1260 | + "server-public-key-pattern": "Server Public Key must be hex decimal format.", | |
1261 | + "server-public-key-length": "Server Public Key must be {{ count }} characters.", | |
1260 | 1262 | "client-hold-off-time": "Hold Off Time", |
1261 | - "client-hold-off-time-tip": "Client Hold Off Time for use with a Bootstrap-Server only", | |
1262 | - "bootstrap-server-account-timeout": "Account after the timeout", | |
1263 | - "bootstrap-server-account-timeout-tip": "Bootstrap-Server Account after the timeout value given by this resource.", | |
1264 | - "others-tab": "Other settings...", | |
1263 | + "client-hold-off-time-required": "Hold Off Time is required.", | |
1264 | + "client-hold-off-time-tooltip": "Client Hold Off Time for use with a Bootstrap-Server only", | |
1265 | + "account-after-timeout": "Account after the timeout", | |
1266 | + "account-after-timeout-required": "Account after the timeout is required.", | |
1267 | + "account-after-timeout-tooltip": "Bootstrap-Server Account after the timeout value given by this resource.", | |
1268 | + "others-tab": "Other settings", | |
1265 | 1269 | "client-strategy": "Client strategy when connecting", |
1266 | 1270 | "client-strategy-label": "Strategy", |
1267 | 1271 | "client-strategy-connect": "{ count, plural, 1 {1: Only Observe Request to the client after the initial connection} other {2: Read All Resources & Observe Request to the client after registration} }", |
1268 | 1272 | "client-strategy-tip": "{ count, plural, 1 {Strategy 1: After the initial connection of the LWM2M Client, the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} other {Strategy 2: After the registration, request the client to read all the resource values for all objects that the LWM2M client has,\n then execute: the server sends Observe resources Request to the client, those resources that are marked as observation in the Device profile and which exist on the LWM2M client.} }", |
1269 | - "ota-update-strategy": "Ota update strategy", | |
1270 | - "fw-update-strategy-label": "Firmware update strategy", | |
1271 | - "fw-update-strategy": "{ count, plural, 1 {Push firmware update as binary file using Object 5 and Resource 0 (Package).} 2 {Auto-generate unique CoAP URL to download the package and push firmware update as Object 5 and Resource 1 (Package URI).} other {Push firmware update as binary file using Object 19 and Resource 0 (Data).} }", | |
1272 | - "sw-update-strategy-label": "Software update strategy", | |
1273 | - "sw-update-strategy": "{ count, plural, 1 {Push binary file using Object 9 and Resource 2 (Package).} other {Auto-generate unique CoAP URL to download the package and push software update using Object 9 and Resource 3 (Package URI).} }", | |
1274 | - "ota-update-recourse": "Ota update Coap recourse", | |
1275 | - "fw-update-recourse": "Firmware update Coap recourse", | |
1276 | - "sw-update-recourse": "Software update Coap recourse", | |
1273 | + "fw-update": "Firmware update", | |
1274 | + "fw-update-strategy": "Firmware update strategy", | |
1275 | + "fw-update-strategy-data": "Push firmware update as binary file using Object 19 and Resource 0 (Data)", | |
1276 | + "fw-update-strategy-package": "Push firmware update as binary file using Object 5 and Resource 0 (Package)", | |
1277 | + "fw-update-strategy-package-uri": "Auto-generate unique CoAP URL to download the package and push firmware update as Object 5 and Resource 1 (Package URI)", | |
1278 | + "sw-update": "Software update", | |
1279 | + "sw-update-strategy": "Software update strategy", | |
1280 | + "sw-update-strategy-package": "Push binary file using Object 9 and Resource 2 (Package)", | |
1281 | + "sw-update-strategy-package-uri": "Auto-generate unique CoAP URL to download the package and push software update using Object 9 and Resource 3 (Package URI)", | |
1282 | + "fw-update-recourse": "Firmware update CoAP recourse", | |
1283 | + "fw-update-recourse-required": "Firmware update CoAP recourse is required.", | |
1284 | + "sw-update-recourse": "Software update CoAP recourse", | |
1285 | + "sw-update-recourse-required": "Software update CoAP recourse is required.", | |
1277 | 1286 | "config-json-tab": "Json Config Profile Device" |
1278 | 1287 | } |
1279 | 1288 | }, | ... | ... |