Detect Row and parse MAC from DesktopTextArea

I have an ARM 64 desktop app that scans for BLE devices and returns them to a DesktopTextArea. Here is a sample of what is returned

[INFO] BLE scan started.
[INFO] Found: |5C:E5:C5:51:47:3F| [UNKNOWN]
[INFO] Found: |D8:3A:DD:57:55:64| RVECC-P1
[INFO] Found: |55:3A:41:10:41:06| [UNKNOWN]
[INFO] Found: |73:DD:DC:F1:71:24| [UNKNOWN]
[INFO] Found: |51:37:93:B1:2B:50| [UNKNOWN]
[INFO] Found: |45:09:61:9F:ED:6E| [UNKNOWN]
[INFO] Found: |7E:A4:05:B3:4E:0B| [UNKNOWN]
[INFO] Found: |60:38:0E:F5:E1:9F| SCG-CF-W8

I am looking to detect the row clicked and parse out the MAC ADDRESS. While I can split using RETURN and then Split using | OR REPLACEALL(" [INFO] Found: |", β€œβ€), then SPLIT β€œ|” but it starts getting messy but can make it work.

The important aspects I am looking for is the MAC and BLE NAMED DEVICE. In the above example return UNKNOWN

Is there a cleaner way to get the data the user clicked in MouseUp EVENT by the row clicked and then parse out MAC and DEVICE NAME?

You’re almost there.

dim lines() as string

rawData=ReplaceLineEndings(rawData, EndOfLine)

lines=rawData.Split(EndOfLine)

dim currentLineItems() as string
dim currentMACAddress as string
dim currentDeviceName as string

for each currentLine as string in lines
    currentLine=Replace(currentLine, "[INFO] Found: |", "")
    currentLine=Replace(currentLine, "| ", Chr(9))

    currentLineItems=currentLine.Split(Chr(9))

    'The array will contain the items in this order
    'Extract them and then do something with them
    currentMACAddress=currentLineItems(0)
    currentDeviceName=currentLIneItems(1)
next

This could also be done with RegEx but since you have already gotten most of the way there with Replace, I thought I’d stick with that.

Dim rx as new regex
Rx.searchpattern = "\|([0-9A-F:]+)\|"
Dim rm as regexmatch = rx.search(line)
Dim macaddress as string
If rm<>nil then
  Macaddress=rm.SubExpressionString(1)
End if
3 Likes

He needs the device name as well:

Dim rx as new regex
Rx.searchpattern = "\|([0-9A-F:]+)\| (.+)$"
Dim rm as regexmatch = rx.search(line)
Dim macaddress as string
If rm<>nil then
  Macaddress=rm.SubExpressionString(1)
  DeviceName=rm.SubExpressionString(2)
End if
1 Like

In which case the pattern should be:

"\|([0-9A-F:]+)\|\s+\[([^]]+)\]"

That is

  1. A pipe
  2. A string of one or more 0-9, A-F or :
  3. A pipe
  4. One or more spaces
  5. A left bracket
  6. One or more characters that are not a right bracket
  7. A right bracket.

Not all of the names are in brackets - if he wants to catch those, the more relaxed pattern I suggested will work better.

Regarding the clicked row. You could read the data, replace all lineendings with the UNIX lineending. Then split the data by EndOfLine.UNIX and present it in a Listbox. Then do the RegEx detection of the MAC Address and Device Name in the clicked row.

For the RegEx-Expression, i recommend (?Umi-s)\|([0-9A-F:]+)\|\s+\[?(.+)\]?\R
This one would also allow Device-Names starting with a Whitespace.
Please note that a line break must follow the last data line, otherwise the last data line will not be fully evaluated.

In the MouseUp Event of the TextArea you can get the content of the clicked row like this:

Var LineSelected As Integer = Me.LineNumber( Me.CharacterPosition( x, y ) )
Var Lines() As String = Me.Text.Split( "#" )
Var LineContent As String = Lines(LineSelected).Trim

(I used β€œ#” as a splitter, because splitting by simple lineendings did not work. So i added a # after each line, within the TextArea.)

1 Like

Instead of using a text area, could you instead output the lines to a list box?

Just normalize the line endings with ReplaceLineEndings and then split on EndOfLine.

That seems like it would make your life a lot easier in this case, unless that text area is serving other purposes as well and you’re just trying to add a unique feature to it.

That is a good solution if the system uses a mouse/keyboard. I have implemented such a solution on other efforts.

In this instance I will be using a 7" touch screen. The ability provided in

Rx.searchpattern = β€œ|([0-9A-F:]+)| (.+)$”

to strip out the MAC from the BLE SCAN to enable BLE CONNECT is very useful in the final touch screen implementation.

@Greg_O and @Eric_Williams

This is the solution I have implemented which works while debugging with the RX portion to be used inline with BLE SCAN on final solution.

Var rawData As string
Var LineSelected As Integer = Me.LineNumber( Me.CharacterPosition( x, y ) )
Var Lines() As String = Me.Text.Split( EndOfLine)

If Not Lines.Count > 0 Then Return // Problem - POST ERROR

Var LineContent As String = Lines(LineSelected).Trim
Var rx As New regex
Var rm As regexmatch
Var Macaddress, DeviceName As String

rawData = ReplaceLineEndings(rawData, EndOfLine)

lines = rawData.Split(EndOfLine)

Rx.searchpattern = "\|([0-9A-F:]+)\| (.+)$"
rm  = rx.search(LineContent)
If rm<>nil then
  Macaddress = rm.SubExpressionString(1)
  DeviceName = rm.SubExpressionString(2)
End if

I really need to understand how the two of you know how to format Rx.searchpattern

What both of you wrote resembles search patterns in CLID-ANI in TELCO industry for CALL PATTERNS. In those patterns [ ] indicates inlcude but in this it appears to be data when [ or ] is present. So the inclusion of first term and second term used in the search pattern syntax you wrote is different and is appears this β€œ\|” is used to start a search term. If that is correct the rest of the formatting is less than 100% to me. What resource do you use to format search patterns?

Thank you to both for what is ultimately the final solution.

@Sascha_S while I have not come across this using bluetoothctl in ARM 64 I think this is significant as a user may add a whitespace and not know it or on purpose. For the use I need I am creating the BLE LOCAL NAME and will only be looking for that. So when I move to looking at all BLE LOCAL NAMES in other efforts this will be a handy resource. Thank you

1 Like