feat(rede): placa em carinha.local e app que acha a placa sozinho
- sistema/rede: a placa vira "carinha" na rede (avahi), http://carinha.local na porta 80 (nftables redireciona para a 8100, sem tocar no 192.168.4.1 do portal Carinha-Config) e anúncio "_carinha._tcp" na 8100; - app 0.9.1: quando o endereço salvo não responde, procura o anúncio na rede (NsdManager), testa o endereço achado e passa a usar e guardar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package br.carinha.rosto;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Acha a placa na rede pelo anúncio mDNS "_carinha._tcp" (avahi na Orange Pi, o mesmo do
|
||||
* carinha.local). Assim, se o IP da placa mudar, o app se reconecta sem ninguém digitar endereço.
|
||||
* Uma busca por vez; desiste depois de alguns segundos e responde no fio principal.
|
||||
*/
|
||||
final class Descoberta {
|
||||
interface Resposta { void achou(String endereco); } // null = não achou
|
||||
|
||||
private static final String TAG = "CarinhaDescoberta";
|
||||
private static final String TIPO = "_carinha._tcp.";
|
||||
private static final long LIMITE = 8000;
|
||||
|
||||
private final NsdManager nsd;
|
||||
private final Handler principal = new Handler(Looper.getMainLooper());
|
||||
private NsdManager.DiscoveryListener ouvinte;
|
||||
private Resposta resposta;
|
||||
|
||||
Descoberta(Context c) {
|
||||
nsd = (NsdManager) c.getApplicationContext().getSystemService(Context.NSD_SERVICE);
|
||||
}
|
||||
|
||||
boolean procurando() { return ouvinte != null; }
|
||||
|
||||
void procurar(Resposta r) {
|
||||
if (nsd == null) { r.achou(null); return; }
|
||||
if (ouvinte != null) return;
|
||||
resposta = r;
|
||||
ouvinte = new NsdManager.DiscoveryListener() {
|
||||
@Override public void onDiscoveryStarted(String tipo) { }
|
||||
@Override public void onDiscoveryStopped(String tipo) { }
|
||||
@Override public void onStartDiscoveryFailed(String tipo, int erro) { terminar(null); }
|
||||
@Override public void onStopDiscoveryFailed(String tipo, int erro) { }
|
||||
@Override public void onServiceLost(NsdServiceInfo s) { }
|
||||
@Override public void onServiceFound(NsdServiceInfo s) {
|
||||
if (!s.getServiceType().startsWith("_carinha._tcp")) return;
|
||||
resolver(s);
|
||||
}
|
||||
};
|
||||
try {
|
||||
nsd.discoverServices(TIPO, NsdManager.PROTOCOL_DNS_SD, ouvinte);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "busca falhou: " + e);
|
||||
ouvinte = null;
|
||||
r.achou(null);
|
||||
return;
|
||||
}
|
||||
principal.postDelayed(new Runnable() {
|
||||
@Override public void run() { terminar(null); }
|
||||
}, LIMITE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void resolver(NsdServiceInfo s) {
|
||||
try {
|
||||
nsd.resolveService(s, new NsdManager.ResolveListener() {
|
||||
@Override public void onResolveFailed(NsdServiceInfo s, int erro) { Log.w(TAG, "não resolveu: " + erro); }
|
||||
@Override public void onServiceResolved(NsdServiceInfo s) {
|
||||
if (s.getHost() == null || s.getHost().isLoopbackAddress()) return;
|
||||
String ip = s.getHost().getHostAddress();
|
||||
if (ip == null || ip.contains(":")) return; // só IPv4: o servidor ouve em 0.0.0.0
|
||||
terminar("http://" + ip + ":" + s.getPort());
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "resolver falhou: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private void terminar(final String endereco) {
|
||||
principal.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (ouvinte == null) return; // já respondeu
|
||||
try { nsd.stopServiceDiscovery(ouvinte); } catch (Exception e) { /* já parou */ }
|
||||
ouvinte = null;
|
||||
Resposta r = resposta;
|
||||
resposta = null;
|
||||
Log.i(TAG, endereco == null ? "placa não encontrada na rede" : "placa encontrada: " + endereco);
|
||||
if (r != null) r.achou(endereco);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void parar() { terminar(null); }
|
||||
}
|
||||
Reference in New Issue
Block a user