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 com.android.server.wifi;
18
19import java.io.IOException;
20
21/**
22 * This class carries the payload of a Hotspot 2.0 Wireless Network Management (WNM) frame,
23 * described in the Hotspot 2.0 spec, section 3.2.
24 */
25public class WnmData {
26    private static final int ESS = 1;   // HS2.0 spec section 3.2.1.2, table 4
27
28    private final long mBssid;
29    private final String mUrl;
30    private final boolean mDeauthEvent;
31    private final int mMethod;
32    private final boolean mEss;
33    private final int mDelay;
34
35    public static WnmData buildWnmData(String event) throws IOException {
36        // %012x HS20-SUBSCRIPTION-REMEDIATION "%u %s", osu_method, url
37        // %012x HS20-DEAUTH-IMMINENT-NOTICE "%u %u %s", code, reauth_delay, url
38
39        String[] segments = event.split(" ");
40        if (segments.length < 2) {
41            throw new IOException("Short event");
42        }
43
44        switch (segments[1]) {
45            case WifiMonitor.HS20_SUB_REM_STR: {
46                if (segments.length != 4) {
47                    throw new IOException("Expected 4 segments");
48                }
49                return new WnmData(Long.parseLong(segments[0], 16),
50                        segments[3],
51                        Integer.parseInt(segments[2]));
52            }
53            case WifiMonitor.HS20_DEAUTH_STR: {
54                if (segments.length != 5) {
55                    throw new IOException("Expected 5 segments");
56                }
57                int codeID = Integer.parseInt(segments[2]);
58                if (codeID < 0 || codeID > ESS) {
59                    throw new IOException("Unknown code");
60                }
61                return new WnmData(Long.parseLong(segments[0], 16),
62                        segments[4],
63                        codeID == ESS,
64                        Integer.parseInt(segments[3]));
65            }
66            default:
67                throw new IOException("Unknown event type");
68        }
69    }
70
71    private WnmData(long bssid, String url, int method) {
72        mBssid = bssid;
73        mUrl = url;
74        mMethod = method;
75        mEss = false;
76        mDelay = -1;
77        mDeauthEvent = false;
78    }
79
80    private WnmData(long bssid, String url, boolean ess, int delay) {
81        mBssid = bssid;
82        mUrl = url;
83        mEss = ess;
84        mDelay = delay;
85        mMethod = -1;
86        mDeauthEvent = true;
87    }
88
89    public long getBssid() {
90        return mBssid;
91    }
92
93    public String getUrl() {
94        return mUrl;
95    }
96
97    public boolean isDeauthEvent() {
98        return mDeauthEvent;
99    }
100
101    public int getMethod() {
102        return mMethod;
103    }
104
105    public boolean isEss() {
106        return mEss;
107    }
108
109    public int getDelay() {
110        return mDelay;
111    }
112}
113