Generic functions

<syntaxhighlight lang="lua"> -- General modules require("Core")

-- Third-party libraries -- https://github.com/silentbicycle/lua-memcached local client = require("memcached") local cache = client.connect()

function getCountryCode(number)

  1. -- Number should have not less than 3 digits
  2. if number >= 100
  3. then
  4. local value = tostring(number)
  5. return string.sub(value, 1, 3)
  6. end
  7. return nil

end

function getCountryAndRegionCode(number)

  1. -- Number should have not less than 4 digits
  2. if number >= 1000
  3. then
  4. local value = tostring(number)
  5. return string.sub(value, 1, 4)
  6. end
  7. return nil

end

function validateGeographicRegionCode(number, code)

  1. local value1 = tostring(code)
  2. local value2 = tostring(number)
  3. local length1 = string.len(value1)
  4. local length2 = string.len(value2)
  5. return
  6. (length1 <= length2) and
  7. (value1 == string.sub(value2, 1, length1))

end

function validateRegularRepeater(parameters)

  1. return
  2. -- Link has a repeater kind
  3. (parameters.kind == LINK_TYPE_REPEATER) and
  4. -- It is not DV4mini
  5. (parameters.name ~= "DG1HT DV4mini") and
  6. -- And not Homebrew Repeater in DMO mode
  7. ((parameters.name ~= "Homebrew Repeater") or
  8. (parameters.values[VALUE_HOMEBREW_CONNECTION_MODE] ~= CONNECTION_MODE_HOTSPOT))

end </syntaxhighlight>

Global TalkGroup routing

This function is used to route calls to other BrandMeisters <syntaxhighlight lang="lua"> function makeGlobalRouteForGroup(kind, destination)

  1. if
  2. (destination ~= 9) and
  3. (kind ~= LINK_TYPE_NETWORK) and
  4. (validateGeographicRegionCode(destination, "8") or
  5. validateGeographicRegionCode(destination, "9") or
  6. getCountryCode(destination))
  7. then
  8. local contexts = getContextTable()
  9. for _, parameters in pairs(contexts) do
  10. if parameters.name == "FastForward"
  11. then
  12. newRoute(parameters.object, 0, 0)
  13. end
  14. end
  15. end

end </syntaxhighlight>

National TalkGroup routing

<syntaxhighlight lang="lua"> function makeAutomaticRouteForNationalGroup(kind, number, destination, slot)

  1. if destination >= 100
  2. then
  3. local country = getCountryCode(destination)
  4. local contexts = getContextTable()
  5. for _, parameters in pairs(contexts) do
  6. if
  7. -- Do not route call back
  8. ((kind ~= parameters.kind) or
  9. (number ~= parameters.number)) and
  10. -- Remote should be a repeater
  11. validateRegularRepeater(parameters) and
  12. -- Remote ID length is great than country code
  13. (parameters.number >= 100) and
  14. -- Destination ID and Remote ID should have same country code as prefix
  15. (getCountryCode(parameters.number) == country)
  16. then
  17. newRoute(parameters.object, slot, 0)
  18. end
  19. end
  20. end

end </syntaxhighlight>

Regional TalkGroup routing

<syntaxhighlight lang="lua"> function makeAutomaticRouteForRegionalGroup(kind, number, destination, slot)

  1. if destination >= 1000
  2. then
  3. local region = getCountryAndRegionCode(destination)
  4. local contexts = getContextTable()
  5. for _, parameters in pairs(contexts) do
  6. if
  7. -- Do not route call back
  8. ((kind ~= parameters.kind) or
  9. (number ~= parameters.number)) and
  10. -- Remote should be a repeater
  11. validateRegularRepeater(parameters) and
  12. -- Remote ID length is great than region code
  13. (parameters.number >= 1000) and
  14. -- Destination ID and Remote ID should have same region code as prefix
  15. (getCountryAndRegionCode(parameters.number) == region)
  16. then
  17. newRoute(parameters.object, slot, 0)
  18. end
  19. end
  20. end

end </syntaxhighlight>

OnDemand/Dynamic TalkGroup routing

A OnDemand TalkGroup is connected by pressing the PTT in the future also possable via RRS <syntaxhighlight lang="lua"> function makeOnDemandRouteForGroup(kind, number, slot, destination, interval)

  1. -- Keep Group 9 as local
  2. if destination ~= 9
  3. then
  4. -- Subscribe repeater to group
  5. if kind == LINK_TYPE_REPEATER
  6. then
  7. cache:set(number .. "-" .. destination, tostring(slot), interval)
  8. end
  9. -- Route to subscribed group
  10. local contexts = getContextTable()
  11. for _, parameters in pairs(contexts) do
  12. if
  13. -- Do not route call back
  14. ((kind ~= parameters.kind) or
  15. (number ~= parameters.number)) and
  16. -- Remote should be a repeater
  17. (parameters.kind == LINK_TYPE_REPEATER)
  18. then
  19. local slot = cache:get(parameters.number .. "-" .. destination)
  20. if
  21. -- Subscription should be available
  22. (slot ~= nil)
  23. then
  24. newRoute(parameters.object, tonumber(slot), 0)
  25. end
  26. end
  27. end
  28. end

end </syntaxhighlight>

Dongle Reflector/TalkGroup routing

The function is used for mapping reflectors to TalkGroups <syntaxhighlight lang="lua"> local state = 0;

function makeRouteForDV4mini(kind, name, number, destination, map)

  1. -- 1) Forward new Group calls to LoopBack
  2. if name ~= "LoopBack"
  3. then
  4. for reflector, group in pairs(map) do
  5. if destination == group
  6. then
  7. state = reflector
  8. newRoute(LINK_TYPE_APPLICATION, LOOPBACK, 0, 9)
  9. return REGISTRY_CONTINUE_APPENDING
  10. end
  11. end
  12. end
  13. -- 2) Forward calls from LoopBack to DV4mini connected to reflector
  14. if (destination == 9) and
  15. (name == "LoopBack")
  16. then
  17. local contexts = getContextTable()
  18. for _, parameters in pairs(contexts) do
  19. if (parameters.name == "DG1HT DV4mini") and
  20. (parameters.values[VALUE_REFLECTOR] == state)
  21. then
  22. newRoute(parameters.object, 0, 0)
  23. end
  24. end
  25. return REGISTRY_STOP_APPENDING
  26. end
  27. -- 3) Forward DV4mini calls of reflector to LoopBack
  28. if (destination == 9) and
  29. (name == "DG1HT DV4mini")
  30. then
  31. -- 3.1) Get current reflector of DV4mini
  32. local reflector = nil
  33. local contexts = getContextTable()
  34. for _, parameters in pairs(contexts) do
  35. if (parameters.number == number) and
  36. (parameters.name == "DG1HT DV4mini")
  37. then
  38. reflector = parameters.values[VALUE_REFLECTOR];
  39. break
  40. end
  41. end
  42. -- 3.2) Get group number from map
  43. local group = map[reflector]
  44. if group == nil
  45. then
  46. -- Group was not found, should be processed by TorsenHelper
  47. report("Mapped group not found for reflector DCS" .. reflector)
  48. return REGISTRY_CONTINUE_APPENDING
  49. end
  50. -- 3.3) Route call to other DVmini
  51. for _, parameters in pairs(contexts) do
  52. if (parameters.number ~= number) and
  53. (parameters.name == "DG1HT DV4mini") and
  54. (parameters.values[VALUE_REFLECTOR] == reflector)
  55. then
  56. newRoute(parameters.object, 0, 0)
  57. end
  58. end
  59. -- 3.4) Route call to LoopBack
  60. newRoute(LINK_TYPE_APPLICATION, LOOPBACK, 0, group)
  61. -- 3.5) Publish user event with reference to the reflector
  62. report("Processing call for mapped reflector DCS" .. reflector)
  63. publishEvent("reflector = " .. reflector)
  64. return REGISTRY_STOP_APPENDING
  65. end
  66. return REGISTRY_CONTINUE_APPENDING

end </syntaxhighlight>

Generic functions[edit]

<syntaxhighlight lang="lua"> -- General modules require("Core")

-- Third-party libraries -- https://github.com/silentbicycle/lua-memcached local client = require("memcached") local cache = client.connect()

function getCountryCode(number)

  1. -- Number should have not less than 3 digits
  2. if number >= 100
  3. then
  4. local value = tostring(number)
  5. return string.sub(value, 1, 3)
  6. end
  7. return nil

end

function getCountryAndRegionCode(number)

  1. -- Number should have not less than 4 digits
  2. if number >= 1000
  3. then
  4. local value = tostring(number)
  5. return string.sub(value, 1, 4)
  6. end
  7. return nil

end

function validateGeographicRegionCode(number, code)

  1. local value1 = tostring(code)
  2. local value2 = tostring(number)
  3. local length1 = string.len(value1)
  4. local length2 = string.len(value2)
  5. return
  6. (length1 <= length2) and
  7. (value1 == string.sub(value2, 1, length1))

end

function validateRegularRepeater(parameters)

  1. return
  2. -- Link has a repeater kind
  3. (parameters.kind == LINK_TYPE_REPEATER) and
  4. -- It is not DV4mini
  5. (parameters.name ~= "DG1HT DV4mini") and
  6. -- And not Homebrew Repeater in DMO mode
  7. ((parameters.name ~= "Homebrew Repeater") or
  8. (parameters.values[VALUE_HOMEBREW_CONNECTION_MODE] ~= CONNECTION_MODE_HOTSPOT))

end </syntaxhighlight>

Global TalkGroup routing[edit]

This function is used to route calls to other BrandMeisters <syntaxhighlight lang="lua"> function makeGlobalRouteForGroup(kind, destination)

  1. if
  2. (destination ~= 9) and
  3. (kind ~= LINK_TYPE_NETWORK) and
  4. (validateGeographicRegionCode(destination, "8") or
  5. validateGeographicRegionCode(destination, "9") or
  6. getCountryCode(destination))
  7. then
  8. local contexts = getContextTable()
  9. for _, parameters in pairs(contexts) do
  10. if parameters.name == "FastForward"
  11. then
  12. newRoute(parameters.object, 0, 0)
  13. end
  14. end
  15. end

end </syntaxhighlight>

National TalkGroup routing[edit]

<syntaxhighlight lang="lua"> function makeAutomaticRouteForNationalGroup(kind, number, destination, slot)

  1. if destination >= 100
  2. then
  3. local country = getCountryCode(destination)
  4. local contexts = getContextTable()
  5. for _, parameters in pairs(contexts) do
  6. if
  7. -- Do not route call back
  8. ((kind ~= parameters.kind) or
  9. (number ~= parameters.number)) and
  10. -- Remote should be a repeater
  11. validateRegularRepeater(parameters) and
  12. -- Remote ID length is great than country code
  13. (parameters.number >= 100) and
  14. -- Destination ID and Remote ID should have same country code as prefix
  15. (getCountryCode(parameters.number) == country)
  16. then
  17. newRoute(parameters.object, slot, 0)
  18. end
  19. end
  20. end

end </syntaxhighlight>

Regional TalkGroup routing[edit]

<syntaxhighlight lang="lua"> function makeAutomaticRouteForRegionalGroup(kind, number, destination, slot)

  1. if destination >= 1000
  2. then
  3. local region = getCountryAndRegionCode(destination)
  4. local contexts = getContextTable()
  5. for _, parameters in pairs(contexts) do
  6. if
  7. -- Do not route call back
  8. ((kind ~= parameters.kind) or
  9. (number ~= parameters.number)) and
  10. -- Remote should be a repeater
  11. validateRegularRepeater(parameters) and
  12. -- Remote ID length is great than region code
  13. (parameters.number >= 1000) and
  14. -- Destination ID and Remote ID should have same region code as prefix
  15. (getCountryAndRegionCode(parameters.number) == region)
  16. then
  17. newRoute(parameters.object, slot, 0)
  18. end
  19. end
  20. end

end </syntaxhighlight>

OnDemand/Dynamic TalkGroup routing[edit]

A OnDemand TalkGroup is connected by pressing the PTT in the future also possable via RRS <syntaxhighlight lang="lua"> function makeOnDemandRouteForGroup(kind, number, slot, destination, interval)

  1. -- Keep Group 9 as local
  2. if destination ~= 9
  3. then
  4. -- Subscribe repeater to group
  5. if kind == LINK_TYPE_REPEATER
  6. then
  7. cache:set(number .. "-" .. destination, tostring(slot), interval)
  8. end
  9. -- Route to subscribed group
  10. local contexts = getContextTable()
  11. for _, parameters in pairs(contexts) do
  12. if
  13. -- Do not route call back
  14. ((kind ~= parameters.kind) or
  15. (number ~= parameters.number)) and
  16. -- Remote should be a repeater
  17. (parameters.kind == LINK_TYPE_REPEATER)
  18. then
  19. local slot = cache:get(parameters.number .. "-" .. destination)
  20. if
  21. -- Subscription should be available
  22. (slot ~= nil)
  23. then
  24. newRoute(parameters.object, tonumber(slot), 0)
  25. end
  26. end
  27. end
  28. end

end </syntaxhighlight>

Dongle Reflector/TalkGroup routing[edit]

The function is used for mapping reflectors to TalkGroups <syntaxhighlight lang="lua"> local state = 0;

function makeRouteForDV4mini(kind, name, number, destination, map)

  1. -- 1) Forward new Group calls to LoopBack
  2. if name ~= "LoopBack"
  3. then
  4. for reflector, group in pairs(map) do
  5. if destination == group
  6. then
  7. state = reflector
  8. newRoute(LINK_TYPE_APPLICATION, LOOPBACK, 0, 9)
  9. return REGISTRY_CONTINUE_APPENDING
  10. end
  11. end
  12. end
  13. -- 2) Forward calls from LoopBack to DV4mini connected to reflector
  14. if (destination == 9) and
  15. (name == "LoopBack")
  16. then
  17. local contexts = getContextTable()
  18. for _, parameters in pairs(contexts) do
  19. if (parameters.name == "DG1HT DV4mini") and
  20. (parameters.values[VALUE_REFLECTOR] == state)
  21. then
  22. newRoute(parameters.object, 0, 0)
  23. end
  24. end
  25. return REGISTRY_STOP_APPENDING
  26. end
  27. -- 3) Forward DV4mini calls of reflector to LoopBack
  28. if (destination == 9) and
  29. (name == "DG1HT DV4mini")
  30. then
  31. -- 3.1) Get current reflector of DV4mini
  32. local reflector = nil
  33. local contexts = getContextTable()
  34. for _, parameters in pairs(contexts) do
  35. if (parameters.number == number) and
  36. (parameters.name == "DG1HT DV4mini")
  37. then
  38. reflector = parameters.values[VALUE_REFLECTOR];
  39. break
  40. end
  41. end
  42. -- 3.2) Get group number from map
  43. local group = map[reflector]
  44. if group == nil
  45. then
  46. -- Group was not found, should be processed by TorsenHelper
  47. report("Mapped group not found for reflector DCS" .. reflector)
  48. return REGISTRY_CONTINUE_APPENDING
  49. end
  50. -- 3.3) Route call to other DVmini
  51. for _, parameters in pairs(contexts) do
  52. if (parameters.number ~= number) and
  53. (parameters.name == "DG1HT DV4mini") and
  54. (parameters.values[VALUE_REFLECTOR] == reflector)
  55. then
  56. newRoute(parameters.object, 0, 0)
  57. end
  58. end
  59. -- 3.4) Route call to LoopBack
  60. newRoute(LINK_TYPE_APPLICATION, LOOPBACK, 0, group)
  61. -- 3.5) Publish user event with reference to the reflector
  62. report("Processing call for mapped reflector DCS" .. reflector)
  63. publishEvent("reflector = " .. reflector)
  64. return REGISTRY_STOP_APPENDING
  65. end
  66. return REGISTRY_CONTINUE_APPENDING

end </syntaxhighlight>