( settings *ttnpb.MACState_UplinkMessage_TxSettings, mds []*ttnpb.MACState_UplinkMessage_RxMetadata, )
| 742 | } |
| 743 | |
| 744 | func downlinkPathsFromMetadata( |
| 745 | settings *ttnpb.MACState_UplinkMessage_TxSettings, mds []*ttnpb.MACState_UplinkMessage_RxMetadata, |
| 746 | ) []downlinkPath { |
| 747 | mds = append(mds[:0:0], mds...) |
| 748 | sort.SliceStable(mds, buildMetadataComparator(settings, mds)) |
| 749 | head := make([]downlinkPath, 0, len(mds)) |
| 750 | body := make([]downlinkPath, 0, len(mds)) |
| 751 | tail := make([]downlinkPath, 0, len(mds)) |
| 752 | for _, md := range mds { |
| 753 | if len(md.UplinkToken) == 0 || md.DownlinkPathConstraint == ttnpb.DownlinkPathConstraint_DOWNLINK_PATH_CONSTRAINT_NEVER { |
| 754 | continue |
| 755 | } |
| 756 | path := downlinkPath{ |
| 757 | DownlinkPath: &ttnpb.DownlinkPath{ |
| 758 | Path: &ttnpb.DownlinkPath_UplinkToken{ |
| 759 | UplinkToken: md.UplinkToken, |
| 760 | }, |
| 761 | }, |
| 762 | } |
| 763 | switch { |
| 764 | case md.PacketBroker != nil: |
| 765 | path.GatewayIdentifiers = packetbroker.GatewayIdentifiers |
| 766 | tail = append(tail, path) |
| 767 | case md.Relay != nil: |
| 768 | path.GatewayIdentifiers = relayspec.GatewayIdentifiers |
| 769 | tail = append(tail, path) |
| 770 | default: |
| 771 | path.GatewayIdentifiers = md.GatewayIds |
| 772 | switch md.DownlinkPathConstraint { |
| 773 | case ttnpb.DownlinkPathConstraint_DOWNLINK_PATH_CONSTRAINT_NONE: |
| 774 | head = append(head, path) |
| 775 | case ttnpb.DownlinkPathConstraint_DOWNLINK_PATH_CONSTRAINT_PREFER_OTHER: |
| 776 | body = append(body, path) |
| 777 | } |
| 778 | } |
| 779 | } |
| 780 | res := append(head, body...) |
| 781 | res = append(res, tail...) |
| 782 | return res |
| 783 | } |
| 784 | |
| 785 | func downlinkPathsFromRecentUplinks(ups ...*ttnpb.MACState_UplinkMessage) []downlinkPath { |
| 786 | for i := len(ups) - 1; i >= 0; i-- { |
no test coverage detected