1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net.lowpan;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import java.util.Objects;
22
23/**
24 * Provides detailed information about a given channel.
25 *
26 * @hide
27 */
28// @SystemApi
29public class LowpanChannelInfo implements Parcelable {
30
31    public static final int UNKNOWN_POWER = Integer.MAX_VALUE;
32    public static final float UNKNOWN_FREQUENCY = 0.0f;
33    public static final float UNKNOWN_BANDWIDTH = 0.0f;
34
35    private int mIndex = 0;
36    private String mName = null;
37    private float mSpectrumCenterFrequency = UNKNOWN_FREQUENCY;
38    private float mSpectrumBandwidth = UNKNOWN_BANDWIDTH;
39    private int mMaxTransmitPower = UNKNOWN_POWER;
40    private boolean mIsMaskedByRegulatoryDomain = false;
41
42    /** @hide */
43    public static LowpanChannelInfo getChannelInfoForIeee802154Page0(int index) {
44        LowpanChannelInfo info = new LowpanChannelInfo();
45
46        if (index < 0) {
47            info = null;
48
49        } else if (index == 0) {
50            info.mSpectrumCenterFrequency = 868300000.0f;
51            info.mSpectrumBandwidth = 600000.0f;
52
53        } else if (index < 11) {
54            info.mSpectrumCenterFrequency = 906000000.0f - (2000000.0f * 1) + 2000000.0f * (index);
55            info.mSpectrumBandwidth = 0; // Unknown
56
57        } else if (index < 26) {
58            info.mSpectrumCenterFrequency =
59                    2405000000.0f - (5000000.0f * 11) + 5000000.0f * (index);
60            info.mSpectrumBandwidth = 2000000.0f;
61
62        } else {
63            info = null;
64        }
65
66        info.mName = Integer.toString(index);
67
68        return info;
69    }
70
71    private LowpanChannelInfo() {}
72
73    private LowpanChannelInfo(int index, String name, float cf, float bw) {
74        mIndex = index;
75        mName = name;
76        mSpectrumCenterFrequency = cf;
77        mSpectrumBandwidth = bw;
78    }
79
80    public String getName() {
81        return mName;
82    }
83
84    public int getIndex() {
85        return mIndex;
86    }
87
88    public int getMaxTransmitPower() {
89        return mMaxTransmitPower;
90    }
91
92    public boolean isMaskedByRegulatoryDomain() {
93        return mIsMaskedByRegulatoryDomain;
94    }
95
96    public float getSpectrumCenterFrequency() {
97        return mSpectrumCenterFrequency;
98    }
99
100    public float getSpectrumBandwidth() {
101        return mSpectrumBandwidth;
102    }
103
104    @Override
105    public String toString() {
106        StringBuffer sb = new StringBuffer();
107
108        sb.append("Channel ").append(mIndex);
109
110        if (mName != null && !mName.equals(Integer.toString(mIndex))) {
111            sb.append(" (").append(mName).append(")");
112        }
113
114        if (mSpectrumCenterFrequency > 0.0f) {
115            if (mSpectrumCenterFrequency > 1000000000.0f) {
116                sb.append(", SpectrumCenterFrequency: ")
117                        .append(mSpectrumCenterFrequency / 1000000000.0f)
118                        .append("GHz");
119            } else if (mSpectrumCenterFrequency > 1000000.0f) {
120                sb.append(", SpectrumCenterFrequency: ")
121                        .append(mSpectrumCenterFrequency / 1000000.0f)
122                        .append("MHz");
123            } else {
124                sb.append(", SpectrumCenterFrequency: ")
125                        .append(mSpectrumCenterFrequency / 1000.0f)
126                        .append("kHz");
127            }
128        }
129
130        if (mSpectrumBandwidth > 0.0f) {
131            if (mSpectrumBandwidth > 1000000000.0f) {
132                sb.append(", SpectrumBandwidth: ")
133                        .append(mSpectrumBandwidth / 1000000000.0f)
134                        .append("GHz");
135            } else if (mSpectrumBandwidth > 1000000.0f) {
136                sb.append(", SpectrumBandwidth: ")
137                        .append(mSpectrumBandwidth / 1000000.0f)
138                        .append("MHz");
139            } else {
140                sb.append(", SpectrumBandwidth: ")
141                        .append(mSpectrumBandwidth / 1000.0f)
142                        .append("kHz");
143            }
144        }
145
146        if (mMaxTransmitPower != UNKNOWN_POWER) {
147            sb.append(", MaxTransmitPower: ").append(mMaxTransmitPower).append("dBm");
148        }
149
150        return sb.toString();
151    }
152
153    @Override
154    public boolean equals(Object obj) {
155        if (!(obj instanceof LowpanChannelInfo)) {
156            return false;
157        }
158        LowpanChannelInfo rhs = (LowpanChannelInfo) obj;
159        return Objects.equals(mName, rhs.mName)
160                && mIndex == rhs.mIndex
161                && mIsMaskedByRegulatoryDomain == rhs.mIsMaskedByRegulatoryDomain
162                && mSpectrumCenterFrequency == rhs.mSpectrumCenterFrequency
163                && mSpectrumBandwidth == rhs.mSpectrumBandwidth
164                && mMaxTransmitPower == rhs.mMaxTransmitPower;
165    }
166
167    @Override
168    public int hashCode() {
169        return Objects.hash(
170                mName,
171                mIndex,
172                mIsMaskedByRegulatoryDomain,
173                mSpectrumCenterFrequency,
174                mSpectrumBandwidth,
175                mMaxTransmitPower);
176    }
177
178    /** Implement the Parcelable interface. */
179    @Override
180    public int describeContents() {
181        return 0;
182    }
183
184    /** Implement the Parcelable interface. */
185    @Override
186    public void writeToParcel(Parcel dest, int flags) {
187        dest.writeInt(mIndex);
188        dest.writeString(mName);
189        dest.writeFloat(mSpectrumCenterFrequency);
190        dest.writeFloat(mSpectrumBandwidth);
191        dest.writeInt(mMaxTransmitPower);
192        dest.writeBoolean(mIsMaskedByRegulatoryDomain);
193    }
194
195    /** Implement the Parcelable interface. */
196    public static final Creator<LowpanChannelInfo> CREATOR =
197            new Creator<LowpanChannelInfo>() {
198
199                public LowpanChannelInfo createFromParcel(Parcel in) {
200                    LowpanChannelInfo info = new LowpanChannelInfo();
201
202                    info.mIndex = in.readInt();
203                    info.mName = in.readString();
204                    info.mSpectrumCenterFrequency = in.readFloat();
205                    info.mSpectrumBandwidth = in.readFloat();
206                    info.mMaxTransmitPower = in.readInt();
207                    info.mIsMaskedByRegulatoryDomain = in.readBoolean();
208
209                    return info;
210                }
211
212                public LowpanChannelInfo[] newArray(int size) {
213                    return new LowpanChannelInfo[size];
214                }
215            };
216}
217