如何以Xamarin形式为BLE分割并发送大于20字节的数据? [英] How to split and send data >20 bytes for BLE in Xamarin forms?

查看:79
本文介绍了如何以Xamarin形式为BLE分割并发送大于20字节的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试以Xamarin形式实现 BLE .我要发送数据大于20个字节.我已经看到使用Java在原生android中的实现.如下图

I'm trying to implement BLE in Xamarin forms. I want to send data larger than 20 bytes. I have seen the implementations in the native android using java. It looks like below

private void sendMessage(BluetoothGattCharacteristic characteristic, String CHARACTERS){
        byte[] initial_packet = new byte[3];
        /**
         * Indicate byte
         */
        initial_packet[0] = BLE.INITIAL_MESSAGE_PACKET;
        if (Long.valueOf(
                String.valueOf(CHARACTERS.length() + initial_packet.length))
                > BLE.DEFAULT_BYTES_VIA_BLE) {
            sendingContinuePacket(characteristic, initial_packet, CHARACTERS);
        } else {
            sendingLastPacket(characteristic, initial_packet, CHARACTERS);
        }
    }

private void sendingContinuePacket(BluetoothGattCharacteristic characteristic,
            byte[] initial_packet, String CHARACTERS){
        /**
         * TODO If data length > Default data can sent via BLE : 20 bytes
         */
        // Check the data length is large how many times with Default Data (BLE)
        int times = Byte.valueOf(String.valueOf(
                CHARACTERS.length() / BLE.DEFAULT_BYTES_IN_CONTINUE_PACKET));

        Log.i(TAG, "CHARACTERS.length() " + CHARACTERS.length());
        Log.i(TAG, "times " + times);

        // TODO
        // 100 : Success
        // 101 : Error
        byte[] sending_continue_hex = new byte[BLE.DEFAULT_BYTES_IN_CONTINUE_PACKET];
        for (int time = 0; time <= times; time++) {
            /**
             * Wait second before sending continue packet 
             */
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (time == times) {
                Log.i(TAG, "LAST PACKET ");

                /**
                 * If you do not have enough characters to send continue packet,
                 * This is the last packet that will be sent to the band
                 */

                /**
                 * Packet length byte :
                 */
                /**
                 * Length of last packet
                 */
                int character_length = CHARACTERS.length()
                        - BLE.DEFAULT_BYTES_IN_CONTINUE_PACKET*times;

                initial_packet[1] = Byte.valueOf(String.valueOf(character_length
                        + BLE.INITIAL_MESSAGE_PACKET_LENGTH));
                initial_packet[2] = BLE.SENDING_LAST_PACKET;

                Log.i(TAG, "character_length " + character_length);

                /**
                 * Message
                 */
                // Hex file
                byte[] sending_last_hex = new byte[character_length];

                // Hex file : Get next bytes
                for (int i = 0; i < sending_last_hex.length; i++) {
                    sending_last_hex[i] = 
                            CHARACTERS.getBytes()[sending_continue_hex.length*time + i];
                }

                // Merge byte[]
                byte[] last_packet = 
                        new byte[character_length + BLE.INITIAL_MESSAGE_PACKET_LENGTH];
                System.arraycopy(initial_packet, 0, last_packet,
                        0, initial_packet.length);
                System.arraycopy(sending_last_hex, 0, last_packet, 
                        initial_packet.length, sending_last_hex.length);

                // Set value for characteristic
                characteristic.setValue(last_packet);
            } else {
                Log.i(TAG, "CONTINUE PACKET ");
                /**
                 * If you have enough characters to send continue packet,
                 * This is the continue packet that will be sent to the band
                 */
                /**
                 * Packet length byte
                 */
                int character_length = sending_continue_hex.length;

                /**
                 * TODO Default Length : 20 Bytes
                 */
                initial_packet[1] = Byte.valueOf(String.valueOf(
                        character_length + BLE.INITIAL_MESSAGE_PACKET_LENGTH));

                /**
                 * If sent data length > 20 bytes (Default : BLE allow send 20 bytes one time)
                 * -> set 01 : continue sending next packet
                 * else or if after sent until data length < 20 bytes
                 * -> set 00 : last packet
                 */
                initial_packet[2] = BLE.SENDING_CONTINUE_PACKET;
                /**
                 * Message
                 */
                // Hex file : Get first 17 bytes
                for (int i = 0; i < sending_continue_hex.length; i++) {
                    Log.i(TAG, "Send stt : " 
                            + (sending_continue_hex.length*time + i));

                    // Get next bytes
                    sending_continue_hex[i] = 
                            CHARACTERS.getBytes()[sending_continue_hex.length*time + i];
                }

                // Merge byte[]
                byte[] sending_continue_packet = 
                        new byte[character_length + BLE.INITIAL_MESSAGE_PACKET_LENGTH];
                System.arraycopy(initial_packet, 0, sending_continue_packet, 
                        0, initial_packet.length);
                System.arraycopy(sending_continue_hex, 0, sending_continue_packet, 
                        initial_packet.length, sending_continue_hex.length);

                // Set value for characteristic
                characteristic.setValue(sending_continue_packet);
            }

            // Write characteristic via BLE
            mBluetoothGatt.writeCharacteristic(characteristic);
        }
    }

public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic,
            String data) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return false;
        }

        if (ActivityBLEController.IS_FIRST_TIME) {
            /**
             * In the first time, 
             * should send the Title
             */
            byte[] merge_title = sendTitle(data);

            // Set value for characteristic
            characteristic.setValue(merge_title);

            // Write characteristic via BLE
            mBluetoothGatt.writeCharacteristic(characteristic);

            // Reset
            ActivityBLEController.IS_FIRST_TIME = false;

            return true;
        } else {
            /**
             * In the second time, 
             * should send the Message
             */
            if (data.length() <= BLE.LIMIT_CHARACTERS) {
                sendMessage(characteristic, data);

                // Reset
                ActivityBLEController.IS_FIRST_TIME = true; 

                return true;
            } else {
                // Typed character
                typed_character = data.length();

                return false;
            }
        }
    }

这是我的 Xamarin代码,我在其中进行写操作

This is my Xamarin code where I do write operation

 private async Task<string> ReadAndWriteCharacterisicsValue(ICharacteristic _characteristics)
        {
            if (_characteristics != null)
            {
                var sbnew = new StringBuilder("BLE Characteristics\n");
                byte[] senddata = Encoding.UTF8.GetBytes(string.IsNullOrEmpty("") ? "Hi1290004847846767627723676" : "");

                if (MainThread.IsMainThread)
                {
                    string writeTypes = _characteristics.WriteType.ToString();
                    await _characteristics.WriteAsync(senddata);

                }

                //_characteristics.ReadAsync();


                var charVal = _characteristics.Value;

                var str = Encoding.UTF8.GetString(charVal);
                sbnew.AppendLine($"Characteristics found on this device: {string.Join(", ", str.ToString())}");

                return sbnew.ToString();


            }
            return null;
        }

当我尝试发送字符串 Hi1290004847846767627723676(27字节)时,我在外围设备中收到了 Hi129000484784676762(20字节)而没有崩溃.我正在使用 plugin.ble 最新版本,并且我的蓝牙设备版本是 5.0 .我什至尝试请求Mtu .如您在以下代码中看到的

When I try to send String Hi1290004847846767627723676(27 Bytes) but I get Hi129000484784676762(20 Bytes) in peripheral without crashing. I'm using plugin.ble latest version and also my bluetooth device version is 5.0. I even tried requesting Mtu. As you can see in the following code

 if (_characteristics != null)
            {
                try
                {

                    var sbnew = new StringBuilder("BLE Characteristics\n");
                     byte[] senddata = Encoding.UTF8.GetBytes(string.IsNullOrEmpty("") ? "Start{'command':'UnSelectEnhancement','data':[{'UnSelectEnhancement':'VitaminC'},{'UnSelectEnhancement':'CitricAcid'},  {'UnSelectEnhancement':'Electolytes'},{'UnSelectEnhancement':'Sweetener'}]}End":"");
                   
                    await _device.RequestMtuAsync(2000);
                  

                    
                    if (MainThread.IsMainThread)
                    {
                        string writeTypes = _characteristics.WriteType.ToString();
                         await _characteristics.WriteAsync(senddata);

                    }

我要发送的数据最大为 200字节.我还尝试使用此代码分割字符串.

I want to send data maximum of 200 bytes. I also tried splitting string using this code.

IEnumerable<string> s = str.Split();
                    IEnumerable<string> Split( )
                    {
                        while (!string.IsNullOrWhiteSpace(str))
                        {
                            var chunk = str.Take(size).ToArray();
                           str = str.Substring(chunk.Length);
                           yield return new string(chunk);

                       }

                    }

                    
                    Console.WriteLine("Error of split");
                    
                    Console.WriteLine(String.Join(Environment.NewLine, str));
                    Console.WriteLine(String.Join(Environment.NewLine, str));

但是它没有用,对我来说看起来很复杂.是否有任何简便的方法使用Xamarin形式的c#对大于 20字节的数据进行写操作?

But it didn't work.It looks quite complicated for me. Is there any easy way to do the write operation for data larger than 20 bytes using c# in xamarin forms?

推荐答案

您可以尝试以多个块发送数据,每个块的最大大小为20.此示例发送第一个20字节的块,然后发送剩下的7字节的另一个块.

You can try and send the data in multiple chunks each having a maximum size of 20. This example sends the first chunk of 20 bytes, then another one with the remaining 7.

            byte[] senddata = Encoding.ASCII.GetBytes("Hi1290004847846767627723676");
            int start = 0;
            while (start < senddata.Length)
            {
                int chunkLength = Math.Min(20, senddata.Length - start);
                byte[] chunk = new byte[chunkLength];
                Array.Copy(senddata, start, chunk, 0, chunkLength);
                await writeBuf.WriteAsync(chunk);
                start += 20;
            }

  • 已删除为副本&的评论粘贴

这篇关于如何以Xamarin形式为BLE分割并发送大于20字节的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆