5
3

More than 1 year has passed since last update.

新型コロナウイルス接触確認アプリ(COCOA)がインストールされているスマホを数える

Last updated at Posted at 2022-03-26

はじめに

2020年7月頃、Macの Swift Playgrounds で、10秒間、周辺の新型コロナウイルス接触確認アプリ(COCOA)がインストールされているスマホを数えるコードを書きました。
iOSアプリ版も作成したのですが、iOS13以上ではCOCOAが検知できなくなっています。
今回、同様なことを javascript で書くチャレンジです。

Swiftコード

import UIKit
import CoreBluetooth
import PlaygroundSupport

class ViewController: UIViewController, CBCentralManagerDelegate {
    
    var centralManager: CBCentralManager?
    let scanTime: Double = 10 // seconds
    let label = UILabel()
    var count = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        label.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height/4)
        label.center = view.center
        label.textAlignment = .left
        label.font = label.font.withSize(100)
        label.text = "-"
        self.view.addSubview(label)
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }
    
    func scanStart() {
        if centralManager!.isScanning == false {
            let service = CBUUID(string: "fd6f")
            self.centralManager?.scanForPeripherals(withServices: [service], options: nil)
            DispatchQueue.main.asyncAfter(deadline: .now() + scanTime) {
                self.centralManager?.stopScan()
                self.label.text = "\(self.count)"
                self.count = 0
                self.scanStart()
            }
        }
    }
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch (central.state) {
        case .poweredOn:
            scanStart()
        case .unknown:
            break
        case .resetting:
            break
        case .unsupported:
            break
        case .unauthorized:
            break
        case .poweredOff:
            break
        @unknown default:
            break
        }
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        print(peripheral.identifier)
        count += 1
    }
}

PlaygroundPage.current.liveView = ViewController()

macOS Catalina, iPadOS 12のSwift Playgroundsでは、COCOAを検知できますが、macOS Monterey, iPadOS 13以上では、検知できなくなりました。

事前調査

  • node.js v8の古いバージョンでは、nobleのモジュールを使った、BLEの事例があった。
  • openSSLの脆弱性を考慮すると、新しいバージョンを使いたい。
  • できるだけ新しいバージョンのnode.jsでBLEを使う時、アバンダンウェアプロジェクト (Abandonware) のnobleを使うらしい。
  • node.jsの公式サイトには、ARMv6のバイナリがない。

環境

  • Raspberry Pi Zero (CPU ARMv6)
  • Raspberry Pi OS Lite 32bit January 28th 2022 (bullseye)
  • node.js v17.7.2

nodejsのインストール

~/.profile に環境変数を追加します。

VERSION=v17.7.2
DISTRO=linux-armv6l
export PATH=/usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin:$PATH

※VERSIONを書き換えることで、違うバージョンのnodejsをインストールできます。

環境変数を反映します。

. ~/.profile

nodejs公式サイトには、ARMv6のバイナリビルドがないため、非公式ビルドサイトからダウンロードします。

curl -OL https://unofficial-builds.nodejs.org/download/release/$VERSION/node-$VERSION-$DISTRO.tar.gz

ファイルを展開します。

sudo mkdir -p /usr/local/lib/nodejs
sudo tar -zxvf node-v16.14.2-linux-armv6l.tar.gz -C /usr/local/lib/nodejs

シンボリンクリンクを作成します。

sudo ln -s /usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin/node /usr/bin/node
sudo ln -s /usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin/npm /usr/bin/npm
sudo ln -s /usr/local/lib/nodejs/node-$VERSION-$DISTRO/bin/npx /usr/bin/npx

確認

$ node -v
v17.7.2
$ npm -v
8.5.2
$ npx -v
8.5.2
$ node -p process.versions
{
  node: '17.7.2',
  v8: '9.6.180.15-node.15',
  uv: '1.43.0',
  zlib: '1.2.11',
  brotli: '1.0.9',
  ares: '1.18.1',
  modules: '102',
  nghttp2: '1.47.0',
  napi: '8',
  llhttp: '6.0.4',
  openssl: '3.0.2+quic',
  cldr: '40.0',
  icu: '70.1',
  tz: '2021a3',
  unicode: '14.0',
  ngtcp2: '0.1.0-DEV',
  nghttp3: '0.1.0-DEV'
}

nobleのインストール

npm i @abandonware/noble

サンプルコード

10秒間、周辺の新型コロナウイルス接触確認アプリ(COCOA)がインストールされている端末数を数えます。

// COCOA scan.js
'use strict';

const noble = require('@abandonware/noble');
const cocoaDevices = [];

//discovered BLE device
const discovered = (peripheral) => {
    const device = {
        uuid: peripheral.uuid,
        rssi: peripheral.rssi
    };
    cocoaDevices.push(device);
    console.log(`${cocoaDevices.length}:(${device.uuid}) RSSI${device.rssi}`);
}

//BLE scan start
const scanStart = () => {
    //COCOA Service UUID
    noble.startScanning(['fd6f'],false);
    noble.on('discover', discovered);
}

if(noble.state === 'poweredOn'){
    scanStart();
}else{
    noble.on('stateChange', scanStart);
}
setTimeout(function(){
  noble.stopScanning();
  process.exit();
},10000);

実行結果

COCOAアプリ入れた、iPhoneを1台を置いた状態で、試したら、1回目、スマホが1台、2回目、スマホが2台でした。近くに、もう1台、スマホがあるみたい。
スクリーンショット 2022-03-26 17.55.33.png

参考

Node.jsから周辺のBLEデバイスを探すサンプル (2021年4月版)

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3