首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BeaconTransmitting Eddystone TLM frame AltBeacon no work

BeaconTransmitting Eddystone TLM frame AltBeacon no work
EN

Stack Overflow用户
提问于 2016-10-25 19:47:36
回答 3查看 532关注 0票数 0

我正在尝试创建完整的eddystone Beacon仿真器。URL、UID帧没有问题。但是,当我尝试发送TLM额外数据时,没有任何工作。

BeaconParser extraparser,广告是什么时候开始收录的?

这是我的代码:

代码语言:javascript
复制
    //create BeaconParse Like UID and add extraparser for TLM
     BeaconParser beaconParser = new BeaconParser();
                beaconParser.addExtraDataParser(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_TLM_LAYOUT));
                beaconParser.setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT);

                BeaconTransmitter mBeaconTransmitter = new BeaconTransmitter(this, beaconParser);
//this is the beacon with info for UID and ExtraData with 5 values of TLM
Beacon beacon = new Beacon.Builder()
                        .setId1("0x2F234454F4911BA9FFA6")//UID
                        .setId2("0x0BDB87539B67") //UID
                        .setManufacturer(0xfeaa)   //0x00​E0 eddystone
                        .setBeaconTypeCode(0x00) //0X00 withTLM  
                        .setMultiFrameBeacon(true) //TLM
                        .setServiceUuid(0xfeaa) //TLM
                        .setTxPower(-65) //UID
                        .setDataFields(Arrays.asList(new Long[]{0l}))//?
                        .setExtraDataFields(Arrays.asList(new Long[]{0L, 3580L,5776L, 289780991L, 28978000L}))//TLM extradata
                        .build();

//then create the Transmitter and start it
  BeaconTransmitter bt = new BeaconTransmitter(this, beaconParser);
 bt.startAdvertising(beacon);

问题是,当我检测到信标时,它带有MExtraDataFields =null;

我认为TLM信息不包括在BeaconTransmitter发出的advertisingData中。

是否支持TLM信标传输?是BeaconTransmitter限制还是问题是信标引起的?

也许我需要使用标识符来发送这种信息。

我尝试过,三星S5和三星s7Edge,并使用2.9.1版本的AltBeacon

EN

回答 3

Stack Overflow用户

发布于 2016-10-26 01:08:38

抱歉,这不管用。BeaconTransmitter类不会基于额外的数据字段自动发出Eddystone-TLM。尽管我从未显式测试过它,但我认为它根本不能用于传输该帧,因为不可能仅使用数据字段来构造Beacon对象实例,这对于使用现有的BeaconTransmitter类传输Eddystone-TLM是必要的。

这就是说,这是一个合理的功能请求,如果你想增加对它的支持,我当然欢迎你的拉取请求。

完全披露:我是Android Beacon Library开源项目的首席开发人员。

票数 0
EN

Stack Overflow用户

发布于 2016-10-26 16:23:57

好的,非常感谢你的快速响应。

昨天不要加载你的代码,从主和Eddystone Eid,分析如果问题的BEaconEmmitter没有广告的ExtraData。

在阅读了您网站上的一些文档后,我了解到TLM信息在另一个广告包中,通过方法与其他EddyStone/Ibeacon相匹配:

代码语言:javascript
复制
  private String getBeaconKey(Beacon beacon) {
    if (matchBeaconsByServiceUUID) {
        return beacon.getBluetoothAddress() + beacon.getServiceUuid();
    } else {
        return beacon.getBluetoothAddress();
    }
}

如果匹配,则将extraData添加到信标中。

为此,我修改了BeaconTransmitter startAdvertising方法,尝试使用相同的beaconTransmitter发送tlm的通告数据(因为需要在UID信标和TLM信标中具有相同的bTMac ),如下所示:

代码语言:javascript
复制
 if (mBeacon.isMultiFrameBeacon()) {
            byte[] advertisingExtraDataBytes = mBeaconParser.getBeaconAdvertisementDataFromTLM(mBeacon);
            //segun https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md 14 bytes
            //solo con esa info cmo matchea? typebeacon 0x20
            try {
                AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
                //always bigger than 0
                if (serviceUuid > 0) {
                    byte[] serviceUuidBytes = new byte[]{
                            (byte) (serviceUuid & 0xff),
                            (byte) ((serviceUuid >> 8) & 0xff)};
                    ParcelUuid parcelUuid = parseUuidFrom(serviceUuidBytes);
                    dataBuilder.addServiceData(parcelUuid, advertisingExtraDataBytes);
                    dataBuilder.addServiceUuid(parcelUuid);
                  //  dataBuilder.setIncludeTxPowerLevel(false); //no in tlm
                //    dataBuilder.setIncludeDeviceName(false);//no in tlm

                } else {
                    dataBuilder.addManufacturerData(manufacturerCode, advertisingExtraDataBytes);// in tlm?
                }

                AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();

                settingsBuilder.setAdvertiseMode(mAdvertiseMode); //need?
                settingsBuilder.setTxPowerLevel(mAdvertiseTxPowerLevel);//need?
                settingsBuilder.setConnectable(false);

                mBluetoothLeAdvertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), getAdvertiseCallback());
                LogManager.d(TAG, "Started advertisement with callback: %s", getAdvertiseCallback());
            } catch (Exception e) {
                LogManager.e(e, TAG, "Cannot start advertising due to exception");
            }

        }

仍然不能工作,但我还不知道AltBeacon是否已经支持它,没有花更多的时间在它上面。

我现在使用这段代码,为了获得字节数组的正确格式,欢迎您的所有意见。如果它工作得很好,那就谈拉请求吧,因为我不知道将代码放在BeaconTransmitter中是否是实现这种extraData框架的最好方法。

再次感谢David,你和你的合作者正在使用Altbeacon做着非常棒的工作,所以如果我能在这个功能上提供帮助,它确实做到了。

票数 0
EN

Stack Overflow用户

发布于 2017-01-26 01:15:42

@Davidgyoung,promises I ^_^对不起,为了等待,我终于找到时间重新考虑传输TLM帧的问题。

这是传输TLM帧(不含AltBeacon)的完整代码,但您需要BeaconTransmitter来创建UID或URL Eddystone帧,以便检查它。

代码语言:javascript
复制
@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
  private void createEddyStone_TLM2() { 

    final int len = 12;
    final byte TLM_FRAME = 0x20;
    byte[] ServiceData = new byte[2 + len];

    ServiceData[0] = TLM_FRAME;
    ServiceData[1] = 0;
    ParcelUuid parcelUuid = parcelUuidFromShortUUID(0xFEAA);
    final int pos = 0;//4 TLM
    byte[] frameData = generateTLMFrameData();
    System.arraycopy(frameData, pos, ServiceData, 2, len);

    AdvertiseData advertiseData = new AdvertiseData.Builder().setIncludeDeviceName(false)
        .setIncludeTxPowerLevel(false)
        .addServiceData(parcelUuid, ServiceData)
        .addServiceUuid(parcelUuid)
        .build();

    AdvertiseSettings advertiseSettings = new AdvertiseSettings.Builder().setAdvertiseMode(1)
        .setTxPowerLevel(2)
        .setConnectable(false)
        .build();

    try {

      BluetoothManager bluetoothManager =
          (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
      if (bluetoothManager != null) {
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();

        BluetoothLeAdvertiser bleAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
        bleAdvertiser.stopAdvertising(getAdvertiseCallback());
        bleAdvertiser.startAdvertising(advertiseSettings, advertiseData, null,
            getAdvertiseCallback());
      }
    } catch (IllegalStateException e) {
      Log.e("", "error", e);
    }
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP) private AdvertiseCallback getAdvertiseCallback() {
    AdvertiseCallback advertiseCallback = new AdvertiseCallback() {
      @Override public void onStartFailure(int errorCode) {
        Log.e("","Something wrong with Advertising");
      }
      @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) {
        Log.i("","Advertising start succesfully");
      }
    };
    return advertiseCallback;
  }
  public static ParcelUuid parcelUuidFromShortUUID(long serviceId) {
    long leastSigBits = 0x800000805f9b34fbL;
    return new ParcelUuid(new UUID(0x1000 | (serviceId << 32),leastSigBits));
  }

  private byte[] generateTLMFrameData() {
    byte[] data = new byte[12];

    ByteBuffer buffer = ByteBuffer.wrap(data);
    buffer.putShort((short) getTLMBattery());
    int temperature = getTLMTemperature();
    buffer.putShort((short) (temperature << 8));
    buffer.putInt((int) getTLMPduCount());
    buffer.putInt((int) getTLMPowerOnTime() / 100);

    return data;
  }

  private int getTLMTemperature() {
    //todo make random, now 10º
    return 266;
  }

  private int getTLMBattery() {
    //todo make random
    return 1234;
  }

  private int getTLMPduCount() {
    //todo make random
    return 0;
  }

  private long getTLMPowerOnTime() {
    //todo - createtime, but don't care
    return SystemClock.elapsedRealtime();
  }

我在我的:app中这样做,如果你愿意,我可以在AltBeacon中添加这个。

向您致敬,阿尔贝托

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40239128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档