• 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
16import mdns from '@ohos.net.mdns';
17import DiscoveredPrinter from '../discovery/DiscoveredPrinter';
18import { Log } from '@ohos/common';
19import { GlobalThisHelper, GlobalThisStorageKey } from '@ohos/common';
20import { SERVICE_IPP, SERVICE_IPPS, MDNS_EMITTER_EVENT_ID } from '@ohos/common';
21import Discovery from './Discovery';
22import type common from '@ohos.app.ability.common';
23import CheckEmptyUtils from '@ohos/common';
24import emitter from '@ohos.events.emitter';
25import socket from '@ohos.net.socket';
26import CommonUtils from '../utils/CommonUtils';
27import uri from '@ohos.uri';
28import wifi from '@ohos.wifi';
29
30const TAG = 'MdnsDiscovery';
31
32export class MdnsDiscovery extends Discovery {
33
34  private readonly _serviceName: string;
35  private _discoveryService: mdns.DiscoveryService;
36  private context: common.ExtensionContext;
37  private resolveEvent: emitter.InnerEvent;
38
39  constructor(scheme: string) {
40    super();
41    switch (scheme) {
42      case SERVICE_IPP:
43        this._serviceName = SERVICE_IPP;
44        break;
45      case SERVICE_IPPS:
46        this._serviceName = SERVICE_IPPS;
47        break;
48      default:
49        throw new Error('unrecognized scheme ' + scheme);
50    }
51    this.resolveEvent = { eventId: MDNS_EMITTER_EVENT_ID };
52    emitter.on(this.resolveEvent, this.resolveService);
53  }
54
55  private static toMdnsPrinter(info): DiscoveredPrinter {
56    Log.debug(TAG, 'toMdnsPrinter enter');
57    if (CheckEmptyUtils.isEmpty(info)) {
58      Log.error(TAG, 'serviceInfo is undefined');
59      return undefined;
60    }
61    const path = MdnsDiscovery.getServiceAttribute(info, 'rp');
62    Log.debug(TAG, 'path is: ' + path);
63    if (CheckEmptyUtils.checkStrIsEmpty(path)) {
64      Log.error(TAG, 'rp is missing');
65      return undefined;
66    }
67    if (path.startsWith('/')) {
68      path === path.substring(1);
69    }
70    const uuid = MdnsDiscovery.getServiceAttribute(info, 'UUID');
71    const printerId = `mdns://${uuid}`;
72    let printer: DiscoveredPrinter = new DiscoveredPrinter(<string>info.serviceName, printerId, 0, uuid);
73    printer.setUri(<string>info.host.address, <number>info.host.port, path);
74    return printer;
75  }
76
77  private static getServiceAttribute(serviceInfo, key: string): string {
78    const arr = serviceInfo.serviceAttribute;
79    let result = arr.find((attr) => {
80      return attr.key === key;
81    });
82    if (result === undefined) {
83      Log.error(TAG, `key: ${key}, result is undefined`);
84      return '';
85    }
86    let value: string = '';
87    for (let num of result.value) {
88      value += String.fromCharCode(<number>num);
89    }
90    return value;
91  }
92
93  /**
94  * 开始查找打印机
95   */
96  onStartDiscovery(): void {
97    if (mdns === undefined) {
98      Log.error(TAG, 'mdns is undefined');
99      return;
100    }
101    Log.info(TAG, 'createDiscoveryService: ' + this._serviceName);
102    this.context = GlobalThisHelper.getValue(GlobalThisStorageKey.KEY_ABILITY_CONTEXT);
103    if (CheckEmptyUtils.isEmpty(this._discoveryService)) {
104      this._discoveryService = mdns.createDiscoveryService(this.context, this._serviceName);
105    }
106    if (this._discoveryService === undefined) {
107      Log.error(TAG, 'discoveryService is undefined');
108      return;
109    }
110    Log.info(TAG, 'register callback');
111    this._discoveryService.on('serviceFound', this.onServiceFound);
112    this._discoveryService.on('serviceLost', this.onServiceLost);
113    Log.info(TAG, 'startSearchingMDNS');
114    this._discoveryService.startSearchingMDNS();
115  }
116
117  /**
118  * onServiceFound callback
119   */
120  private onServiceFound = (data): void => {
121    Log.debug(TAG, `onServiceFound, data: ${JSON.stringify(data)} `);
122    emitter.emit(this.resolveEvent, {data: data.serviceInfo});
123  };
124
125  private onServiceLost = (data): void => {
126    Log.debug(TAG, `onServiceLost, data: ${CommonUtils.getSecurityPrinterName(data.serviceInfo.serviceName)} `);
127    if (this.mCachePrinters.size === 0) {
128      Log.error(TAG, 'cache printer is empty');
129      return;
130    }
131    for (let key of this.mCachePrinters.keys()) {
132      if (this.mCachePrinters.get(key).getDeviceName() === data.serviceInfo.serviceName) {
133        this.printerLost(this.mCachePrinters.get(key)?.getPath());
134      }
135    }
136  };
137
138  private resolveService = (eventData: emitter.EventData): void => {
139    Log.debug(TAG, 'resolveService enter');
140    mdns.resolveLocalService(this.context, <mdns.LocalServiceInfo>eventData.data).then((data) => {
141      Log.debug(`${TAG}, resolveLocalService, host is ${CommonUtils.getSecurityIp(data.host.address)}`);
142      if (CheckEmptyUtils.checkStrIsEmpty(data.serviceName)) {
143        Log.info(TAG, 'serviceName is empty');
144        data.serviceName = eventData.data.serviceName;
145      }
146      let printer = MdnsDiscovery.toMdnsPrinter(data);
147      this.printerFound(printer);
148    }).catch((error) => {
149      Log.error(TAG, `resolveLocalService, err is ${JSON.stringify(error)}`);
150    });
151    Log.debug(TAG, 'resolveService end');
152  };
153
154  /**
155   * 停止搜索打印机,释放所有与搜索相关的资源
156  */
157  onStopDiscovery(): void {
158    Log.info(TAG, 'onStopDiscovery enter');
159    if (this._discoveryService === undefined) {
160      Log.info(TAG, 'discoveryService is undefined');
161      return;
162    }
163    this._discoveryService.stopSearchingMDNS();
164  }
165}