kopia lustrzana https://github.com/N0BOY/FT8CN
186 wiersze
5.4 KiB
Java
186 wiersze
5.4 KiB
Java
package com.bg7yoz.ft8cn.flex;
|
||
|
||
import android.util.Log;
|
||
|
||
import java.net.DatagramPacket;
|
||
import java.net.DatagramSocket;
|
||
import java.net.SocketException;
|
||
import java.util.ArrayList;
|
||
import java.util.Timer;
|
||
import java.util.TimerTask;
|
||
|
||
// VITA 形成的发现消息解析器的枚举定义
|
||
//enum VitaTokens {
|
||
// nullToken ,
|
||
// ipToken,
|
||
// portToken,
|
||
// modelToken,
|
||
// serialToken,
|
||
// callsignToken,
|
||
// nameToken,
|
||
// dpVersionToken,
|
||
// versionToken,
|
||
// statusToken,
|
||
//};
|
||
/**
|
||
* RadioFactory 当前发现的所有收音机。
|
||
* RadioFactory: 实例化这个类来创建一个 Radio Factory,它将为网络上发现的无线电维护FlexRadio列表flexRadios。
|
||
*
|
||
* 通过Upd协议,在4992端口的广播数据中获取vita协议数据,并解析出序列号,用于更新电台列表flexRadios。
|
||
* @author BGY70Z
|
||
* @date 2023-03-20
|
||
*/
|
||
public class FlexRadioFactory {
|
||
private static final String TAG="FlexRadioFactory";
|
||
private static final int FLEX_DISCOVERY_PORT =4992;
|
||
private static FlexRadioFactory instance=null;
|
||
private final RadioUdpClient broadcastClient ;
|
||
private OnFlexRadioEvents onFlexRadioEvents;
|
||
|
||
private Timer refreshTimer=null;
|
||
private TimerTask refreshTask=null;
|
||
|
||
public ArrayList<FlexRadio> flexRadios=new ArrayList<>();
|
||
|
||
/**
|
||
* 获取电台列表实例
|
||
* @return 电台列表实例
|
||
*/
|
||
public static FlexRadioFactory getInstance(){
|
||
if (instance==null){
|
||
instance= new FlexRadioFactory();
|
||
}
|
||
return instance;
|
||
}
|
||
|
||
|
||
|
||
public FlexRadioFactory() {
|
||
broadcastClient = new RadioUdpClient(FLEX_DISCOVERY_PORT);
|
||
|
||
broadcastClient.setOnUdpEvents(new RadioUdpClient.OnUdpEvents() {
|
||
@Override
|
||
public void OnReceiveData(DatagramSocket socket, DatagramPacket packet, byte[] data) {
|
||
VITA vita = new VITA(data);
|
||
if (vita.isAvailable//如果数据包有效,且classId=0x534CFFFF,StreamId=0x800,更新电台列表
|
||
&&vita.informationClassCode==VITA.FLEX_CLASS_ID
|
||
&&vita.packetClassCode==VITA.VS_Discovery
|
||
&&vita.streamId==VITA.FLEX_Discovery_stream_ID){
|
||
updateFlexRadioList(new String(vita.payload));
|
||
}
|
||
}
|
||
});
|
||
try {
|
||
broadcastClient.setActivated(true);
|
||
} catch (SocketException e) {
|
||
e.printStackTrace();
|
||
Log.e(TAG, "FlexRadioFactory: "+e.getMessage());
|
||
}
|
||
|
||
}
|
||
|
||
|
||
public void startRefreshTimer(){
|
||
if (refreshTimer==null) {
|
||
refreshTask=new TimerTask() {
|
||
@Override
|
||
public void run() {
|
||
Log.e(TAG, "run: 检查离线" );
|
||
checkOffLineRadios();
|
||
}
|
||
};
|
||
refreshTimer=new Timer();
|
||
refreshTimer.schedule(refreshTask, 1000, 1000);//检查电台列表中的电台是否在线(每一秒)
|
||
}
|
||
}
|
||
public void cancelRefreshTimer(){
|
||
if (refreshTimer!=null){
|
||
refreshTimer.cancel();
|
||
refreshTimer=null;
|
||
refreshTask.cancel();
|
||
refreshTask=null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 从数据中查找电台的序列号
|
||
* @param s 数据
|
||
* @return 序列号
|
||
*/
|
||
private String getSerialNum(String s){
|
||
String[] strings=s.split(" ");
|
||
for (int i = 0; i <strings.length ; i++) {
|
||
if (strings[i].toLowerCase().startsWith("serial")){
|
||
return strings[i].substring("serial".length()+1);
|
||
}
|
||
}
|
||
return "";
|
||
}
|
||
|
||
/**
|
||
* 在电台列表中查找有没有指定序列号的电台
|
||
* @param serial 序列号
|
||
* @return 电台实例
|
||
*/
|
||
public FlexRadio checkFlexRadioBySerial(String serial){
|
||
for (FlexRadio radio:flexRadios) {
|
||
if (radio.isEqual(serial)){
|
||
return radio;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
private synchronized void updateFlexRadioList(String s){
|
||
String serial=getSerialNum(s);
|
||
if (serial.equals("")){return;}
|
||
FlexRadio radio=checkFlexRadioBySerial(serial);
|
||
if (radio!=null){
|
||
radio.updateLastSeen();
|
||
}else {
|
||
radio=new FlexRadio(s);
|
||
if (onFlexRadioEvents!=null){
|
||
onFlexRadioEvents.OnFlexRadioAdded(radio);
|
||
}
|
||
flexRadios.add(radio);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查电台是不是离线,如果离线,触发离线事件
|
||
*/
|
||
private void checkOffLineRadios(){
|
||
for (FlexRadio radio:flexRadios) {
|
||
if (radio.isInvalidNow()){
|
||
if (onFlexRadioEvents!=null){
|
||
onFlexRadioEvents.OnFlexRadioInvalid(radio);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//***********Getter****************
|
||
public RadioUdpClient getBroadcastClient() {
|
||
return broadcastClient;
|
||
}
|
||
|
||
public OnFlexRadioEvents getOnFlexRadioEvents() {
|
||
return onFlexRadioEvents;
|
||
}
|
||
|
||
public void setOnFlexRadioEvents(OnFlexRadioEvents onFlexRadioEvents) {
|
||
this.onFlexRadioEvents = onFlexRadioEvents;
|
||
}
|
||
//*********************************
|
||
|
||
|
||
/**
|
||
* 电台列表变化的接口
|
||
*/
|
||
public static interface OnFlexRadioEvents{
|
||
void OnFlexRadioAdded(FlexRadio flexRadio);
|
||
void OnFlexRadioInvalid(FlexRadio flexRadio);
|
||
}
|
||
|
||
}
|