FT8CN/ft8CN/app/src/main/java/com/bg7yoz/ft8cn/Ft8Message.java

489 wiersze
17 KiB
Java
Czysty Zwykły widok Historia

package com.bg7yoz.ft8cn;
/**
* Ft8MessageFT8
* UTC
* ----2022.5.6-----
* time_sec
* 1.便GetString
* -----2022.5.13---
* 2.i3,n3
* @author BG7YOZ
* @date 2022.5.6
*/
import android.annotation.SuppressLint;
import androidx.annotation.NonNull;
import com.bg7yoz.ft8cn.database.DatabaseOpr;
import com.bg7yoz.ft8cn.ft8signal.FT8Package;
import com.bg7yoz.ft8cn.ft8transmit.TransmitCallsign;
import com.bg7yoz.ft8cn.maidenhead.MaidenheadGrid;
import com.bg7yoz.ft8cn.rigs.BaseRigOperation;
import com.bg7yoz.ft8cn.timer.UtcTimer;
import com.google.android.gms.maps.model.LatLng;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
public class Ft8Message {
private static String TAG = "Ft8Message";
public int i3 = 0;
public int n3 = 0;
public int signalFormat = FT8Common.FT8_MODE;//是不是FT8格式的消息
public long utcTime;//UTC时间
public boolean isValid;//是否是有效信息
public int snr = 0;//信噪比
public float time_sec = 0;//时间偏移
public float freq_hz = 0;//频率
public int score = 0;//得分
public int messageHash;//消息的哈希
public String callsignFrom = null;//发起呼叫的呼号
public String callsignTo = null;//接收呼叫的呼号
public String modifier = null;//目标呼号的修饰符 如CQ POTA BG7YOZ OL50中的POTA
public String extraInfo = null;
public String maidenGrid = null;
public int report = -100;//当-100时意味着没有信号报告
public long callFromHash10 = 0;//12位长度的哈希码
public long callFromHash12 = 0;//12位长度的哈希码
public long callFromHash22 = 0;//12位长度的哈希码
public long callToHash10 = 0;//12位长度的哈希码
public long callToHash12 = 0;//12位长度的哈希码
public long callToHash22 = 0;//12位长度的哈希码
//private boolean isCallMe = false;//是不是CALL我的消息
public long band;//载波频率
public String fromWhere = null;//用于显示地址
public String toWhere = null;//用于显示地址
public boolean isQSL_Callsign = false;//是不是通联过的呼号
public static MessageHashMap hashList = new MessageHashMap();
public boolean fromDxcc = false;
public boolean fromItu = false;
public boolean fromCq = false;
public boolean toDxcc = false;
public boolean toItu = false;
public boolean toCq = false;
public LatLng fromLatLng = null;
public LatLng toLatLng = null;
@NonNull
@SuppressLint({"SimpleDateFormat", "DefaultLocale"})
@Override
public String toString() {
return String.format("%s %d %+4.2f %4.0f ~ %s Hash : %#06X",
new SimpleDateFormat("HHmmss").format(utcTime),
snr, time_sec, freq_hz, getMessageText(), messageHash);
}
/**
*
*
* @param signalFormat
*/
public Ft8Message(int signalFormat) {
this.signalFormat = signalFormat;
}
public Ft8Message(String callTo, String callFrom, String extraInfo) {
//如果是自由文本callTo=CQ,callFrom=MyCall,extraInfo=freeText
this.callsignTo = callTo.toUpperCase();
this.callsignFrom = callFrom.toUpperCase();
this.extraInfo = extraInfo.toUpperCase();
}
public Ft8Message(int i3, int n3, String callTo, String callFrom, String extraInfo) {
this.callsignTo = callTo;
this.callsignFrom = callFrom;
this.extraInfo = extraInfo;
this.i3 = i3;
this.n3 = n3;
this.utcTime = UtcTimer.getSystemTime();//用于显示TX
}
/**
*
*
* @param message messagenullmessage
*/
public Ft8Message(Ft8Message message) {
if (message != null) {
signalFormat = message.signalFormat;
utcTime = message.utcTime;
isValid = message.isValid;
snr = message.snr;
time_sec = message.time_sec;
freq_hz = message.freq_hz;
score = message.score;
band = message.band;
messageHash = message.messageHash;
if (message.callsignFrom.equals("<...>")) {//到哈希列表中查一下
callsignFrom = hashList.getCallsign(new long[]{message.callFromHash10, message.callFromHash12, message.callFromHash22});
} else {
callsignFrom = message.callsignFrom;
}
if (message.callsignTo.equals("<...>")) {//到哈希列表中查一下
callsignTo = hashList.getCallsign(new long[]{message.callToHash10, message.callToHash12, message.callToHash22});
} else {
callsignTo = message.callsignTo;
}
if (message.i3 == 4) {
hashList.addHash(FT8Package.getHash22(message.callsignFrom), message.callsignFrom);
hashList.addHash(FT8Package.getHash12(message.callsignFrom), message.callsignFrom);
hashList.addHash(FT8Package.getHash10(message.callsignFrom), message.callsignFrom);
}
extraInfo = message.extraInfo;
maidenGrid = message.maidenGrid;
report = message.report;
callToHash10 = message.callToHash10;
callToHash12 = message.callToHash12;
callToHash22 = message.callToHash22;
callFromHash10 = message.callFromHash10;
callFromHash12 = message.callFromHash12;
callFromHash22 = message.callFromHash22;
i3 = message.i3;
n3 = message.n3;
//把哈希和呼号对应关系保存到列表里
hashList.addHash(callToHash10, callsignTo);
hashList.addHash(callToHash12, callsignTo);
hashList.addHash(callToHash22, callsignTo);
hashList.addHash(callFromHash10, callsignFrom);
hashList.addHash(callFromHash12, callsignFrom);
hashList.addHash(callFromHash22, callsignFrom);
//Log.d(TAG, String.format("i3:%d,n3:%d,From:%s,To:%s", i3, n3, getCallsignFrom(), getCallsignTo()));
}
}
/**
* 使
*
* @return String 便
*/
@SuppressLint("DefaultLocale")
public String getFreq_hz() {
return String.format("%04.0f", freq_hz);
}
/**
*
*
* @return String
*/
public String getMessageText() {
if (i3 == 0 && n3 == 0) {//说明是自由文本
if (extraInfo.length() < 13) {
return String.format("%-13s", extraInfo.toUpperCase());
} else {
return extraInfo.toUpperCase().substring(0, 13);
}
}
if (modifier != null && checkIsCQ()) {//修饰符
if (modifier.matches("[0-9]{3}|[A-Z]{1,4}")) {
return String.format("%s %s %s %s", callsignTo, modifier, callsignFrom, extraInfo).trim();
}
}
return String.format("%s %s %s", callsignTo, callsignFrom, extraInfo).trim();
}
/**
*
*
* @return
*/
@SuppressLint("DefaultLocale")
public String getMessageTextWithDb() {
return String.format("%d %s %s %s", snr, callsignTo, callsignFrom, extraInfo).trim();
}
/**
*
*
* @return String 便
*/
@SuppressLint("DefaultLocale")
public String getDt() {
return String.format("%.1f", time_sec);
}
/**
* dB000
*
* @return String 便
*/
public String getdB() {
return String.valueOf(snr);
}
/**
*
*
* @return boolean true0,30true
*/
public boolean isEvenSequence() {
if (signalFormat == FT8Common.FT8_MODE) {
return (utcTime / 1000) % 15 == 0;
} else {
return (utcTime / 100) % 75 == 0;
}
}
/**
*
*
* @return String
*/
@SuppressLint("DefaultLocale")
public int getSequence() {
if (signalFormat == FT8Common.FT8_MODE) {
return (int) ((((utcTime + 750) / 1000) / 15) % 2);
} else {
return (int) (((utcTime + 370) / 100) / 75) % 2;
}
}
@SuppressLint("DefaultLocale")
public int getSequence4() {
if (signalFormat == FT8Common.FT8_MODE) {
return (int) ((((utcTime + 750) / 1000) / 15) % 4);
} else {
return (int) (((utcTime + 370) / 100) / 75) % 4;
}
}
/**
* mycall
*
* @return boolean
*/
public boolean inMyCall() {
if (GeneralVariables.myCallsign.length() == 0) return false;
return this.callsignFrom.contains(GeneralVariables.myCallsign)
|| this.callsignTo.contains(GeneralVariables.myCallsign);
//return (this.callsignFrom.contains(mycall) || this.callsignTo.contains(mycall)) && (!mycall.equals(""));
}
/*
i3.n3
0.0 Free Text TNX BOB 73 GL f71
0.1 DXpedition K1ABC RR73; W9XYZ <KH1/KH7Z> -08 c28 c28 h10 r5
0.3 Field Day K1ABC W9XYZ 6A WI c28 c28 R1 n4 k3 S7
0.4 Field Day W9XYZ K1ABC R 17B EMA c28 c28 R1 n4 k3 S7
0.5 Telemetry 123456789ABCDEF012 t71
1. Std Msg K1ABC/R W9XYZ/R R EN37 c28 r1 c28 r1 R1 g15
2. EU VHF G4ABC/P PA9XYZ JO22 c28 p1 c28 p1 R1 g15
3. RTTY RU K1ABC W9XYZ 579 WI t1 c28 c28 R1 r3 s13
4. NonStd Call <W9XYZ> PJ4/K1ABC RRR h12 c58 h1 r2 c1
5. EU VHF <G4ABC> <PA9XYZ> R 570007 JO22DB h12 h22 R1 r3 s11 g25
*/
/*
c1 CQh12
c28 CQDEQRZ22
c58 11
f71 13
g15 4RRRRR7373
g25 6
h1
h10 10
h12 12
h22 22
k3 ClassABF
n4 1-1617-32
p1 /P
r1 /R
r2 RRRRR7373
r3 2-9529-59952-59
R1 R
r5 -30+30
s11 0-2047
s13 0-7999/
S7 ARRL/RAC
t1 TU;
t71 18
*/
/**
* fromTodecode.c---TO DO----
* i1i2,i3,i4,i5,i0.1,i0.3,i0.4
*
* @return String
*/
public String getCallsignFrom() {
if (callsignFrom == null) {
return "";
}
return callsignFrom.replace("<", "").replace(">", "");
}
/**
*
*
* @return
*/
public String getCallsignTo() {
if (callsignTo == null) {
return "";
}
if (callsignTo.length() < 2) {
return "";
}
if (callsignTo.substring(0, 2).equals("CQ") || callsignTo.substring(0, 2).equals("DE")
|| callsignTo.substring(0, 3).equals("QRZ")) {
return "";
}
return callsignTo.replace("<", "").replace(">", "");
}
/**
*
*
* @return String""
*/
public String getMaidenheadGrid(DatabaseOpr db) {
if (i3 != 1 && i3 != 2) {//一般只有i3=1或i3=2标准消息甚高频消息才有网格
return GeneralVariables.getGridByCallsign(callsignFrom, db);//到对应表中找一下网格
} else {
String[] msg = getMessageText().split(" ");
if (msg.length < 1) {
return GeneralVariables.getGridByCallsign(callsignFrom, db);//到对应表中找一下网格
}
String s = msg[msg.length - 1];
if (MaidenheadGrid.checkMaidenhead(s)) {
return s;
} else {//不是网格信息,就可能是信号报告
return GeneralVariables.getGridByCallsign(callsignFrom, db);//到对应表中找一下网格
}
}
}
public String getToMaidenheadGrid(DatabaseOpr db) {
if (checkIsCQ()) return "";
return GeneralVariables.getGridByCallsign(callsignTo, db);
}
/**
* CQ
*
* @return boolean CQtrue
*/
public boolean checkIsCQ() {
String s = callsignTo.trim().split(" ")[0];
if (s == null) {
return false;
} else {
return (s.equals("CQ") || s.equals("DE") || s.equals("QRZ"));
}
}
/**
* i3.n3
*
* @return
*/
public String getCommandInfo() {
return getCommandInfoByI3N3(i3, n3);
}
/**
* i3.n3
*
* @param i i3
* @param n n3
* @return
*/
@SuppressLint("DefaultLocale")
public static String getCommandInfoByI3N3(int i, int n) {
String format = "%d.%d:%s";
switch (i) {
case 1:
case 2:
return String.format(format, i, 0, GeneralVariables.getStringFromResource(R.string.std_msg));
case 5:
case 3:
case 4:
return String.format(format, i, 0, GeneralVariables.getStringFromResource(R.string.none_std_msg));
case 0:
switch (n) {
case 0:
return String.format(format, i, n, GeneralVariables.getStringFromResource(R.string.free_text));
case 1:
return String.format(format, i, n, GeneralVariables.getStringFromResource(R.string.dXpedition));
case 3:
case 4:
return String.format(format, i, n, GeneralVariables.getStringFromResource(R.string.field_day));
case 5:
return String.format(format, i, n, GeneralVariables.getStringFromResource(R.string.telemetry));
}
}
return "";
}
//获取发送者的传输对象
public TransmitCallsign getFromCallTransmitCallsign() {
return new TransmitCallsign(this.i3, this.n3, this.callsignFrom, freq_hz
, this.getSequence()
, snr);
}
//获取发送者的传输对象,注意!!!与发送者的时序是相反的!!!
public TransmitCallsign getToCallTransmitCallsign() {
if (report == -100) {//如果消息中没有信号报告就用发送方的SNR代替
return new TransmitCallsign(this.i3, this.n3, this.callsignTo, freq_hz, (this.getSequence() + 1) % 2, snr);
} else {
return new TransmitCallsign(this.i3, this.n3, this.callsignTo, freq_hz, (this.getSequence() + 1) % 2, report);
}
}
@SuppressLint("DefaultLocale")
public String toHtml() {
StringBuilder result = new StringBuilder();
result.append("<td class=\"default\" >");
result.append(UtcTimer.getDatetimeStr(utcTime));
result.append("</td>\n");
result.append("<td class=\"default\" >");
result.append(getdB());
result.append("</td>\n");
result.append("<td class=\"default\" >");
result.append(String.format("%.1f", time_sec));
result.append("</td>\n");
result.append("<td class=\"default\" >");
result.append(String.format("%.0f", freq_hz));
result.append("</td>\n");
result.append("<td class=\"default\" >");
result.append(getMessageText());
result.append("</td>\n");
result.append("<td class=\"default\" >");
result.append(BaseRigOperation.getFrequencyStr(band));
result.append("</td>\n");
return result.toString();
}
}