#!/bin/sh # # Copyright (C) 2019-2024, Digi International Inc. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, you can obtain one at http://mozilla.org/MPL/2.0/. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # Description: create P2P link # # Configuration variables in '/etc/network/interfaces': # Mandatory: # p2p-peer-mac # Optional: # p2p-discover-window # p2p-freq # p2p-local-address # p2p-local-netmask # p2p-network-id # # Execute only for the P2P interface [ "${IFACE}" = "##WLAN_P2P_INTERFACE##" ] || exit 0 log() { if type "systemd-cat" >/dev/null 2>/dev/null; then systemd-cat -p "${1}" -t p2plink printf "%s" "${2}" else logger -p "${1}" -t p2plink "${2}" fi } # Exit without error if the peer MAC address is not available [ -z "${IF_P2P_PEER_MAC}" ] && { log info "Peer MAC address not available"; exit 0; } # wpa_cli reports lowercase MACs, so convert to lowercase IF_P2P_PEER_MAC="$(echo "${IF_P2P_PEER_MAC}" | tr 'A-F' 'a-f')" if [ "${MODE}" = "start" ]; then wpa_cli -i"${IFACE}" p2p_find && sleep 1 for _ in $(seq "${IF_P2P_DISCOVER_WINDOW:=120}"); do wpa_cli -i"${IFACE}" p2p_peers discovered | grep -i -qs "${IF_P2P_PEER_MAC}" && { peer_found="1"; break; } sleep 1 done wpa_cli -i"${IFACE}" p2p_stop_find [ -z "${peer_found}" ] && { log err "p2p discover: peer NOT found"; exit 1; } # Peer found, establish the link log info "Peer found, establishing the P2P link" wpa_cli -i"${IFACE}" p2p_connect "${IF_P2P_PEER_MAC}" pbc ${IF_P2P_NETWORK_ID:+persistent=${IF_P2P_NETWORK_ID}} ${IF_P2P_FREQ:+freq=${IF_P2P_FREQ}} auto for _ in $(seq 20); do # When a new connection is created, we need to get the index of the new interface (p2p-${IFACE}-[0-9] # Check for the interface matching the pattern "p2p-${IFACE}-*" P2P_IFNAME=$(ip link | grep -o "p2p-${IFACE}-[0-9]") [ -z "$P2P_IFNAME" ] && sleep 1 && continue if wpa_cli -i "${P2P_IFNAME}" status 2>&1 | grep -qs "^wpa_state=COMPLETED$"; then if wpa_cli -i "${P2P_IFNAME}" status 2>&1 | grep -qs "^mode=P2P GO$"; then # P2P GO side: verify the remote peer has connected wpa_cli -i "${P2P_IFNAME}" all_sta 2>&1 | grep -i -qs "^p2p_device_addr=${IF_P2P_PEER_MAC}$" && p2p_link_found="1" elif wpa_cli -i "${P2P_IFNAME}" status 2>&1 | grep -qs "^mode=station$"; then p2p_link_found="1" fi fi if [ -n "${p2p_link_found}" ]; then # Configure the newly created interface if [ -n "${IF_P2P_LOCAL_ADDRESS}" ]; then ifconfig "${P2P_IFNAME}" "${IF_P2P_LOCAL_ADDRESS}" ${IF_P2P_LOCAL_NETMASK:+netmask ${IF_P2P_LOCAL_NETMASK}} up fi break fi sleep 1 done # Give 'ifupdown' a proper error return value if 'wpa_state' is NOT COMPLETED [ -n "${p2p_link_found}" ] && log info "P2P link created" || { log err "P2P link not created"; false ;} fi