• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
17 
18 package android.net.ip;
19 
20 import android.os.Handler;
21 
22 import androidx.annotation.NonNull;
23 
24 import com.android.net.module.util.InterfaceParams;
25 import com.android.net.module.util.PacketReader;
26 
27 import java.io.FileDescriptor;
28 
29 /**
30  * Monitor IGMP/MLD report packets and notify listeners the multicast address changes.
31  *
32  * <p>This class uses a {@link PacketReader} to listen for IGMP/MLD report packets on a given
33  * interface. When a packet is received, it notifies the provided {@link Callback} of the change
34  * in the multicast address.
35  *
36  * <p>To use this class, create a new instance with the desired {@link Handler},
37  * {@link InterfaceParams}, {@link Callback}, and {@link FileDescriptor}. Then, call {@link #start()}
38  * to start listening for packets. To stop listening, call {@link #stop()}.
39  */
40 public class MulticastReportMonitor {
41     public interface Callback {
42         /**
43          * Notifies the system or other components about a change in the multicast address.
44          */
notifyMulticastAddrChange()45         void notifyMulticastAddrChange();
46     }
47 
48     private static final String TAG = MulticastReportMonitor.class.getSimpleName();
49     private final PacketReader mPacketListener;
50 
51     /**
52      * Creates a new {@link MulticastReportMonitor}.
53      *
54      * @param handler The {@link Handler} to use for the {@link PacketReader}.
55      * @param ifParams The {@link InterfaceParams} for the interface to listen on.
56      * @param callback The {@link Callback} to notify the multicast address changes.
57      * @param fd The {@link FileDescriptor} to use for the {@link PacketReader}.
58      */
MulticastReportMonitor( @onNull Handler handler, @NonNull InterfaceParams ifParams, @NonNull Callback callback, @NonNull FileDescriptor fd)59     public MulticastReportMonitor(
60             @NonNull Handler handler,
61             @NonNull InterfaceParams ifParams,
62             @NonNull Callback callback,
63             @NonNull FileDescriptor fd) {
64         mPacketListener = new PacketListener(handler, ifParams, callback, fd);
65     }
66 
67     /**
68      * Starts the packet listener.
69      */
start()70     public void start() {
71         mPacketListener.start();
72     }
73 
74     /**
75      * Stops the packet listener.
76      */
stop()77     public void stop() {
78         mPacketListener.stop();
79     }
80 
81     private static final class PacketListener extends PacketReader {
82         private final Callback mCallback;
83         private final FileDescriptor mFd;
84 
PacketListener(Handler h, InterfaceParams ifParams, Callback callback, FileDescriptor fd)85         PacketListener(Handler h, InterfaceParams ifParams, Callback callback, FileDescriptor fd) {
86             super(h, ifParams.defaultMtu);
87             mCallback = callback;
88             mFd = fd;
89         }
90 
91         @Override
createFd()92         protected FileDescriptor createFd() {
93             return mFd;
94         }
95 
96         @Override
handlePacket(@onNull byte[] recvbuf, int length)97         protected void handlePacket(@NonNull byte[] recvbuf, int length) {
98             mCallback.notifyMulticastAddrChange();
99         }
100     }
101 }
102