Return to Main Page
GeSHi © 2004, Nigel McNie.
  1. Imports System.Net.Sockets
  2. Imports System.Threading
  3. Imports System.Text.RegularExpressions
  4.  
  5. Public Class FrmMain
  6.  
  7. Private conn As Socket
  8. Private killed As Boolean
  9. Private nextReq As Integer = 1
  10. Private isQueryAggregate As Boolean
  11. Private tossim As Boolean
  12. Private temp_msg As String
  13.  
  14. Private Sub cmdConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdConnect.Click
  15. Dim regex As Regex
  16. regex = New Regex("(\d?\d?\d\.\d?\d?\d\.\d?\d?\d\.\d?\d?\d):(\d+)")
  17. If Not regex.IsMatch(txtIpAddr.Text) Then
  18. MsgBox("Please enter a valid connection address")
  19. Exit Sub
  20. End If
  21. conn = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
  22. Try
  23. conn.Connect(regex.Match(txtIpAddr.Text).Groups(1).Value, regex.Match(txtIpAddr.Text).Groups(2).Value)
  24. Dim data(1) As Byte
  25. data(0) = 84
  26. data(1) = 32
  27. conn.Send(data, 2, SocketFlags.None) 'Send Initialize SF stuff...
  28. conn.Receive(data, 2, SocketFlags.None) 'Receive Initialize SF stuff...
  29. Catch ex As Exception
  30. MsgBox("Error: " & ex.Message)
  31. Exit Sub
  32. End Try
  33. killed = False
  34. cmdConnect.Enabled = False
  35. cmdDisConnect.Enabled = True
  36. Me.TopMost = True
  37. listenFunc()
  38. End Sub
  39.  
  40. Private Sub cmdDisConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDisConnect.Click
  41. killed = True
  42. cmdConnect.Enabled = True
  43. cmdDisConnect.Enabled = False
  44. Me.TopMost = False
  45. End Sub
  46.  
  47. Private Sub listenFunc()
  48. Dim b(255) As Byte
  49. While Not killed
  50. Application.DoEvents()
  51. conn.ReceiveTimeout = 100
  52. Try
  53. Thread.BeginCriticalRegion()
  54. conn.Receive(b, 1, SocketFlags.None)
  55. Thread.EndCriticalRegion()
  56. Dim size As Integer
  57. size = conn.Receive(b, b(0), SocketFlags.None)
  58. If size >= 6 Then
  59. Dim req As reqPacket
  60. Dim resp As respPacket
  61. Dim data As dataPacket
  62. Dim payload(255) As Byte
  63. Dim i As Integer
  64. If tossim Then
  65. For i = 5 To size - 1
  66. payload(i - 5) = b(i)
  67. Next
  68. Else
  69. For i = 10 To size - 1
  70. payload(i - 10) = b(i)
  71. Next
  72. End If
  73. Thread.BeginCriticalRegion()
  74. updateRead(getText(b, size) & vbNewLine)
  75. If payload(0) = 1 Then
  76. req = New reqPacket
  77. req.loadFromBytes(payload, size - IIf(tossim, 6, 11))
  78. updateRead("Node " & req.sourceAddr & " broadcast request " & req.requestId & vbNewLine)
  79. ElseIf payload(0) = 2 Then
  80. resp = New respPacket
  81. resp.loadFromBytes(payload, size - IIf(tossim, 6, 11))
  82. updateRead("Node " & resp.destAddr & " receives response from Node " & resp.sourceAddr & " for request " & resp.requestId & vbNewLine)
  83. ElseIf payload(0) = 3 Then
  84. data = New dataPacket
  85. data.loadFromBytes(payload, size - IIf(tossim, 6, 11), tossim)
  86. updateRead("Node " & data.destAddr & " receives data from node " & data.sourceAddr & " for request " & data.requestId & vbNewLine)
  87. For i = 0 To (data.dataLength / 2) - 1
  88. updateRead(" Field" & i & ": " & (CInt(data.data(i * 2)) Or (CInt(data.data((i * 2) + 1)) << 8)) & vbNewLine)
  89. Next
  90. If data.requestId = nextReq - 1 Then 'This is data for the current request
  91. Dim curQuery As DataTable
  92. curQuery = grdResults.DataSource
  93. If data.destAddr = 0 And data.valid And (CInt(curQuery.TableName) And data.nodes) = 0 Then
  94. 'This data is also sent to us and valid for use
  95. If isQueryAggregate Then
  96. 'This query uses functions, so we need to apply the functions to this data plus what data we already have
  97. Dim row As DataRow
  98. row = curQuery.Rows(0)
  99. For i = 0 To (data.dataLength / 2) - 1
  100. Dim newData As Integer
  101. newData = (CInt(data.data(i * 2)) Or (CInt(data.data((i * 2) + 1)) << 8))
  102. If curQuery.Columns(i).Caption.ToLower.StartsWith("min") Then
  103. If curQuery.TableName = 0 Or newData < row(i) Then
  104. row(i) = newData
  105. End If
  106. ElseIf curQuery.Columns(i).Caption.ToLower.StartsWith("max") Then
  107. If curQuery.TableName = 0 Or newData > row(i) Then
  108. row(i) = newData
  109. End If
  110. ElseIf curQuery.Columns(i).Caption.ToLower.StartsWith("average") Then
  111. Dim oldNodes As Integer
  112. Dim newNodes As Integer
  113. oldNodes = countNodes(curQuery.TableName)
  114. newNodes = countNodes(data.nodes)
  115. row(i) = CInt(((row(i) * oldNodes) + (newData * newNodes)) / (oldNodes + newNodes))
  116. ElseIf curQuery.Columns(i).Caption.ToLower.StartsWith("sum") Then
  117. row(i) = row(i) + newData
  118. End If
  119. Next
  120. Else
  121. 'This is a full data request, so all data we get goes on its own row
  122. Dim row As DataRow
  123. row = curQuery.NewRow()
  124. For i = 0 To (data.dataLength / 2) - 1
  125. row(i) = (CInt(data.data(i * 2)) Or (CInt(data.data((i * 2) + 1)) << 8))
  126. Next
  127. curQuery.Rows.Add(row)
  128. End If
  129. End If
  130. curQuery.TableName = CInt(curQuery.TableName) Or data.nodes
  131. grdResults.DataSource = curQuery
  132. grdResults.Refresh()
  133. lblStatus.Text = "Responded: " & getAllNodes(Val(curQuery.TableName))
  134. End If
  135. Else
  136. i = 10 'something to break on
  137. End If
  138. updateRead(vbNewLine)
  139. End If
  140. Thread.EndCriticalRegion()
  141. Catch ex As Exception
  142. Thread.EndCriticalRegion()
  143. End Try
  144. End While
  145. conn.Close()
  146. End Sub
  147.  
  148. Private Sub updateRead(ByVal msg As String)
  149. temp_msg = temp_msg & msg
  150. If temp_msg.Contains(vbNewLine) Then
  151. txtRead.Text = txtRead.Text & temp_msg
  152. temp_msg = ""
  153. txtRead.SelectionStart = txtRead.Text.Length
  154. txtRead.ScrollToCaret()
  155. End If
  156. End Sub
  157.  
  158. Private Function isNodePresent(ByVal nodes, ByVal nodeId) As Boolean
  159. If (nodes And (1 << nodeId)) > 0 Then
  160. Return True
  161. End If
  162. Return False
  163. End Function
  164.  
  165. Private Function getAllNodes(ByVal nodes As Integer) As String
  166. Dim toRet As String
  167. toRet = ""
  168.  
  169. Dim i As Integer
  170. For i = 0 To 31
  171. If (nodes And (1 << i)) > 0 Then
  172. toRet = toRet & i & ", "
  173. End If
  174. Next
  175. If toRet = "" Then
  176. toRet = "-"
  177. Else
  178. toRet = toRet.Substring(0, toRet.Length - 2)
  179. End If
  180.  
  181. Return toRet
  182. End Function
  183.  
  184. Private Function countNodes(ByVal nodes As Integer) As Integer
  185. Dim i As Integer
  186. Dim toRet As Integer
  187. toRet = 0
  188.  
  189. For i = 0 To 31
  190. If (nodes And (1 << i)) > 0 Then toRet = toRet + 1
  191. Next
  192.  
  193. Return toRet
  194. End Function
  195.  
  196. Private Function getText(ByVal b() As Byte, ByVal size As Integer) As String
  197. Dim toRet As String
  198. toRet = ""
  199.  
  200. Dim i As Integer
  201. For i = 0 To size - 1
  202. toRet = toRet & "0x" & IIf(Hex(b(i)).Length = 1, "0", "") & Hex(b(i))
  203. If i < size - 1 Then toRet = toRet & " "
  204. Next
  205. toRet = toRet & vbNewLine
  206.  
  207. Return toRet
  208. End Function
  209.  
  210. Private Sub FrmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
  211. killed = True
  212. End Sub
  213.  
  214. Private Sub cmdSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSubmit.Click
  215. Dim regex As Regex
  216. regex = New Regex("(AND|OR)\s*$", RegexOptions.IgnoreCase)
  217. Dim curQuery As DataTable
  218. If regex.IsMatch(txtQuery.Text) Then
  219. curQuery = New DataTable
  220. curQuery.Columns.Add("Error")
  221. Dim row As DataRow
  222. row = curQuery.NewRow
  223. row(0) = "Error in query string, unable to parse SQL expression"
  224. curQuery.Rows.Add(row)
  225. row = curQuery.NewRow
  226. row(0) = "You can only have a SELECT, FROM, and WHERE clause"
  227. curQuery.Rows.Add(row)
  228. grdResults.DataSource = curQuery
  229. Exit Sub
  230. End If
  231. regex = New Regex("^SELECT\s+((((\w+)\()?(\w+)\)?)\s*,?\s+)+FROM(\s+)(\w+)(\s*)(\sWHERE(\s+)((\(\s*)*\s*(\w+)\s*(=|<|>|<=|>=|<>|!=)\s*(\w+)\s*(\)\s*)*\s*(\s+(AND|OR)\s+)?)+)?$", RegexOptions.IgnoreCase)
  232. If Not regex.IsMatch(txtQuery.Text) Then
  233. curQuery = New DataTable
  234. curQuery.Columns.Add("Error")
  235. Dim row As DataRow
  236. row = curQuery.NewRow
  237. row(0) = "Error in query string, unable to parse SQL expression"
  238. curQuery.Rows.Add(row)
  239. row = curQuery.NewRow
  240. row(0) = "You can only have a SELECT, FROM, and WHERE clause"
  241. curQuery.Rows.Add(row)
  242. grdResults.DataSource = curQuery
  243. Exit Sub
  244. End If
  245. Dim fields As CaptureCollection
  246. Dim conditions As CaptureCollection
  247.  
  248. fields = regex.Match(txtQuery.Text).Groups(2).Captures
  249. conditions = regex.Match(txtQuery.Text).Groups(11).Captures
  250.  
  251. curQuery = New DataTable
  252. curQuery.TableName = 0 'Use the table name to track what nodes this data is for... (Like partialNodes in TOS, I know, ugly hack)
  253. lblStatus.Text = "Responded: -"
  254. Dim i As Integer
  255. For i = 0 To fields.Count - 1
  256. curQuery.Columns.Add(fields(i).Value)
  257. Next
  258.  
  259. Dim myData(255) As Byte
  260. Dim length As Integer
  261. If optTossim.Checked Then
  262. 'Standard header for broadcast packet: node address 0 (0x00 0x00), channel 0x0F, group id 0x7D
  263. myData(0) = &H0
  264. myData(1) = &H0
  265. myData(2) = &H4
  266. myData(3) = &H7D
  267. length = 5
  268. Else
  269. myData(1) = &H1
  270. myData(2) = &H8 'FCF hi/lo config data for 802.15.4
  271. myData(3) = nextReq And &HFF 'Packet sequence number
  272. myData(4) = &HFF
  273. myData(5) = &HFF 'Broadcast destination address
  274. myData(6) = &HFF
  275. myData(7) = &HFF 'Broadcast source address (?)
  276. myData(8) = &H4 'Type (channel?)
  277. myData(9) = &H7D 'GroupId
  278. length = 10
  279. End If
  280.  
  281. myData(length) = &H1
  282. myData(length + 1) = &H0 'msgType = PKT_REQ
  283. myData(length + 2) = &H0
  284. myData(length + 3) = &H0 'sourceAddr = 0 (base station)
  285. myData(length + 4) = nextReq And &HFF
  286. myData(length + 5) = (nextReq >> 8) And &HFF 'RequestId
  287. myData(length + 6) = fields.Count * 2 'fieldLength
  288. Dim condLengthPos As Integer
  289. condLengthPos = length + 7
  290.  
  291. length = length + 8
  292.  
  293. Dim usesAggregate As Boolean
  294. Dim curFunc As String
  295. Dim curFuncId As Integer
  296. Dim nextOps(20) As Byte
  297. Dim nextOpsCount As Integer
  298. Dim field1 As String
  299. Dim field1Id As Integer
  300. Dim field2 As String
  301. Dim field2Id As Integer
  302. Dim immediate As Integer
  303.  
  304. usesAggregate = False
  305. For i = 0 To fields.Count - 1
  306. regex = New Regex("^(\w+)\((\w+)\)$")
  307. If regex.IsMatch(fields(i).Value) Then
  308. curFunc = regex.Match(fields(i).Value).Groups(1).Value
  309. field1 = regex.Match(fields(i).Value).Groups(2).Value
  310. Else
  311. curFunc = "all"
  312. field1 = fields(i).Value
  313. End If
  314. If curFunc <> "all" Then usesAggregate = True
  315. If curFunc = "all" And usesAggregate Then
  316. curQuery = New DataTable
  317. curQuery.Columns.Add("Error")
  318. Dim row As DataRow
  319. row = curQuery.NewRow
  320. row(0) = "Error in query, field """ & field1 & """ is not applied to an aggregate function. (You can not mix aggregate and non-aggregate data.)"
  321. curQuery.Rows.Add(row)
  322. grdResults.DataSource = curQuery
  323. Exit Sub
  324. End If
  325. curFuncId = getFuncId(curFunc)
  326. If curFuncId = -1 Then
  327. curQuery = New DataTable
  328. curQuery.Columns.Add("Error")
  329. Dim row As DataRow
  330. row = curQuery.NewRow
  331. row(0) = "Error: unknown function name """ & curFunc & """"
  332. curQuery.Rows.Add(row)
  333. grdResults.DataSource = curQuery
  334. Exit Sub
  335. End If
  336. field1Id = getFieldId(field1)
  337. If field1Id = -1 Then
  338. curQuery = New DataTable
  339. curQuery.Columns.Add("Error")
  340. Dim row As DataRow
  341. row = curQuery.NewRow
  342. row(0) = "Error: unknown field name """ & field1 & """"
  343. curQuery.Rows.Add(row)
  344. grdResults.DataSource = curQuery
  345. Exit Sub
  346. End If
  347. 'If we make it this far, then we have a valid function applied to a valid field
  348. myData(length) = field1Id
  349. myData(length + 1) = curFuncId
  350. length = length + 2
  351. Next
  352.  
  353. isQueryAggregate = usesAggregate
  354. If usesAggregate Then
  355. Dim row As DataRow
  356. row = curQuery.NewRow
  357. For i = 0 To fields.Count - 1
  358. row(i) = 0
  359. Next
  360. curQuery.Rows.Add(row)
  361. End If
  362.  
  363. For i = 0 To conditions.Count - 1
  364. Dim cond As String
  365. cond = Trim(conditions(i).Value)
  366. While cond.StartsWith("(")
  367. myData(length) = 26 'C_START (Start Conditional Group)
  368. length = length + 1
  369. cond = Trim(cond.Substring(1))
  370. End While
  371. nextOpsCount = 0
  372. If cond.EndsWith("AND") Then
  373. nextOps(nextOpsCount) = 28 'C_AND
  374. cond = Trim(cond.Replace("AND", ""))
  375. nextOpsCount = nextOpsCount + 1
  376. ElseIf cond.EndsWith("OR") Then
  377. nextOps(nextOpsCount) = 29 'C_OR
  378. cond = Trim(cond.Replace("OR", ""))
  379. nextOpsCount = nextOpsCount + 1
  380. End If
  381. While cond.EndsWith(")")
  382. nextOps(nextOpsCount) = 27 'C_STOP (Stop Conditional Group)
  383. nextOpsCount = nextOpsCount + 1
  384. cond = Trim(cond.Substring(0, cond.Length - 1))
  385. End While
  386. regex = New Regex("^(\w+)\s*(=|<|>|<=|>=|<>|!=)\s*(\w+)$")
  387. If Not regex.IsMatch(cond) Then
  388. curQuery = New DataTable
  389. curQuery.Columns.Add("Error")
  390. Dim row As DataRow
  391. row = curQuery.NewRow
  392. row(0) = "Error: invalid contional """ & cond & """"
  393. curQuery.Rows.Add(row)
  394. grdResults.DataSource = curQuery
  395. Exit Sub
  396. End If
  397. field1 = regex.Match(cond).Groups(1).Value
  398. curFunc = regex.Match(cond).Groups(2).Value
  399. field2 = regex.Match(cond).Groups(3).Value
  400. field1Id = getFieldId(field1)
  401. If field1Id = -1 Then
  402. curQuery = New DataTable
  403. curQuery.Columns.Add("Error")
  404. Dim row As DataRow
  405. row = curQuery.NewRow
  406. row(0) = "Error: expected field name in conditional, not """ & field1 & """"
  407. curQuery.Rows.Add(row)
  408. grdResults.DataSource = curQuery
  409. Exit Sub
  410. End If
  411. curFuncId = getCompId(curFunc)
  412. If curFuncId = -1 Then
  413. curQuery = New DataTable
  414. curQuery.Columns.Add("Error")
  415. Dim row As DataRow
  416. row = curQuery.NewRow
  417. row(0) = "Error: unknown comparison operator """ & curFunc & """"
  418. curQuery.Rows.Add(row)
  419. grdResults.DataSource = curQuery
  420. Exit Sub
  421. End If
  422. field2Id = getFieldId(field2)
  423. If field2Id = -1 Then
  424. If Not IsNumeric(field2) Then
  425. curQuery = New DataTable
  426. curQuery.Columns.Add("Error")
  427. Dim row As DataRow
  428. row = curQuery.NewRow
  429. row(0) = "Error: expected field name or immediate value, not """ & field2 & """"
  430. curQuery.Rows.Add(row)
  431. grdResults.DataSource = curQuery
  432. Exit Sub
  433. End If
  434. immediate = Val(field2)
  435. Else
  436. curFuncId = &H80 Or curFuncId 'This is a field vs. field comparison
  437. immediate = -1
  438. End If
  439. myData(length) = field1Id
  440. myData(length + 1) = curFuncId
  441. If immediate = -1 Then
  442. myData(length + 2) = field2Id
  443. myData(length + 3) = &H0
  444. Else
  445. myData(length + 2) = immediate And &HFF
  446. myData(length + 3) = (immediate >> 8) And &HFF
  447. End If
  448. length = length + 4
  449.  
  450. Dim j As Integer
  451. For j = nextOpsCount - 1 To 0 Step -1
  452. myData(length) = nextOps(j)
  453. length = length + 1
  454. Next j
  455. Next
  456.  
  457. If conditions.Count = 0 Then
  458. 'An empty conditional clause (START STOP)
  459. myData(length) = 26
  460. myData(length + 1) = 27
  461. length = length + 2
  462. End If
  463.  
  464. myData(condLengthPos) = length - (fields.Count * 2) - IIf(optTossim.Checked, 13, 18) 'condLength
  465. myData(length) = 0
  466. If optTossim.Checked Then
  467. myData(4) = length - 5
  468. Else
  469. myData(0) = length - 10
  470. End If
  471. Thread.BeginCriticalRegion()
  472. Try
  473. Dim len(0) As Byte
  474. len(0) = length
  475. 'Send out the packet three times, the same number of times as the nodes send packet reapeats
  476. conn.Send(len, 1, SocketFlags.None)
  477. conn.Send(myData, length, SocketFlags.None)
  478. Thread.Sleep(100)
  479. conn.Send(len, 1, SocketFlags.None)
  480. conn.Send(myData, length, SocketFlags.None)
  481. Thread.Sleep(100)
  482. conn.Send(len, 1, SocketFlags.None)
  483. conn.Send(myData, length, SocketFlags.None)
  484. grdResults.DataSource = curQuery
  485. nextReq = nextReq + 1 'Increment the requestId number
  486. Catch ex As Exception
  487. curQuery = New DataTable
  488. curQuery.Columns.Add("Error")
  489. Dim row As DataRow
  490. row = curQuery.NewRow
  491. row(0) = "Error: " & ex.Message
  492. curQuery.Rows.Add(row)
  493. grdResults.DataSource = curQuery
  494. End Try
  495. Thread.EndCriticalRegion()
  496. End Sub
  497.  
  498. Private Function getCompId(ByVal comp As String) As Integer
  499. comp = comp.ToLower
  500. If comp = "=" Then Return 20
  501. If comp = "<" Then Return 21
  502. If comp = ">" Then Return 22
  503. If comp = "<=" Then Return 23
  504. If comp = ">=" Then Return 24
  505. If comp = "<>" Or comp = "!=" Then Return 25
  506. Return -1
  507. End Function
  508.  
  509. Private Function getFuncId(ByVal func As String) As Integer
  510. func = func.ToLower
  511. If func = "min" Then Return 0
  512. If func = "max" Then Return 1
  513. If func = "average" Then Return 2
  514. If func = "sum" Then Return 3
  515. If func = "all" Then Return 4
  516. Return -1
  517. End Function
  518.  
  519. Private Function getFieldId(ByVal field As String) As Integer
  520. field = field.ToLower
  521. If field = "temp" Then Return 10
  522. If field = "light" Then Return 11
  523. If field = "accelx" Then Return 12
  524. If field = "accely" Then Return 13
  525. If field = "mic" Then Return 14
  526. If field = "voltage" Then Return 15
  527. If field = "nodeid" Then Return 16
  528. If field = "parentid" Then Return 17
  529. Return -1
  530. End Function
  531.  
  532. Private Sub optTossim_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optTossim.CheckedChanged, optTmote.CheckedChanged
  533. tossim = optTossim.Checked
  534. End Sub
  535. End Class
  536.  
  537. Public Class reqPacket
  538. Public msgType As Int32
  539. Public sourceAddr As Int32
  540. Public requestId As Int32
  541. Public fieldLength As Byte
  542. Public condLength As Byte
  543. Public field_cond(254) As Byte
  544.  
  545. 'Return value is success of load attempt
  546. Public Function loadFromBytes(ByRef b() As Byte, ByVal size As Integer) As Boolean
  547. Dim i As Integer
  548. If size < 8 Then Return False
  549. msgType = (CInt(b(1)) << 8) Or b(0)
  550. sourceAddr = (CInt(b(3)) << 8) Or b(2)
  551. requestId = (CInt(b(5)) << 8) Or b(4)
  552. fieldLength = b(6)
  553. condLength = b(7)
  554. If size < 8 + fieldLength + condLength Then Return False
  555. For i = 0 To fieldLength + condLength - 1
  556. field_cond(i) = b(i + 8)
  557. Next
  558. Return True
  559. End Function
  560.  
  561. 'Puts the packet structure into the byte array "b", returns size in bytes
  562. Public Function writeToBytes(ByRef b() As Byte) As Integer
  563. Dim i As Integer
  564. Array.Resize(b, 8 + fieldLength + condLength)
  565. b(0) = msgType And &HFF
  566. b(1) = (msgType >> 8) And &HFF
  567. b(2) = sourceAddr And &HFF
  568. b(3) = (sourceAddr >> 8) And &HFF
  569. b(4) = requestId And &HFF
  570. b(5) = (requestId >> 8) And &HFF
  571. b(6) = fieldLength
  572. b(7) = condLength
  573. For i = 0 To fieldLength + condLength - 1
  574. b(i + 8) = field_cond(i)
  575. Next
  576. Return 8 + fieldLength + condLength
  577. End Function
  578. End Class
  579.  
  580. Public Class respPacket
  581. Public msgType As Int32
  582. Public sourceAddr As Int32
  583. Public destAddr As Int32
  584. Public requestId As Int32
  585.  
  586. Public Function loadFromBytes(ByRef b() As Byte, ByVal size As Integer) As Boolean
  587. If size < 7 Then Return False
  588. msgType = (CInt(b(1)) << 8) Or b(0)
  589. sourceAddr = (CInt(b(3)) << 8) Or b(2)
  590. destAddr = (CInt(b(5)) << 8) Or b(4)
  591. requestId = (CInt(b(7)) << 8) Or b(6)
  592. Return True
  593. End Function
  594.  
  595. 'Puts the packet structure into the byte array "b", returns size in bytes
  596. Public Function writeToBytes(ByRef b() As Byte) As Integer
  597. Array.Resize(b, 8)
  598. b(0) = msgType And &HFF
  599. b(1) = (msgType >> 8) And &HFF
  600. b(2) = sourceAddr And &HFF
  601. b(3) = (sourceAddr >> 8) And &HFF
  602. b(4) = sourceAddr And &HFF
  603. b(5) = (sourceAddr >> 8) And &HFF
  604. b(6) = requestId And &HFF
  605. b(7) = (requestId >> 8) And &HFF
  606. Return 8
  607. End Function
  608. End Class
  609.  
  610. Public Class dataPacket
  611. Public msgType As Int32
  612. Public sourceAddr As Int32
  613. Public destAddr As Int32
  614. Public requestId As Int32
  615. Public valid As Byte
  616. Public nodes As Int64
  617. Public dataLength As Byte
  618. Public data(254) As Byte
  619.  
  620. 'Return value is success of load attempt
  621. Public Function loadFromBytes(ByRef b() As Byte, ByVal size As Integer, tossim as Boolean) As Boolean
  622. Dim i As Integer
  623. If size < 14 Then Return False
  624. msgType = (CInt(b(1)) << 8) Or b(0)
  625. sourceAddr = (CInt(b(3)) << 8) Or b(2)
  626. destAddr = (CInt(b(5)) << 8) Or b(4)
  627. requestId = (CInt(b(7)) << 8) Or b(6)
  628. valid = b(8)
  629. If tossim Then
  630. nodes = (CInt(b(15)) << 24) Or (CInt(b(14)) << 16) Or (CInt(b(13)) << 8) Or b(12)
  631. dataLength = b(16)
  632. If size < 16 + dataLength Then Return False
  633. Else
  634. nodes = (b(13) << 24) Or (b(12) << 16) Or (b(11) << 8) Or b(10)
  635. dataLength = b(14)
  636. If size < 14 + dataLength Then Return False
  637. End If
  638. For i = 0 To dataLength - 1
  639. data(i) = b(i + IIf(tossim, 17, 15))
  640. Next
  641. Return True
  642. End Function
  643.  
  644. 'Puts the packet structure into the byte array "b", returns size in bytes
  645. Public Function writeToBytes(ByRef b() As Byte) As Integer
  646. Dim i As Integer
  647. Array.Resize(b, 14 + dataLength)
  648. b(0) = msgType And &HFF
  649. b(1) = (msgType >> 8) And &HFF
  650. b(2) = sourceAddr And &HFF
  651. b(3) = (sourceAddr >> 8) And &HFF
  652. b(4) = destAddr And &HFF
  653. b(5) = (destAddr >> 8) And &HFF
  654. b(6) = requestId And &HFF
  655. b(7) = (requestId >> 8) And &HFF
  656. b(8) = valid
  657. b(12) = nodes And &HFF
  658. b(13) = (nodes >> 8) And &HFF
  659. b(14) = (nodes >> 16) And &HFF
  660. b(15) = (nodes >> 24) And &HFF
  661. b(16) = dataLength
  662. For i = 0 To dataLength - 1
  663. b(i + 17) = data(i)
  664. Next
  665. Return 16 + dataLength
  666. End Function
  667. End Class
Parsed in 0.168 seconds, using GeSHi 1.0.7.20