WifiP2pGroup.java revision 55bc5f3e0408bcb5a39a6732de0b2d1aa99a55be
155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/* 255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Copyright (C) 2011 The Android Open Source Project 355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Licensed under the Apache License, Version 2.0 (the "License"); 555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * you may not use this file except in compliance with the License. 655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * You may obtain a copy of the License at 755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * http://www.apache.org/licenses/LICENSE-2.0 955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 1055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Unless required by applicable law or agreed to in writing, software 1155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * distributed under the License is distributed on an "AS IS" BASIS, 1255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * See the License for the specific language governing permissions and 1455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * limitations under the License. 1555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */ 1655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 1755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpackage android.net.wifi.p2p; 1855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 1955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Parcelable; 2055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Parcel; 2155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 2255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.ArrayList; 2355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.List; 2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.Collection; 2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.Collections; 2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/** 2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * A class representing a Wi-Fi P2p group 2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * @hide 3055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */ 3155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpublic class WifiP2pGroup implements Parcelable { 3255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 3355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** The network name */ 3455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private String mNetworkName; 3555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 3655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** The network bssid */ 3755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private String mNetworkBssid; 3855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 3955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Group owner */ 4055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private WifiP2pDevice mOwner; 4155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 4255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Device is group owner */ 4355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private boolean mIsGroupOwner; 4455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 4555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Group clients */ 4655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private List<WifiP2pDevice> mClients = new ArrayList<WifiP2pDevice>(); 4755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 4855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private int mChannel; 4955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 5055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** 5155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * The network passphrase 5255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * <p/> 5355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * The passphrase used for WPA2-PSK 5455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */ 5555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private String mPassphrase; 5655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 5755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** 5855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * TODO: fix 5955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Sometimes supplicant sends a psk 6055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */ 6155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private String mPsk; 6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 6355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Indicates that the group is persistent */ 6455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private boolean mIsPersistent; 6555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 6655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync private String mInterface; 6755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 6855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public WifiP2pGroup() { 6955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 7055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 7155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** 7255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * @param string formats supported include 7355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 7455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437 7555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc| 7655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 7755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 7855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED 7955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 8055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13 8155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * bssid=fa:7b:7a:42:82:13 unknown-network 8255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * 8355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Note: The events formats can be looked up in the wpa_supplicant code 8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */ 8555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public WifiP2pGroup(String supplicantEvent) throws IllegalArgumentException { 8655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 8755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync String[] tokens = supplicantEvent.split(" "); 8855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 8955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (tokens.length < 3) { 9055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync throw new IllegalArgumentException("Malformed supplicant event"); 9155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 9255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 9355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (tokens[0].startsWith("P2P-GROUP")) { 9455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mInterface = tokens[1]; 9555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mIsGroupOwner = tokens[2].equals("GO"); 9655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync for (String token : tokens) { 9855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync String[] nameValue = token.split("="); 9955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue.length != 2) continue; 10055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 10155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("ssid")) { 10255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mNetworkName = nameValue[1]; 10355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync continue; 10455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 10555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 10655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("freq")) { 10755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync try { 10855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mChannel = Integer.parseInt(nameValue[1]); 10955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } catch (NumberFormatException e) { 11055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mChannel = 0; //invalid 11155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 11255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync continue; 11355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 11455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 11555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("psk")) { 11655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mPsk = nameValue[1]; 11755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync continue; 11855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 11955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 12055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("passphrase")) { 12155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mPassphrase = nameValue[1]; 12255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync continue; 12355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 12455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 12555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("go_dev_addr")) { 12655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mOwner = new WifiP2pDevice(nameValue[1]); 12755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 12855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 12955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) { 13055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync for (String token : tokens) { 13155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync String[] nameValue = token.split("="); 13255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue.length != 2) continue; 13355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 13455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("go_dev_addr")) { 13555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mOwner = new WifiP2pDevice(nameValue[1]); 13655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync continue; 13755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 13855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 13955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (nameValue[0].equals("bssid")) { 14055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mNetworkBssid = nameValue[1]; 14155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 14255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 14355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } else { 14455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync throw new IllegalArgumentException("Malformed supplicant event"); 14555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 14655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 14755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 14855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public boolean isGroupOwner() { 14955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return mIsGroupOwner; 15055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 15155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 15255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public WifiP2pDevice getOwner() { 15355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return mOwner; 15455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 15555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 15655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public void addClient(String address) { 15755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync addClient(new WifiP2pDevice(address)); 15855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 15955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 16055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public void addClient(WifiP2pDevice device) { 16155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync for (WifiP2pDevice client : mClients) { 16255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (client.equals(device)) return; 16355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 16455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync mClients.add(device); 16555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 16655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 16755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public boolean removeClient(String address) { 16855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return mClients.remove(new WifiP2pDevice(address)); 16955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 17055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 17155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public boolean removeClient(WifiP2pDevice device) { 17255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return mClients.remove(device); 17355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 17455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public boolean isClientListEmpty() { 17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return mClients.size() == 0; 17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 17855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 17955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public Collection<WifiP2pDevice> getClientList() { 18055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return Collections.unmodifiableCollection(mClients); 18155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 18255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 18355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public String getInterface() { 18455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return mInterface; 18555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 18655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 18755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync // TODO: implement 18855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public String toString() { 18955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync StringBuffer sbuf = new StringBuffer(); 19055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync //sbuf.append("SSID: ").append(SSID); 19155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync //sbuf.append("\n passphrase: ").append(passphrase); 19255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return sbuf.toString(); 19355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 19455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 19555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Implement the Parcelable interface {@hide} */ 19655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public int describeContents() { 19755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return 0; 19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** copy constructor {@hide} */ 20155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync // TODO: implement 20255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public WifiP2pGroup(WifiP2pGroup source) { 20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync if (source != null) { 20455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Implement the Parcelable interface {@hide} */ 20855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync // STOPSHIP: implement 20955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public void writeToParcel(Parcel dest, int flags) { 21055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 21155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 21255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync /** Implement the Parcelable interface {@hide} */ 21355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public static final Creator<WifiP2pGroup> CREATOR = 21455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync new Creator<WifiP2pGroup>() { 21555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public WifiP2pGroup createFromParcel(Parcel in) { 21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync WifiP2pGroup group = new WifiP2pGroup(); 21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return group; 21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 21955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync 22055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync public WifiP2pGroup[] newArray(int size) { 22155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync return new WifiP2pGroup[size]; 22255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync } 22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync }; 22455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync} 225