neighbourstream.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. "use strict"
  2. define([ "bacon"
  3. , "lib/helper"
  4. , "lib/streams"
  5. ], function(Bacon, Helper, Streams) {
  6. return function (mgmtBus, nodesBus, ip) {
  7. function nodeQuerier() {
  8. var asked = {}
  9. var timeout = 6000
  10. return function (ifname) {
  11. var now = new Date().getTime()
  12. if (ifname in asked && now - asked[ifname] < timeout)
  13. return Bacon.never()
  14. asked[ifname] = now
  15. return Streams.nodeInfo(ip, ifname).map(function (d) {
  16. return { "ifname": ifname
  17. , "nodeInfo": d
  18. }
  19. })
  20. }
  21. }
  22. var querierAsk = new Bacon.Bus()
  23. var querier = querierAsk.flatMap(nodeQuerier())
  24. querier.map(".nodeInfo").onValue(mgmtBus, "pushEvent", "nodeinfo")
  25. function wrapIfname(ifname, d) {
  26. return [ifname, d]
  27. }
  28. function extractIfname(d) {
  29. var r = {}
  30. for (var station in d) {
  31. var ifname = d[station].ifname
  32. delete d[station].ifname
  33. if (!(ifname in r))
  34. r[ifname] = {}
  35. r[ifname][station] = d[station]
  36. }
  37. return r
  38. }
  39. function stationsStream(ifname) {
  40. return new Streams.Stations(ip, ifname).map(wrapIfname, ifname)
  41. }
  42. function magic(interfaces) {
  43. var ifnames = Object.keys(interfaces)
  44. ifnames.forEach(querierAsk.push)
  45. var wifiStream = Bacon.fromArray(ifnames)
  46. .flatMap(stationsStream)
  47. .scan({}, function (a, b) {
  48. a[b[0]] = b[1]
  49. return a
  50. })
  51. var batadvStream = new Streams.Batadv(ip).toProperty({})
  52. return Bacon.combineWith(combine, wifiStream
  53. , batadvStream.map(extractIfname)
  54. , nodesBus.map(".macs")
  55. )
  56. }
  57. function combine(wifi, batadv, macs) {
  58. var interfaces = combineWithIfnames(wifi, batadv)
  59. for (var ifname in interfaces) {
  60. var stations = interfaces[ifname]
  61. for (var station in stations) {
  62. stations[station].id = station
  63. if (station in macs)
  64. stations[station].nodeInfo = macs[station]
  65. else
  66. querierAsk.push(ifname)
  67. }
  68. }
  69. return interfaces
  70. }
  71. function combineWithIfnames(wifi, batadv) {
  72. var ifnames = Object.keys(wifi).concat(Object.keys(batadv))
  73. // remove duplicates
  74. ifnames.filter(function(e, i) {
  75. return ifnames.indexOf(e) === i
  76. })
  77. var out = {}
  78. ifnames.forEach(function (ifname) {
  79. out[ifname] = combineWifiBatadv(wifi[ifname], batadv[ifname])
  80. })
  81. return out
  82. }
  83. function combineWifiBatadv(wifi, batadv) {
  84. var station
  85. var out = {}
  86. for (station in batadv) {
  87. if (!(station in out))
  88. out[station] = {}
  89. out[station].batadv = batadv[station]
  90. }
  91. for (station in wifi) {
  92. if (!(station in out))
  93. out[station] = {}
  94. out[station].wifi = wifi[station]
  95. }
  96. return out
  97. }
  98. return Helper.request(ip, "interfaces").flatMap(magic)
  99. }
  100. })