1/*
2 * Copyright (C) 2008 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.p2p;
18
19import android.net.wifi.p2p.WifiP2pConfig;
20import android.net.wifi.p2p.WifiP2pGroup;
21import android.net.wifi.p2p.WifiP2pGroupList;
22import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
23
24/**
25 * Native calls for bring up/shut down of the supplicant daemon and for
26 * sending requests to the supplicant daemon
27 *
28 * {@hide}
29 */
30public class WifiP2pNative {
31    private final String mTAG;
32    private final String mInterfaceName;
33    private final SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
34
35    public WifiP2pNative(String interfaceName, SupplicantP2pIfaceHal p2pIfaceHal) {
36        mTAG = "WifiP2pNative-" + interfaceName;
37        mInterfaceName = interfaceName;
38        mSupplicantP2pIfaceHal = p2pIfaceHal;
39    }
40
41    public String getInterfaceName() {
42        return mInterfaceName;
43    }
44
45    /**
46     * Enable verbose logging for all sub modules.
47     */
48    public void enableVerboseLogging(int verbose) {
49    }
50
51    /********************************************************
52     * Supplicant operations
53     ********************************************************/
54    /**
55     * This method is called repeatedly until the connection to wpa_supplicant is established.
56     *
57     * @return true if connection is established, false otherwise.
58     * TODO: Add unit tests for these once we remove the legacy code.
59     */
60    public boolean connectToSupplicant() {
61        // Start initialization if not already started.
62        if (!mSupplicantP2pIfaceHal.isInitializationStarted()
63                && !mSupplicantP2pIfaceHal.initialize()) {
64            return false;
65        }
66        // Check if the initialization is complete.
67        return mSupplicantP2pIfaceHal.isInitializationComplete();
68    }
69
70    /**
71     * Close supplicant connection.
72     */
73    public void closeSupplicantConnection() {
74        // Nothing to do for HIDL.
75    }
76
77    /**
78     * Set WPS device name.
79     *
80     * @param name String to be set.
81     * @return true if request is sent successfully, false otherwise.
82     */
83    public boolean setDeviceName(String name) {
84        return mSupplicantP2pIfaceHal.setWpsDeviceName(name);
85    }
86
87    /**
88     * Populate list of available networks or update existing list.
89     *
90     * @return true, if list has been modified.
91     */
92    public boolean p2pListNetworks(WifiP2pGroupList groups) {
93        return mSupplicantP2pIfaceHal.loadGroups(groups);
94    }
95
96    /**
97     * Initiate WPS Push Button setup.
98     * The PBC operation requires that a button is also pressed at the
99     * AP/Registrar at about the same time (2 minute window).
100     *
101     * @param iface Group interface name to use.
102     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
103     * @return true, if operation was successful.
104     */
105    public boolean startWpsPbc(String iface, String bssid) {
106        return mSupplicantP2pIfaceHal.startWpsPbc(iface, bssid);
107    }
108
109    /**
110     * Initiate WPS Pin Keypad setup.
111     *
112     * @param iface Group interface name to use.
113     * @param pin 8 digit pin to be used.
114     * @return true, if operation was successful.
115     */
116    public boolean startWpsPinKeypad(String iface, String pin) {
117        return mSupplicantP2pIfaceHal.startWpsPinKeypad(iface, pin);
118    }
119
120    /**
121     * Initiate WPS Pin Display setup.
122     *
123     * @param iface Group interface name to use.
124     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
125     * @return generated pin if operation was successful, null otherwise.
126     */
127    public String startWpsPinDisplay(String iface, String bssid) {
128        return mSupplicantP2pIfaceHal.startWpsPinDisplay(iface, bssid);
129    }
130
131    /**
132     * Remove network with provided id.
133     *
134     * @param netId Id of the network to lookup.
135     * @return true, if operation was successful.
136     */
137    public boolean removeP2pNetwork(int netId) {
138        return mSupplicantP2pIfaceHal.removeNetwork(netId);
139    }
140
141    /**
142     * Set WPS device name.
143     *
144     * @param name String to be set.
145     * @return true if request is sent successfully, false otherwise.
146     */
147    public boolean setP2pDeviceName(String name) {
148        return mSupplicantP2pIfaceHal.setWpsDeviceName(name);
149    }
150
151    /**
152     * Set WPS device type.
153     *
154     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
155     * @return true if request is sent successfully, false otherwise.
156     */
157    public boolean setP2pDeviceType(String type) {
158        return mSupplicantP2pIfaceHal.setWpsDeviceType(type);
159    }
160
161    /**
162     * Set WPS config methods
163     *
164     * @param cfg List of config methods.
165     * @return true if request is sent successfully, false otherwise.
166     */
167    public boolean setConfigMethods(String cfg) {
168        return mSupplicantP2pIfaceHal.setWpsConfigMethods(cfg);
169    }
170
171    /**
172     * Set the postfix to be used for P2P SSID's.
173     *
174     * @param postfix String to be appended to SSID.
175     *
176     * @return boolean value indicating whether operation was successful.
177     */
178    public boolean setP2pSsidPostfix(String postfix) {
179        return mSupplicantP2pIfaceHal.setSsidPostfix(postfix);
180    }
181
182    /**
183     * Set the Maximum idle time in seconds for P2P groups.
184     * This value controls how long a P2P group is maintained after there
185     * is no other members in the group. As a group owner, this means no
186     * associated stations in the group. As a P2P client, this means no
187     * group owner seen in scan results.
188     *
189     * @param iface Group interface name to use.
190     * @param time Timeout value in seconds.
191     *
192     * @return boolean value indicating whether operation was successful.
193     */
194    public boolean setP2pGroupIdle(String iface, int time) {
195        return mSupplicantP2pIfaceHal.setGroupIdle(iface, time);
196    }
197
198    /**
199     * Turn on/off power save mode for the interface.
200     *
201     * @param iface Group interface name to use.
202     * @param enabled Indicate if power save is to be turned on/off.
203     *
204     * @return boolean value indicating whether operation was successful.
205     */
206    public boolean setP2pPowerSave(String iface, boolean enabled) {
207        return mSupplicantP2pIfaceHal.setPowerSave(iface, enabled);
208    }
209
210    /**
211     * Enable/Disable Wifi Display.
212     *
213     * @param enable true to enable, false to disable.
214     * @return true, if operation was successful.
215     */
216    public boolean setWfdEnable(boolean enable) {
217        return mSupplicantP2pIfaceHal.enableWfd(enable);
218    }
219
220    /**
221     * Set Wifi Display device info.
222     *
223     * @param hex WFD device info as described in section 5.1.2 of WFD technical
224     *        specification v1.0.0.
225     * @return true, if operation was successful.
226     */
227    public boolean setWfdDeviceInfo(String hex) {
228        return mSupplicantP2pIfaceHal.setWfdDeviceInfo(hex);
229    }
230
231    /**
232     * Initiate a P2P service discovery indefinitely.
233     * Will trigger {@link WifiP2pMonitor#P2P_DEVICE_FOUND_EVENT} on finding devices.
234     *
235     * @return boolean value indicating whether operation was successful.
236     */
237    public boolean p2pFind() {
238        return p2pFind(0);
239    }
240
241    /**
242     * Initiate a P2P service discovery with a (optional) timeout.
243     *
244     * @param timeout Max time to be spent is peforming discovery.
245     *        Set to 0 to indefinely continue discovery untill and explicit
246     *        |stopFind| is sent.
247     * @return boolean value indicating whether operation was successful.
248     */
249    public boolean p2pFind(int timeout) {
250        return mSupplicantP2pIfaceHal.find(timeout);
251    }
252
253    /**
254     * Stop an ongoing P2P service discovery.
255     *
256     * @return boolean value indicating whether operation was successful.
257     */
258    public boolean p2pStopFind() {
259        return mSupplicantP2pIfaceHal.stopFind();
260    }
261
262    /**
263     * Configure Extended Listen Timing.
264     *
265     * If enabled, listen state must be entered every |intervalInMillis| for at
266     * least |periodInMillis|. Both values have acceptable range of 1-65535
267     * (with interval obviously having to be larger than or equal to duration).
268     * If the P2P module is not idle at the time the Extended Listen Timing
269     * timeout occurs, the Listen State operation must be skipped.
270     *
271     * @param enable Enables or disables listening.
272     * @param period Period in milliseconds.
273     * @param interval Interval in milliseconds.
274     *
275     * @return true, if operation was successful.
276     */
277    public boolean p2pExtListen(boolean enable, int period, int interval) {
278        return mSupplicantP2pIfaceHal.configureExtListen(enable, period, interval);
279    }
280
281    /**
282     * Set P2P Listen channel.
283     *
284     * When specifying a social channel on the 2.4 GHz band (1/6/11) there is no
285     * need to specify the operating class since it defaults to 81. When
286     * specifying a social channel on the 60 GHz band (2), specify the 60 GHz
287     * operating class (180).
288     *
289     * @param lc Wifi channel. eg, 1, 6, 11.
290     * @param oc Operating Class indicates the channel set of the AP
291     *        indicated by this BSSID
292     *
293     * @return true, if operation was successful.
294     */
295    public boolean p2pSetChannel(int lc, int oc) {
296        return mSupplicantP2pIfaceHal.setListenChannel(lc, oc);
297    }
298
299    /**
300     * Flush P2P peer table and state.
301     *
302     * @return boolean value indicating whether operation was successful.
303     */
304    public boolean p2pFlush() {
305        return mSupplicantP2pIfaceHal.flush();
306    }
307
308    /**
309     * Start P2P group formation with a discovered P2P peer. This includes
310     * optional group owner negotiation, group interface setup, provisioning,
311     * and establishing data connection.
312     *
313     * @param config Configuration to use to connect to remote device.
314     * @param joinExistingGroup Indicates that this is a command to join an
315     *        existing group as a client. It skips the group owner negotiation
316     *        part. This must send a Provision Discovery Request message to the
317     *        target group owner before associating for WPS provisioning.
318     *
319     * @return String containing generated pin, if selected provision method
320     *        uses PIN.
321     */
322    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
323        return mSupplicantP2pIfaceHal.connect(config, joinExistingGroup);
324    }
325
326    /**
327     * Cancel an ongoing P2P group formation and joining-a-group related
328     * operation. This operation unauthorizes the specific peer device (if any
329     * had been authorized to start group formation), stops P2P find (if in
330     * progress), stops pending operations for join-a-group, and removes the
331     * P2P group interface (if one was used) that is in the WPS provisioning
332     * step. If the WPS provisioning step has been completed, the group is not
333     * terminated.
334     *
335     * @return boolean value indicating whether operation was successful.
336     */
337    public boolean p2pCancelConnect() {
338        return mSupplicantP2pIfaceHal.cancelConnect();
339    }
340
341    /**
342     * Send P2P provision discovery request to the specified peer. The
343     * parameters for this command are the P2P device address of the peer and the
344     * desired configuration method.
345     *
346     * @param config Config class describing peer setup.
347     *
348     * @return boolean value indicating whether operation was successful.
349     */
350    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
351        return mSupplicantP2pIfaceHal.provisionDiscovery(config);
352    }
353
354    /**
355     * Set up a P2P group owner manually.
356     * This is a helper method that invokes groupAdd(networkId, isPersistent) internally.
357     *
358     * @param persistent Used to request a persistent group to be formed.
359     *
360     * @return true, if operation was successful.
361     */
362    public boolean p2pGroupAdd(boolean persistent) {
363        return mSupplicantP2pIfaceHal.groupAdd(persistent);
364    }
365
366    /**
367     * Set up a P2P group owner manually (i.e., without group owner
368     * negotiation with a specific peer). This is also known as autonomous
369     * group owner.
370     *
371     * @param netId Used to specify the restart of a persistent group.
372     *
373     * @return true, if operation was successful.
374     */
375    public boolean p2pGroupAdd(int netId) {
376        return mSupplicantP2pIfaceHal.groupAdd(netId, true);
377    }
378
379    /**
380     * Terminate a P2P group. If a new virtual network interface was used for
381     * the group, it must also be removed. The network interface name of the
382     * group interface is used as a parameter for this command.
383     *
384     * @param iface Group interface name to use.
385     * @return true, if operation was successful.
386     */
387    public boolean p2pGroupRemove(String iface) {
388        return mSupplicantP2pIfaceHal.groupRemove(iface);
389    }
390
391    /**
392     * Reject connection attempt from a peer (specified with a device
393     * address). This is a mechanism to reject a pending group owner negotiation
394     * with a peer and request to automatically block any further connection or
395     * discovery of the peer.
396     *
397     * @param deviceAddress MAC address of the device to reject.
398     *
399     * @return boolean value indicating whether operation was successful.
400     */
401    public boolean p2pReject(String deviceAddress) {
402        return mSupplicantP2pIfaceHal.reject(deviceAddress);
403    }
404
405    /**
406     * Invite a device to a persistent group.
407     * If the peer device is the group owner of the persistent group, the peer
408     * parameter is not needed. Otherwise it is used to specify which
409     * device to invite. |goDeviceAddress| parameter may be used to override
410     * the group owner device address for Invitation Request should it not be
411     * known for some reason (this should not be needed in most cases).
412     *
413     * @param group Group object to use.
414     * @param deviceAddress MAC address of the device to invite.
415     *
416     * @return boolean value indicating whether operation was successful.
417     */
418    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
419        return mSupplicantP2pIfaceHal.invite(group, deviceAddress);
420    }
421
422    /**
423     * Reinvoke a device from a persistent group.
424     *
425     * @param netId Used to specify the persistent group.
426     * @param deviceAddress MAC address of the device to reinvoke.
427     *
428     * @return true, if operation was successful.
429     */
430    public boolean p2pReinvoke(int netId, String deviceAddress) {
431        return mSupplicantP2pIfaceHal.reinvoke(netId, deviceAddress);
432    }
433
434    /**
435     * Gets the operational SSID of the device.
436     *
437     * @param deviceAddress MAC address of the peer.
438     *
439     * @return SSID of the device.
440     */
441    public String p2pGetSsid(String deviceAddress) {
442        return mSupplicantP2pIfaceHal.getSsid(deviceAddress);
443    }
444
445    /**
446     * Gets the MAC address of the device.
447     *
448     * @return MAC address of the device.
449     */
450    public String p2pGetDeviceAddress() {
451        return mSupplicantP2pIfaceHal.getDeviceAddress();
452    }
453
454    /**
455     * Gets the capability of the group which the device is a
456     * member of.
457     *
458     * @param deviceAddress MAC address of the peer.
459     *
460     * @return combination of |GroupCapabilityMask| values.
461     */
462    public int getGroupCapability(String deviceAddress) {
463        return mSupplicantP2pIfaceHal.getGroupCapability(deviceAddress);
464    }
465
466    /**
467     * This command can be used to add a upnp/bonjour service.
468     *
469     * @param servInfo List of service queries.
470     *
471     * @return true, if operation was successful.
472     */
473    public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
474        return mSupplicantP2pIfaceHal.serviceAdd(servInfo);
475    }
476
477    /**
478     * This command can be used to remove a upnp/bonjour service.
479     *
480     * @param servInfo List of service queries.
481     *
482     * @return true, if operation was successful.
483     */
484    public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
485        return mSupplicantP2pIfaceHal.serviceRemove(servInfo);
486    }
487
488    /**
489     * This command can be used to flush all services from the
490     * device.
491     *
492     * @return boolean value indicating whether operation was successful.
493     */
494    public boolean p2pServiceFlush() {
495        return mSupplicantP2pIfaceHal.serviceFlush();
496    }
497
498    /**
499     * Schedule a P2P service discovery request. The parameters for this command
500     * are the device address of the peer device (or 00:00:00:00:00:00 for
501     * wildcard query that is sent to every discovered P2P peer that supports
502     * service discovery) and P2P Service Query TLV(s) as hexdump.
503     *
504     * @param addr MAC address of the device to discover.
505     * @param query Hex dump of the query data.
506     * @return identifier Identifier for the request. Can be used to cancel the
507     *         request.
508     */
509    public String p2pServDiscReq(String addr, String query) {
510        return mSupplicantP2pIfaceHal.requestServiceDiscovery(addr, query);
511    }
512
513    /**
514     * Cancel a previous service discovery request.
515     *
516     * @param id Identifier for the request to cancel.
517     * @return true, if operation was successful.
518     */
519    public boolean p2pServDiscCancelReq(String id) {
520        return mSupplicantP2pIfaceHal.cancelServiceDiscovery(id);
521    }
522
523    /**
524     * Send driver command to set Miracast mode.
525     *
526     * @param mode Mode of Miracast.
527     *        0 = disabled
528     *        1 = operating as source
529     *        2 = operating as sink
530     */
531    public void setMiracastMode(int mode) {
532        mSupplicantP2pIfaceHal.setMiracastMode(mode);
533    }
534
535    /**
536     * Get NFC handover request message.
537     *
538     * @return select message if created successfully, null otherwise.
539     */
540    public String getNfcHandoverRequest() {
541        return mSupplicantP2pIfaceHal.getNfcHandoverRequest();
542    }
543
544    /**
545     * Get NFC handover select message.
546     *
547     * @return select message if created successfully, null otherwise.
548     */
549    public String getNfcHandoverSelect() {
550        return mSupplicantP2pIfaceHal.getNfcHandoverSelect();
551    }
552
553    /**
554     * Report NFC handover select message.
555     *
556     * @return true if reported successfully, false otherwise.
557     */
558    public boolean initiatorReportNfcHandover(String selectMessage) {
559        return mSupplicantP2pIfaceHal.initiatorReportNfcHandover(selectMessage);
560    }
561
562    /**
563     * Report NFC handover request message.
564     *
565     * @return true if reported successfully, false otherwise.
566     */
567    public boolean responderReportNfcHandover(String requestMessage) {
568        return mSupplicantP2pIfaceHal.responderReportNfcHandover(requestMessage);
569    }
570
571    /**
572     * Set the client list for the provided network.
573     *
574     * @param netId Id of the network.
575     * @return  Space separated list of clients if successfull, null otherwise.
576     */
577    public String getP2pClientList(int netId) {
578        return mSupplicantP2pIfaceHal.getClientList(netId);
579    }
580
581    /**
582     * Set the client list for the provided network.
583     *
584     * @param netId Id of the network.
585     * @param list Space separated list of clients.
586     * @return true, if operation was successful.
587     */
588    public boolean setP2pClientList(int netId, String list) {
589        return mSupplicantP2pIfaceHal.setClientList(netId, list);
590    }
591
592    /**
593     * Save the current configuration to p2p_supplicant.conf.
594     *
595     * @return true on success, false otherwise.
596     */
597    public boolean saveConfig() {
598        return mSupplicantP2pIfaceHal.saveConfig();
599    }
600}
601