• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16// @ts-ignore
17import mdns from '@ohos.net.mdns';
18import DiscoveredPrinter from '../discovery/DiscoveredPrinter';
19import { Log } from '@ohos/common';
20import { GlobalThisHelper, GlobalThisStorageKey } from '@ohos/common';
21import { SERVICE_IPP, SERVICE_IPPS, MDNS_EMITTER_EVENT_ID } from '@ohos/common';
22import Discovery from './Discovery';
23import type common from '@ohos.app.ability.common';
24import CheckEmptyUtils from '@ohos/common';
25import emitter from '@ohos.events.emitter';
26import socket from '@ohos.net.socket';
27import CommonUtils from '../utils/CommonUtils';
28import uri from '@ohos.uri';
29import wifi from '@ohos.wifi';
30
31const TAG = 'MdnsDiscovery';
32
33export class MdnsDiscovery extends Discovery {
34
35  private readonly _serviceName: string;
36  private _discoveryService: mdns.DiscoveryService;
37  private context: common.ExtensionContext;
38  private resolveEvent: emitter.InnerEvent;
39
40  constructor(scheme: string) {
41    super();
42    switch (scheme) {
43      case SERVICE_IPP:
44        this._serviceName = SERVICE_IPP;
45        break;
46      case SERVICE_IPPS:
47        this._serviceName = SERVICE_IPPS;
48        break;
49      default:
50        throw new Error('unrecognized scheme ' + scheme);
51    }
52    this.resolveEvent = { eventId: MDNS_EMITTER_EVENT_ID };
53    emitter.on(this.resolveEvent, this.resolveService);
54  }
55
56  private static toMdnsPrinter(info): DiscoveredPrinter {
57    Log.debug(TAG, 'toMdnsPrinter enter');
58    if (CheckEmptyUtils.isEmpty(info)) {
59      Log.error(TAG, 'serviceInfo is undefined');
60      return undefined;
61    }
62    const path = MdnsDiscovery.getServiceAttribute(info, 'rp');
63    Log.debug(TAG, 'path is: ' + path);
64    if (CheckEmptyUtils.checkStrIsEmpty(path)) {
65      Log.error(TAG, 'rp is missing');
66      return undefined;
67    }
68    if (path.startsWith('/')) {
69      path === path.substring(1);
70    }
71    const uuid = MdnsDiscovery.getServiceAttribute(info, 'UUID');
72    Log.debug(TAG, 'uuid is: ' + uuid);
73    const printerId = `mdns://${uuid}`;
74    let printer: DiscoveredPrinter = new DiscoveredPrinter(<string>info.serviceName, printerId, 0, uuid);
75    Log.debug(TAG, 'host is: ' + JSON.stringify(info.host));
76    printer.setUri(<string>info.host.address, <number>info.host.port, path);
77    return printer;
78  }
79
80  private static getServiceAttribute(serviceInfo, key: string): string {
81    const arr = serviceInfo.serviceAttribute;
82    let result = arr.find((attr) => {
83      return attr.key === key;
84    });
85    if (result === undefined) {
86      Log.error(TAG, `key: ${key}, result is undefined`);
87      return '';
88    }
89    let value: string = '';
90    for (let num of result.value) {
91      value += String.fromCharCode(<number>num);
92    }
93    return value;
94  }
95
96  /**
97  * 开始查找打印机
98   */
99  onStartDiscovery(): void {
100    if (mdns === undefined) {
101      Log.error(TAG, 'mdns is undefined');
102      return;
103    }
104    Log.info(TAG, 'createDiscoveryService: ' + this._serviceName);
105    this.context = GlobalThisHelper.getValue(GlobalThisStorageKey.KEY_ABILITY_CONTEXT);
106    if (CheckEmptyUtils.isEmpty(this._discoveryService)) {
107      this._discoveryService = mdns.createDiscoveryService(this.context, this._serviceName);
108    }
109    if (this._discoveryService === undefined) {
110      Log.error(TAG, 'discoveryService is undefined');
111      return;
112    }
113    Log.info(TAG, 'register callback');
114    this._discoveryService.on('serviceFound', this.onServiceFound);
115    this._discoveryService.on('serviceLost', this.onServiceLost);
116    Log.info(TAG, 'startSearchingMDNS');
117    this._discoveryService.startSearchingMDNS();
118  }
119
120  /**
121  * onServiceFound callback
122   */
123  private onServiceFound = (data): void => {
124    Log.debug(TAG, `onServiceFound, data: ${JSON.stringify(data)} `);
125    emitter.emit(this.resolveEvent, {data: data.serviceInfo});
126  };
127
128  private onServiceLost = (data): void => {
129    Log.debug(TAG, `onServiceLost, data: ${CommonUtils.getSecurityPrinterName(data.serviceInfo.serviceName)} `);
130    if (this.mCachePrinters.size === 0) {
131      Log.error(TAG, 'cache printer is empty');
132      return;
133    }
134    for (let key of this.mCachePrinters.keys()) {
135      if (this.mCachePrinters.get(key).getDeviceName() === data.serviceInfo.serviceName) {
136        this.printerLost(this.mCachePrinters.get(key)?.getPath());
137      }
138    }
139  };
140
141  private resolveService = (eventData: emitter.EventData): void => {
142    Log.debug(TAG, 'resolveService enter');
143    mdns.resolveLocalService(this.context, <mdns.LocalServiceInfo>eventData.data).then((data) => {
144      Log.debug(`${TAG}, resolveLocalService, host is ${CommonUtils.getSecurityIp(data.host.address)}`);
145      if (CheckEmptyUtils.checkStrIsEmpty(data.serviceName)) {
146        Log.info(TAG, 'serviceName is empty');
147        data.serviceName = eventData.data.serviceName;
148      }
149      let printer = MdnsDiscovery.toMdnsPrinter(data);
150      this.printerFound(printer);
151    }).catch((error) => {
152      Log.error(TAG, `resolveLocalService, err is ${JSON.stringify(error)}`);
153    });
154    Log.debug(TAG, 'resolveService end');
155  };
156
157  /**
158   * 停止搜索打印机,释放所有与搜索相关的资源
159  */
160  onStopDiscovery(): void {
161    Log.info(TAG, 'onStopDiscovery enter');
162    if (this._discoveryService === undefined) {
163      Log.info(TAG, 'discoveryService is undefined');
164      return;
165    }
166    this._discoveryService.stopSearchingMDNS();
167  }
168}