1/*
2 * Copyright (C) 2016 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.metrics;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.util.SparseArray;
22
23import com.android.internal.util.MessageUtils;
24
25/**
26 * An event recorded when IpReachabilityMonitor sends a neighbor probe or receives
27 * a neighbor probe result.
28 * {@hide}
29 */
30public final class IpReachabilityEvent implements Parcelable {
31
32    // Event types.
33    /** A probe forced by IpReachabilityMonitor. */
34    public static final int PROBE                     = 1 << 8;
35    /** Neighbor unreachable after a forced probe. */
36    public static final int NUD_FAILED                = 2 << 8;
37    /** Neighbor unreachable after a forced probe, IP provisioning is also lost. */
38    public static final int PROVISIONING_LOST         = 3 << 8;
39    /** Neighbor unreachable notification from kernel. */
40    public static final int NUD_FAILED_ORGANIC        = 4 << 8;
41    /** Neighbor unreachable notification from kernel, IP provisioning is also lost. */
42    public static final int PROVISIONING_LOST_ORGANIC = 5 << 8;
43
44    // eventType byte format (MSB to LSB):
45    // byte 0: unused
46    // byte 1: unused
47    // byte 2: type of event: PROBE, NUD_FAILED, PROVISIONING_LOST
48    // byte 3: when byte 2 == PROBE, errno code from RTNetlink or IpReachabilityMonitor.
49    public final int eventType;
50
51    public IpReachabilityEvent(int eventType) {
52        this.eventType = eventType;
53    }
54
55    private IpReachabilityEvent(Parcel in) {
56        this.eventType = in.readInt();
57    }
58
59    @Override
60    public void writeToParcel(Parcel out, int flags) {
61        out.writeInt(eventType);
62    }
63
64    @Override
65    public int describeContents() {
66        return 0;
67    }
68
69    public static final Parcelable.Creator<IpReachabilityEvent> CREATOR
70        = new Parcelable.Creator<IpReachabilityEvent>() {
71        public IpReachabilityEvent createFromParcel(Parcel in) {
72            return new IpReachabilityEvent(in);
73        }
74
75        public IpReachabilityEvent[] newArray(int size) {
76            return new IpReachabilityEvent[size];
77        }
78    };
79
80    /**
81     * Returns the NUD failure event type code corresponding to the given conditions.
82     */
83    public static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
84        if (isFromProbe) {
85            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
86        } else {
87            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
88        }
89    }
90
91    @Override
92    public String toString() {
93        int hi = eventType & 0xff00;
94        int lo = eventType & 0x00ff;
95        String eventName = Decoder.constants.get(hi);
96        return String.format("IpReachabilityEvent(%s:%02x)", eventName, lo);
97    }
98
99    final static class Decoder {
100        static final SparseArray<String> constants =
101                MessageUtils.findMessageNames(new Class[]{IpReachabilityEvent.class},
102                new String[]{"PROBE", "PROVISIONING_", "NUD_"});
103    }
104}
105