func (c IFConfig) MarshalJSON() ([]byte, error) {
	if !c.Enable {
		return []byte(`{"enable": false}`), nil
	}
	return json.Marshal(struct {
		Enable       bool   `json:"enable"`
		Radio        uint8  `json:"radio"`
		IFValue      int32  `json:"if"`
		Bandwidth    uint32 `json:"bandwidth,omitempty"`
		SpreadFactor uint8  `json:"spread_factor,omitempty"`
		Datarate     uint32 `json:"datarate,omitempty"`
	}{
		Enable:       c.Enable,
		Radio:        c.Radio,
		IFValue:      c.IFValue,
		Bandwidth:    c.Bandwidth,
		SpreadFactor: c.SpreadFactor,
		Datarate:     c.Datarate,
	})
}
MarshalJSON implements json.Marshaler
package shared
import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"strconv"
	"strings"
	"time"
	"go.thethings.network/lorawan-stack/v3/pkg/band"
	"go.thethings.network/lorawan-stack/v3/pkg/errors"
	"go.thethings.network/lorawan-stack/v3/pkg/frequencyplans"
	"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
)
type SX1301Config struct {
	LoRaWANPublic       bool
	ClockSource         uint8
	AntennaGain         float32
	LBTConfig           *LBTConfig
	Radios              []RFConfig
	Channels            []IFConfig
	LoRaStandardChannel *IFConfig
	FSKChannel          *IFConfig
	TxLUTConfigs        []TxLUTConfig
}
var errInvalidKey = errors.DefineInvalidArgument("invalid_key", "key `{key}` invalid")
type kv struct {
	key   string
	value interface{}
}
type orderedMap struct {
	kv []kv
}
func (m *orderedMap) add(k string, v interface{}) {
	m.kv = append(m.kv, kv{key: k, value: v})
}
func (m orderedMap) MarshalJSON() ([]byte, error) {
	var b bytes.Buffer
	b.WriteString("{")
	for i, kv := range m.kv {
		if i != 0 {
			b.WriteString(",")
		}
		key, err := json.Marshal(kv.key)
		if err != nil {
			return nil, err
		}
		b.Write(key)
		b.WriteString(":")
		val, err := json.Marshal(kv.value)
		if err != nil {
			return nil, err
		}
		b.Write(val)
	}
	b.WriteString("}")
	return b.Bytes(), nil
}
func (c SX1301Config) MarshalJSON() ([]byte, error) {
	var m orderedMap
	m.add("lorawan_public", c.LoRaWANPublic)
	m.add("clksrc", c.ClockSource)
	m.add("antenna_gain", c.AntennaGain)
	if c.LBTConfig != nil {
		m.add("lbt_cfg", *c.LBTConfig)
	}
	for i, radio := range c.Radios {
		m.add(fmt.Sprintf("radio_%d", i), radio)
	}
	for i, channel := range c.Channels {
		m.add(fmt.Sprintf("chan_multiSF_%d", i), channel)
	}
	if c.LoRaStandardChannel != nil {
		m.add("chan_Lora_std", *c.LoRaStandardChannel)
	}
	if c.FSKChannel != nil {
		m.add("chan_FSK", *c.FSKChannel)
	}
	for i, lut := range c.TxLUTConfigs {
		m.add(fmt.Sprintf("tx_lut_%d", i), lut)
	}
	return json.Marshal(m)
}
func (c *SX1301Config) UnmarshalJSON(msg []byte) error {
	var root map[string]json.RawMessage
	if err := json.Unmarshal(msg, &root); err != nil {
		return err
	}
	radioMap, txLutMap, chanMap := make(map[int]RFConfig), make(map[int]TxLUTConfig), make(map[int]IFConfig)
	for key, value := range root {
		switch {
		case key == "lorawan_public":
			if err := json.Unmarshal(value, &c.LoRaWANPublic); err != nil {
				return err
			}
		case key == "antenna_gain":
			if err := json.Unmarshal(value, &c.AntennaGain); err != nil {
				return err
			}
		case key == "clksrc":
			if err := json.Unmarshal(value, &c.ClockSource); err != nil {
				return err
			}
		case key == "lbt_cfg":
			if err := json.Unmarshal(value, &c.LBTConfig); err != nil {
				return err
			}
		case key == "chan_Lora_std":
			if err := json.Unmarshal(value, &c.LoRaStandardChannel); err != nil {
				return err
			}
		case key == "chan_FSK":
			if err := json.Unmarshal(value, &c.FSKChannel); err != nil {
				return err
			}
		case strings.HasPrefix(key, "chan_multiSF_"):
			var channel IFConfig
			if err := json.Unmarshal(value, &channel); err != nil {
				return err
			}
			var index int
			if _, err := fmt.Sscanf(key, "chan_multiSF_%d", &index); err == nil {
				chanMap[index] = channel
			} else {
				return err
			}
		case strings.HasPrefix(key, "tx_lut_"):
			var txLut TxLUTConfig
			if err := json.Unmarshal(value, &txLut); err != nil {
				return err
			}
			var index int
			if _, err := fmt.Sscanf(key, "tx_lut_%d", &index); err == nil {
				txLutMap[index] = txLut
			} else {
				return err
			}
		case strings.HasPrefix(key, "radio_"):
			var radio RFConfig
			if err := json.Unmarshal(value, &radio); err != nil {
				return err
			}
			var index int
			if _, err := fmt.Sscanf(key, "radio_%d", &index); err == nil {
				radioMap[index] = radio
			} else {
				return err
			}
		}
	}
	c.Radios, c.TxLUTConfigs, c.Channels = make([]RFConfig, len(radioMap)), make([]TxLUTConfig, len(txLutMap)), make([]IFConfig, len(chanMap))
	for key, value := range radioMap {
		c.Radios[key] = value
	}
	for key, value := range txLutMap {
		c.TxLUTConfigs[key] = value
	}
	for key, value := range chanMap {
		c.Channels[key] = value
	}
	return nil
}
type LBTConfig struct {
	Enable         bool               `json:"enable"`
	RSSITarget     float32            `json:"rssi_target"`
	ChannelConfigs []LBTChannelConfig `json:"chan_cfg"`
	RSSIOffset     float32            `json:"sx127x_rssi_offset"`
}
type LBTChannelConfig struct {
	Frequency            uint64 `json:"freq_hz"`
	ScanTimeMicroseconds uint32 `json:"scan_time_us"`
}
type RFConfig struct {
	Enable      bool    `json:"enable"`
	Type        string  `json:"type,omitempty"`
	Frequency   uint64  `json:"freq"`
	RSSIOffset  float32 `json:"rssi_offset"`
	TxEnable    bool    `json:"tx_enable"`
	TxFreqMin   uint64  `json:"tx_freq_min,omitempty"`
	TxFreqMax   uint64  `json:"tx_freq_max,omitempty"`
	TxNotchFreq uint64  `json:"tx_notch_freq,omitempty"`
}
type IFConfig struct {
	Enable       bool   `json:"enable"`
	Radio        uint8  `json:"radio"`
	IFValue      int32  `json:"if"`
	Bandwidth    uint32 `json:"bandwidth,omitempty"`
	SpreadFactor uint8  `json:"spread_factor,omitempty"`
	Datarate     uint32 `json:"datarate,omitempty"`
}