SafeDispatch/AppServerMobile/AndroidHandler.cs

1367 lines
47 KiB
C#
Raw Normal View History

2024-02-22 16:43:59 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using SafeMobileLib;
using System.Collections;
using AndroidLIB;
namespace AppServerMobile
{
class AndroidHandler
{
private int port;
private SafeMobileLib.TCPServer server;
private SafeMobileLib.TCPServer audioServer;
private Hashtable ht_NetworkStreams;//key - (string)IP ; value -(AndrComIdent) {ip;ns;gwid;rgid}
private Hashtable ht_AudioNetworkStreams;//key - (string)IP ; value -(AndrComIdent) {ip;ns;gwid;rgid}
private Hashtable ht_MultiVoice;
private PreParser preParser;
private DBhandler DB;
private Thread listenThread;
private Thread androListenThread;
private RecordingHandle recHandle;
private string pattern_ip = "224.20.userID.1";
public AndroidHandler()
{
ht_NetworkStreams = new Hashtable();
ht_AudioNetworkStreams = new Hashtable();
ht_MultiVoice = new Hashtable();
port = Program.CFG.andPort;
SM.Debug("Android helper TCP port:" + port);
//=================================
//init preparser ==> create queue
//================================
preParser = new PreParser();
//=======================
//init TCP com server
//=======================
server = new TCPServer();
server.OnMessageRecvWithIdent += new TCPServer.MessageRecvWithIdent(server_OnMessageRecv);
server.OnConnectionRecv += new TCPServer.ConnectionRecv(server_OnConnectionRecv);
server.OnConnectionEnded += new TCPServer.ConnectionEnded(server_OnConnectionEnded);
//=======================
//init TCP audio server
//=======================
audioServer = new TCPServer();
audioServer.OnConnectionRecv += new TCPServer.ConnectionRecv(audioServer_OnConnectionRecv);
audioServer.OnConnectionEnded += new TCPServer.ConnectionEnded(audioServer_OnConnectionEnded);
audioServer.OnMessageRecvWithIdent += new TCPServer.MessageRecvWithIdent(audioServer_OnMessageRecvWithIdent);
//=======================
//ini DB con
//=======================
DB = new DBhandler();
// start listen thread to message bus
listenThread = new Thread(new ThreadStart(Listen2MessageBus));
listenThread.IsBackground = true;
listenThread.Start();
// start listen thread to android
androListenThread = new Thread(new ThreadStart(Listen2AndroBus));
androListenThread.IsBackground = true;
androListenThread.Start();
//init andro decode encode helper
recHandle = new RecordingHandle(Program.CFG.DB_IP, 15679, 50003);
}
void AddIdentToNS(string IP,int gwid, int rgwid, string userID="0")
{
if (ht_NetworkStreams.ContainsKey(IP))
{
AndrComIdent aci = (AndrComIdent)ht_NetworkStreams[IP];
aci.Gwid = gwid;
aci.Rgwid = rgwid;
aci.UserID = userID;
}
if (ht_AudioNetworkStreams.ContainsKey(IP))
{
AndrComIdent aci = (AndrComIdent)ht_AudioNetworkStreams[IP];
aci.Gwid = gwid;
aci.Rgwid = rgwid;
aci.UserID = userID;
}
}
private void AddUserIDtoNS(string IP,string userID)
{
if (ht_NetworkStreams.ContainsKey(IP))
{
AndrComIdent aci = (AndrComIdent)ht_NetworkStreams[IP];
aci.UserID = userID;
}
if (ht_AudioNetworkStreams.ContainsKey(IP))
{
AndrComIdent aci = (AndrComIdent)ht_AudioNetworkStreams[IP];
aci.UserID = userID;
}
}
void server_OnConnectionRecv(NetworkStream ns, string IP)
{
if (ht_NetworkStreams.ContainsKey(IP))
ht_NetworkStreams.Remove(IP);
AndrComIdent comIdent = new AndrComIdent() { IP = IP, NetStream = ns, Gwid = -1, Rgwid = -1 };
ht_NetworkStreams.Add(IP, comIdent);
}
void server_OnConnectionEnded(string IP)
{
if (ht_NetworkStreams.ContainsKey(IP))
ht_NetworkStreams.Remove(IP);
}
void server_OnMessageRecv(byte[] data, int recv, string ip)
{
String stringData = System.Text.Encoding.ASCII.GetString(data, 0, recv);
String usefulData = stringData.Trim();
//server.Send(data, recv, ns);
SM.Debug("RX Android("+ip+"):" + usefulData);
// add data to android queue
preParser.FeedData(data, recv,ip);
}
public void Start()
{
server.Start(port);
audioServer.Start(Program.CFG.andAudioPort);
}
public void Stop()
{
server.Stop();
audioServer.Stop();
}
#region Android audio
void audioServer_OnConnectionRecv(NetworkStream ns, string IP)
{
if (ht_AudioNetworkStreams.ContainsKey(IP))
ht_AudioNetworkStreams.Remove(IP);
AndrComIdent comIdent = new AndrComIdent() { IP = IP, NetStream = ns, Gwid = -1, Rgwid = -1 };
ht_AudioNetworkStreams.Add(IP, comIdent);
}
void audioServer_OnConnectionEnded(string IP)
{
if (ht_AudioNetworkStreams.ContainsKey(IP))
ht_AudioNetworkStreams.Remove(IP);
}
void audioServer_OnMessageRecvWithIdent(byte[] data, int recv, string ip)
{
if (ht_AudioNetworkStreams.ContainsKey(ip))
{
AndrComIdent aci = (AndrComIdent)ht_AudioNetworkStreams[ip];
string uniqueIdentif = aci.Gwid + "." + aci.Rgwid;
if (ht_MultiVoice.Contains(uniqueIdentif))
{
MultiVoice mv = (MultiVoice)ht_MultiVoice[uniqueIdentif];
int packetSize = 512;
if (recv <= packetSize)
{
mv.SendAudio(data, recv);
}
else
{
byte[] dataChunks = new byte[packetSize];
for (int offset = 0, size = recv; offset < recv; offset += packetSize, size -= packetSize)
{
int readCount = Math.Min(packetSize, size);
Array.Copy(data, offset, dataChunks, 0, readCount);
mv.SendAudio(dataChunks, readCount);
}
}
}
}
}
public void SendAudio2Android(byte[] data, int len, int gwid, int rgwid)
{
foreach (DictionaryEntry de in ht_AudioNetworkStreams)
{
AndrComIdent aci = (AndrComIdent)de.Value;
NetworkStream ns = aci.NetStream;
if((aci.Gwid == gwid) && (aci.Rgwid ==rgwid))
SendAudio2Android(data, len, ns);
}
}
public void SendAudio2Android(byte[] data, int len, NetworkStream ns)
{
try
{
audioServer.Send(data, len, ns);
/* this block will decode audio received from Android
if (ns != null)
{
nAndro.AddAudio4Decode(data);
while (nAndro.Length > 0)
{
byte[] dataout = new byte[len * 2];
int recv = nAndro.GetDecodedAudio(dataout, 0, len * 2);
//Console.WriteLine("Play recv" + recv);
//Console.WriteLine("nadro len=" + nAndro.Length);
audioServer.Send(dataout, recv, ns);
}
}
else
{
SM.Debug("Error!!! MessageBusHandler messagebus =null");
}*/
}
catch (Exception ex)
{
SM.Debug(ex.ToString());
}
}
#endregion
#region Android message
private void Listen2AndroBus()
{
//Console.WriteLine("UDP multicast listen thread started!!!"+mcastGroup);
while (true)
{
try
{
if (PreParser.AndroMessageQueue != null)
{
AndroidMSG msg = PreParser.AndroMessageQueue.GetItem(100);
if (msg != null)
{
ProcessAndroidMessage(msg, msg.sourceIP);
}
}
Thread.Sleep(100);
}
catch (ThreadAbortException)
{
break;
}
catch (Exception ex)
{
SM.Debug("RadioComHandler.cs->Listen2MessageBus" + ex.ToString());
Thread.Sleep(10);
}
}
}
private void LoginListRequest()
{
SM.Debug("Android RX: Login_List_req");
//=======================
//get user list
//=======================
List<User> listUsr = DB.GetUserList();
//=======================
// format user list
//=======================
StringBuilder userList = new StringBuilder(2048);
foreach (User usr in listUsr)
{
userList.Append($"{usr.UserName}&{usr.Id}&{usr.Password};");
}
//=======================
// format command
//=======================
string opCode = ((int)Android_MSG_type.Login_List_rpl).ToString();
string andrMSG = "#" + opCode + "#" + userList + "#";
//=======================
// send command
//=======================
SendAndroid("0.0", andrMSG);
}
/// <summary>
/// Format and send vehicule list request
/// </summary>
/// <param name="userID"></param>
/// <param name="sourceIP"></param>
private void VehiculeListRequest(string userID, string sourceIP)
{
SM.Debug("Android RX: Vehicle_list_req");
AddUserIDtoNS(sourceIP, userID);
//=======================
// get vehicule list
//=======================
List<Vehicles> listVeh = DB.GetVehiclesList(userID, true);
//=========================
// format the vehicule list
//=========================
StringBuilder vehList = new StringBuilder(2048);
foreach (Vehicles veh in listVeh)
{
vehList.Append($"{veh.Id}&{veh.Imei}&{veh.SerialNumber}&{veh.VehName}&{veh.GroupName}&{veh.ImgID}&{veh.UserName}&{veh.EnableStatus};");
}
//=======================
// format command
//=======================
string opCode = ((int)Android_MSG_type.Veh_rpl).ToString();
string andrMSG = $"#{opCode}#{vehList.ToString()}#";
//=======================
// send command
//=======================
SendAndroid("0.0", andrMSG);
}
private void TextMessageListRequest(int sc_id, int timeGMT)
{
SM.Debug("Android RX: SMS_req");
//=======================
// get text mesage list
//=======================
List<smsmessage> listSMS = DB.GetSMSforUnit(sc_id, timeGMT);
if (listSMS.Count > 0)
{
SM.Debug("+++ sending sms no:" + listSMS.Count);
string opCode = ((int)Android_MSG_type.SMS_rpl).ToString();
FormatAndSendTextMessageList(listSMS, opCode);
}
}
/// <summary>
/// Format and send GPS history request
/// </summary>
/// <param name="his_sc_id"></param>
/// <param name="his_startGMT"></param>
/// <param name="his_stopGMT"></param>
private void GPSHistoryRequest(int his_sc_id, int his_startGMT, int his_stopGMT)
{
SM.Debug("Android RX: GPShistory_req");
List<UnitGpsPos> listLP = DB.GetGPSHistory(his_sc_id, his_startGMT, his_stopGMT);
//=============================================
// send number of history records
//=============================================
string opCode = ((int)Android_MSG_type.GPShistory_countrpl).ToString();
string andrMSG = $"#{opCode}#{listLP.Count}#";
SendAndroid("0.0", andrMSG);
if (listLP.Count < 2000)
{
StringBuilder gpsHistoryList = new StringBuilder(2048);
opCode = ((int)Android_MSG_type.GPShistory_rpl).ToString();
string historyPack = "";
List<string> commandList = new List<string>();
// create commands with history records up to 900 chars to be sent and store them into commandList
foreach (UnitGpsPos gps in listLP)
{
historyPack = $"{gps.IMEI}&{gps.lat}&{gps.lng}&{gps.speed}&{gps.status}&{gps.timeGMT}&{gps.adr};";
//==============================================
// format commands and store them to the list
//==============================================
if ((gpsHistoryList.Length + historyPack.Length) > 900)
{
//=======================
// format command
//=======================
andrMSG = $"#{opCode}#{gpsHistoryList.ToString()}#";
//=======================
// add command to the list
//=======================
commandList.Add(andrMSG);
gpsHistoryList.Clear();
}
gpsHistoryList.Append(historyPack);
}
//==============================================
// add one more command for the rest
//==============================================
if (gpsHistoryList.Length > 0)
{
andrMSG = $"#{opCode}#{gpsHistoryList.ToString()}#";
commandList.Add(andrMSG);
}
//=======================
// send stored commands
//=======================
int count = 0;
foreach (String obj in commandList)
{
count++;
SendAndroid(count + "." + commandList.Count.ToString(), obj);
Thread.Sleep(100);
}
if (commandList.Count == 0)
SendAndroid("0.0", "#" + opCode + "#0&0&0&0&0&0&0;#");
SM.Debug("List count: " + commandList.Count);
}
}
private void LastTextMessageListRequest(int user_id)
{
SM.Debug("Android RX: SMS_last_req");
//=======================
// get text mesage list
//=======================
List<smsmessage> listSMS = DB.GetLastSMS(user_id);
if (listSMS.Count > 0)
{
SM.Debug("+++ sending sms no:" + listSMS.Count);
string opCode = ((int)Android_MSG_type.SMS_last_rpl).ToString();
FormatAndSendTextMessageList(listSMS, opCode);
}
}
private void FormatAndSendTextMessageList(List<smsmessage> listSMS, string opCode)
{
StringBuilder textMessageList = new StringBuilder(2048);
string andrMSG = "";
string textMessage = "";
foreach (smsmessage sms in listSMS)
{
//=======================
// format text message
//=======================
textMessage = $"{sms.idx}&{sms.status}&{sms.timeGMT}&{sms.mess}&{sms.sc_id_sour}&{sms.sc_id_dest}&{sms.seq_id};";
//=============================================
//send text message pack => max 1024 chars;
//=============================================
if ((textMessageList.Length + textMessage.Length) > 1023)
{
andrMSG = $"#{opCode}#{textMessageList.ToString()}#";
SendAndroid("0.0", andrMSG);
textMessageList.Clear();
}
textMessageList.Append(textMessage);
}
//=======================
// send any left overs packs
//=======================
andrMSG = $"#{opCode}#{textMessageList.ToString()}#";
SendAndroid("0.0", andrMSG);
}
/// <summary>
/// Format and send AlarmHistoory request
/// </summary>
/// <param name="userID"></param>
private void AlarmHistoryRequest(int userID)
{
SM.Debug("Android RX: Alarm_List_req");
//=======================
// get alert list
//=======================
List<AlarmHisItem> listAlarm = DB.GetAlarmList(userID);
//=======================
// format alert list
//=======================
StringBuilder alertList = new StringBuilder(2048);
foreach (AlarmHisItem alarm in listAlarm)
{
alertList.Append($"{alarm.ACK}&{alarm.Id}&{alarm.Sc_id}&{alarm.Text}&{alarm.TimegmtUnix}&{(Int32)alarm.Type};");
}
//=======================
// format command
//=======================
string opCode = ((int)Android_MSG_type.Alarmhistory_rpl).ToString();
string andrMSG = $"#{opCode}#{alertList.ToString()}#";
//=======================
// send command
//=======================
SendAndroid("0.0", andrMSG);
}
/// <summary>
/// Format and send the recording request
/// </summary>
/// <param name="user_id"></param>
/// <param name="gw_id"></param>
/// <param name="radio_gw_id"></param>
private void RecordingRequest(int user_id, int gw_id)
{
SM.Debug("Android RX: Recording_req");
List<Recording> recList = new List<Recording>();
ArrayList param = new ArrayList();
// 0 typesd 0 =gateway 1 = dispather
// 1 gw_id
// 2 radiogw_id //sc_id from the field in case o dispatcher
// 3 subscriber_id // user_id of dispatcher
// User type
param.Add(1);
// User type gateway ID 0
param.Add(gw_id);
// User type radio gateway ID 0
param.Add(0);
// User type my user id
param.Add(user_id);
List<RadioGateway> listGWs = DB.GetAllRadioGW();
foreach (RadioGateway obj in listGWs)
{
param.Add(0);
param.Add((Int32)obj.Gw_id);//1
param.Add((Int32)obj.Id);//8
param.Add(0); // i don't limit to specify subscriber
}
recList = DB.GetAllRecordingsForDispatcherAndAssignGateway(param, 0, Int32.MaxValue, user_id);
string RecCMD = "";
foreach (Recording rec in recList)
{
string RecPack = "";
string groupName = "";
if (rec.group_cpsId != null)
{
groupName = DB.getTalkGroupNameFromCpsId((int)rec.group_cpsId);
}
RecPack = rec.id + "&" + rec.startTime + "&" + rec.endTime + "&" + rec.gwID + "&" + rec.radioGWID + "&" + rec.subs_imei + "&" + rec.typeSD + "&" + rec.calltype + "&" + rec.group_cpsId + "&" + rec.dispatcher_id + "&" + groupName + "&";
RecCMD += RecPack + ";";
}
//=======================
// format command
//=======================
string opCode = ((int)Android_MSG_type.Recording_rpl).ToString();
string andrMSG = "#" + opCode + "#" + RecCMD + "#";
//=======================
// send command
//=======================
SendAndroid("0.0", andrMSG);
}
private void AlarmAck(AndroidMSG msg)
{
// #48#2.1507709848636433174488152074#238#0.0.115#3
SM.Debug("Android RX: Alarm_ACK_req");
//=======================
// send on messageBus
//=======================
Int32 respAlarmAck = DB.SendAckAlarm(msg.alarm_id, msg.alarm_type, msg.userID);
String seqID = msg.userID + "." + DateTime.Now.GetSecondsLocalFromDT() + DateTime.Now.Ticks.ToString();
string unitid = DB.GetVehiclesList(msg.userID).FirstOrDefault(v => v.VehName == msg.unitName).Imei;
string message = "#238#" + "0.0." + unitid + "#" + msg.alarm_type;
MessageBussHandler.SendOnMsgBuss(seqID, message);
Thread.Sleep(100);
//=======================
// format command
//=======================
string opCode = ((int)Android_MSG_type.AlarmAck_rpl).ToString();
string andrMSG = $"#{opCode}#1#";
//=======================
// send command
//=======================
SendAndroid("0.0", andrMSG);
}
private void RecordPlayRequest(Int64 play_id)
{
SM.Debug("Android RX: RecordPlay_req");
byte[] temp = BitConverter.GetBytes(play_id);
byte[] buff = new byte[temp.Length + 1];
buff[0] = 1;
int i = 1;
foreach (byte b in temp)
{
buff[i] = b;
i++;
}
if (recHandle != null)
{
recHandle.ConnectAudio();
recHandle.SendAPP(buff, buff.Length);
}
}
private void LastPositionRequest(int userID)
{
SM.Debug("Android RX: LastPos_req");
string andrMSG = "";
List<UnitGpsPos> listLP = DB.GetLastPos(userID);
StringBuilder lastPositionList = new StringBuilder(2048);
string opCode = ((int)Android_MSG_type.LastPos_rpl).ToString();
string lastPosition = "";
foreach (UnitGpsPos lp in listLP)
{
lastPosition = $"{lp.IMEI}&{lp.lat}&{lp.lng}&{lp.speed}&{lp.status}&{lp.timeGMT}&{lp.adr};";
//send last pos in packs of 1024 chars;
if ((lastPositionList.Length + lastPosition.Length) > 1023)
{
andrMSG = $"#{opCode}#{lastPositionList.ToString()}#";
SendAndroid("0.0", andrMSG);
lastPositionList.Clear();
}
lastPositionList.Append(lastPosition);
}
// send any left overs packs
if (lastPositionList.Length > 0)
{
andrMSG = $"#{opCode}#{lastPositionList.ToString()}#";
SendAndroid("0.0", andrMSG);
}
}
private void ProcessAndroidMessage(AndroidMSG msg, string sourceIP)
{
if (!msg.OK)
{
SM.Debug("Message not OK msg:"+msg.allData);
return;
}
switch (msg.opCode)
{
case (int)Android_MSG_type.Login_List_req:
LoginListRequest();
break;
case (int)Android_MSG_type.Veh_req:
VehiculeListRequest(msg.userID, sourceIP);
break;
case (int)Android_MSG_type.SMS_req:
TextMessageListRequest(msg.smsSCID, msg.timeGMT);
break;
case (int)Android_MSG_type.Alarmhistory_req:
AlarmHistoryRequest(Convert.ToInt32(msg.userID));
break;
case (int)Android_MSG_type.Recording_req:
RecordingRequest(Convert.ToInt32(msg.userID), msg.gw_id);
break;
case (int)Android_MSG_type.AlarmAck_req:
AlarmAck(msg);
break;
case (int)Android_MSG_type.RecordPlay_req:
RecordPlayRequest(msg.play_id);
break;
case (int)Android_MSG_type.SMS_last_req:
LastTextMessageListRequest(Convert.ToInt32(msg.userID));
break;
case (int)Android_MSG_type.LastPos_req:
LastPositionRequest(Convert.ToInt32(msg.userID));
break;
case (int)Android_MSG_type.GPShistory_req:
GPSHistoryRequest(msg.his_sc_id, msg.his_startGMT, msg.his_stopGMT);
break;
case (int)Android_MSG_type.SMS_send:
{
SM.Debug("Android RX: SMS_send");
SM.Debug("data:" + msg.data);
SM.Debug("userID:" + msg.userID);
SM.Debug("seqID:" + msg.seqIDsms);
SM.Debug("SCID:" + msg.smsSCID);
SM.Debug("TXT:" + msg.smsTXT);
SendSMS(msg.seqIDsms, msg.smsSCID, msg.smsTXT, msg.userID);
break;
}
case (int)Android_MSG_type.Radio_req:
{
SM.Debug("Android RX: Radio_req");
SM.Debug("data:" + msg.data);
RadioMSG rMSG = new RadioMSG(msg);
ProcessRadioMessage(rMSG,sourceIP);
break;
}
default:
break;
}
}
private void GatewayListRequest()
{
string radioMSG = "";
SM.Debug("Android RX: gw_list_req");
// get radio gw list
List<RadioGateway> listGWs = DB.GetAllRadioGW();
StringBuilder gatewayList = new StringBuilder(2048);
int opcode = (int)Android_MSG_type.Radio_rpl;
string rOPcode = ((int)Radio_MSG_type.gw_list_rpl).ToString();
// loop through gateway list
foreach (RadioGateway rgw in listGWs)
{
StringBuilder zonesStr = new StringBuilder(2048);
//===================================
// get zone list for current gateway
//===================================
List<RadioZones> zoneList = DB.GetAllRadioZones(rgw.Id);
int lastZ = 0;
// loop through zones
foreach (RadioZones zone in zoneList)
{
//====================================
// get channel list for current zone
//====================================
List<RadioChannels> channelList = DB.GetAllRadioChannels(zone.Id);
//================================================================
// format channels => id / nr / name, ( e.g 5 / 2 / Channel 2,4 / 1 / Channel 1 )
//================================================================
string channelStr = string.Join(",", channelList.Select( x => $"{x.Id}/{x.Nr}/{x.Name}" ));
//==================================================================================
// format zones => id:nr:name:channels e.g ( 3:1:Zone 1:5 / 2 / Channel 2)
//==================================================================================
lastZ++;
zonesStr.Append($"{zone.Id}:{zone.Nr}:{zone.Name}:{channelStr}");
if (lastZ != zoneList.Count)
zonesStr.Append("@");
}
// e.g ( 4&2&1&192.168.10.1&3:1:Zone 1:5 / 2 / Channel 2; )
string gwPack = $"{rgw.Id}&{rgw.Gw_id}&{rgw.Imei}&{rgw.Ip}&{zonesStr.ToString()};";
//send gw list in packs of 1024 chars;
if ((gatewayList.Length + gwPack.Length) > 1023)
{
radioMSG = $"#{opcode}#{rOPcode}#{gatewayList.ToString()}#";
SendAndroid("0.0", radioMSG);
gatewayList.Clear();
}
gatewayList.Append(gwPack);
}
// send any left overs packs
if (gatewayList.Length > 0)
{
// e.g (#50#200#4&2&1&192.168.10.1&3:1:Zone 1:5 / 2 / Channel 2;#)
radioMSG = $"#{opcode}#{rOPcode}#{gatewayList.ToString()}#";
SendAndroid("0.0", radioMSG);
}
}
//process all radio functions (this extends ProcessAndroidMessage)!!!
private void ProcessRadioMessage(RadioMSG msg, string sourceIP)
{
SM.Debug("MSG OP CODE " + msg.rOpcode);
switch (msg.rOpcode)
{
case (int)Radio_MSG_type.gw_list_req:
{
GatewayListRequest();
break;
}
case (int)Radio_MSG_type.gw_zone_channel_req:
{
SM.Debug("Android RX: gw_zone_channel_req");
SendZoneAndChannel(msg.gwID, msg.rgwID, msg.zoneNr, msg.channelNr);
//add current radio to hash
AddIdentToNS(sourceIP, msg.gwID, msg.rgwID);
break;
}
case (int)Radio_MSG_type.su_enable_disable_req:
{
SendSUenable_disable(msg.sc_id, msg.status);
break;
}
case (int)Radio_MSG_type.poll_req:
{
SendPOLL(msg.sc_id);
break;
}
case (int)Radio_MSG_type.dekey_req:
{
SendDekey(msg.gwID,msg.rgwID);
break;
}
//PTT stuff
//all call init 101
case (int)Radio_MSG_type.ptt_all_init:
{
SMd.Debug("Processing all call request");
string ip = pattern_ip.Replace("userID", msg.userID);
string message = "#101#" + msg.gwID + "." + msg.rgwID + "#" + ip + "#";
SendInitCall(msg, message);
break;
}
//all call stop 111
case (int)Radio_MSG_type.ptt_all_stop:
{
SMd.Debug("Processing all call stop");
string ip = pattern_ip.Replace("userID", msg.userID);
string message = "#111#" + msg.gwID + "." + msg.rgwID + "#" + ip + "#";
SendEndCall(msg, message);
break;
}
//grp call init 103
case (int)Radio_MSG_type.ptt_grp_init:
{
SMd.Debug("Processing group call request");
string ip = pattern_ip.Replace("userID", msg.userID);
string message = "#103#" + msg.gwID + "." + msg.rgwID + "." + msg.groupID + "#" + ip + "#";
SendInitCall(msg, message);
break;
}
//grp call stop 113
case (int)Radio_MSG_type.ptt_grp_stop:
{
SMd.Debug("Processing group call stop");
string ip = pattern_ip.Replace("userID", msg.userID);
string message = "#113#" + msg.gwID + "." + msg.rgwID + "." + msg.groupID + "#" + ip + "#";
SendEndCall(msg, message);
break;
}
//prv call init 102
case (int)Radio_MSG_type.ptt_prv_init:
{
SMd.Debug("Processing private call request");
string ip = pattern_ip.Replace("userID", msg.userID);
string message = "#102#" + msg.gwID + "." + msg.rgwID + "." + msg.radioID + "#" + ip + "#";
SendInitCall(msg, message);
break;
}
//prv call stop 112
case (int)Radio_MSG_type.ptt_prv_stop:
{
SMd.Debug("Processing private call stop");
string ip = pattern_ip.Replace("userID", msg.userID);
string message = "#112#" + msg.gwID + "." + msg.rgwID + "." + msg.radioID + "#" + ip + "#";
SendEndCall(msg, message);
break;
}
default:
break;
}
}
private void SendInitCall(RadioMSG msg, string message)
{
MessageBussHandler.SendOnMsgBuss("0.0", message);
//test if already in hashtable stop the voice and remove it to make place for the new one
string uniqueIdentif = msg.gwID + "." + msg.rgwID;
RemoveMultiVoiceFromHT(uniqueIdentif);
//start voice transfer
string ip = pattern_ip.Replace("userID", msg.userID);
MultiVoice mv = new MultiVoice(ip, msg.gwID, msg.rgwID);
ht_MultiVoice.Add(uniqueIdentif, mv);
}
private void SendEndCall(RadioMSG msg, string message)
{
MessageBussHandler.SendOnMsgBuss("0.0", message);
string uniqueIdentif = msg.gwID + "." + msg.rgwID;
RemoveMultiVoiceFromHT(uniqueIdentif);
}
public void SendAndroid(string seqID, string msg)
{
foreach(DictionaryEntry de in ht_NetworkStreams)
{
AndrComIdent aci = (AndrComIdent)de.Value;
NetworkStream ns = aci.NetStream;
SendAndroid(seqID, msg, ns);
}
}
public void SendAndroid(string seqID, string msg, NetworkStream ns)
{
try
{
if (ns != null)
{
String cmdok = "#" + seqID + msg;
Int32 tmp = cmdok.Length + 1;
tmp += tmp.ToString().Length;
cmdok = "#" + tmp.ToString() + cmdok;
System.Text.Encoding enc = System.Text.Encoding.ASCII;
byte[] buf = enc.GetBytes(cmdok);
//udp.Send(buf, buf.Length);
server.Send(buf, buf.Length, ns);
SM.Debug("android TX:" + cmdok, true);
}
else
{
SM.Debug("Error!!! MessageBusHandler messagebus =null");
}
}
catch (Exception ex)
{
SM.Debug(ex.ToString());
}
}
public void SendAndroid_MsgFromMSGbuss(string msg)
{
foreach (DictionaryEntry de in ht_NetworkStreams)
{
AndrComIdent aci = (AndrComIdent)de.Value;
NetworkStream ns = aci.NetStream;
SendAndroid_MsgFromMSGbuss(msg,ns);
}
}
public void SendAndroid_MsgFromMSGbuss(string msg, NetworkStream ns)
{
if (ns != null)
{
System.Text.Encoding enc = System.Text.Encoding.ASCII; byte[] buf = enc.GetBytes(msg);
//udp.Send(buf, buf.Length);
server.Send(buf, buf.Length, ns);
SM.Debug("bridge(MSGbuss->android) TX:" + msg, true);
}
else
{
SM.Debug("Error!!! MessageBusHandler messagebus =null");
}
}
#endregion
#region Messagebuss
private void Listen2MessageBus()
{
//Console.WriteLine("UDP multicast listen thread started!!!"+mcastGroup);
while (true)
{
try
{
if (MessageBussHandler.MBMessageQueue != null)
{
MessageBusMessage msg = MessageBussHandler.MBMessageQueue.GetItem(100);
if (msg != null)
MSGbussParser(msg);
}
Thread.Sleep(100);
}
catch (ThreadAbortException)
{
break;
}
catch (Exception ex)
{
SM.Debug("RadioComHandler.cs->Listen2MessageBus" + ex.ToString());
Thread.Sleep(10);
}
}
}
private void SendSMS(String seqID,int sc_id, string txt, string userId)
{
UnitSysPosition sysPos = DB.GetUnitSysPosition(sc_id);
if (sysPos == null) sysPos = new UnitSysPosition(0, 0);
int sched_time = (int)DateTime.Now.ToUniversalTime().DateTo70Format();
//String seqID = userID.ToString() + "." + DBmanager.DateTo70Format(DateTime.Now.ToUniversalTime()).ToString() + DateTime.Now.Ticks.ToString();
String Imei = DB.GetImei(sc_id);
string mesage = "#142#" + sysPos.Gw_id + "." + sysPos.R_gw_id + "." + Imei + "#" + txt + "#" + sched_time + "#" + userId + "#";
MessageBussHandler.SendOnMsgBuss(seqID, mesage);
SM.Debug("Multi TX:" + mesage);
}
private void SendSUenable_disable(int sc_id, int status)
{
SM.Debug("SendSUenable_disable " + sc_id + " | " + status);
int userID = 1;
UnitSysPosition sysPos = DB.GetUnitSysPosition(sc_id);
int sched_time = (int)DateTime.Now.ToUniversalTime().DateTo70Format();
String seqID = userID.ToString() + "." + DateTime.Now.ToUniversalTime().DateTo70Format().ToString() + DateTime.Now.Ticks.ToString();
String Imei = DB.GetImei(sc_id);
if (sysPos != null)
{
string mesage = "#150#" + sysPos.Gw_id + "." + sysPos.R_gw_id + "." + Imei + "#" + status + "#";
MessageBussHandler.SendOnMsgBuss(seqID, mesage);
}
}
private void SendPOLL(int sc_id)
{
SM.Debug("SendPOLL " + sc_id);
int userID = 1;
UnitSysPosition sysPos = DB.GetUnitSysPosition(sc_id);
int sched_time = (int)DateTime.Now.ToUniversalTime().DateTo70Format();
String seqID = userID.ToString() + "." + DateTime.Now.ToUniversalTime().DateTo70Format().ToString() + DateTime.Now.Ticks.ToString();
String Imei = DB.GetImei(sc_id);
if (sysPos != null)
{
string mesage = "#154#" + sysPos.Gw_id + "." + sysPos.R_gw_id + "." + Imei + "#";
MessageBussHandler.SendOnMsgBuss(seqID, mesage);
}
}
private void SendDekey(Int32 gw_id,Int32 r_gw_id)
{
string mesage = "#160#" + gw_id + "." + r_gw_id + "#";
MessageBussHandler.SendOnMsgBuss("0.0", mesage);
}
private void SendZoneAndChannel(int gwID,int rgwID, int zoneNR, int channelNR)
{
string opcode = "104";
String seqID = "0.0";
if (zoneNR == 0 && channelNR == 0)
opcode = "94";
string mesage = "#" + opcode + "#" + gwID + "." + rgwID + "#" + zoneNR + "." + channelNR + "#";
MessageBussHandler.SendOnMsgBuss(seqID, mesage);
}
private void MSGbussParser(MessageBusMessage msg)
{
if (!msg.OK)
return;
switch (msg.opCode)
{
case 132:
{
SM.Debug("New SMS sending it to android!!!");
string[] fieldArr = msg.allData.Split("#".ToCharArray());
if (fieldArr.Length > 4)
{
int radioID = Convert.ToInt32(fieldArr[4]);
string message = fieldArr[5];
string andrMSG = $"#132#{radioID}#{message}#";
SendAndroid(msg.seqID, andrMSG);
}
break;
}
case 242:
{
SM.Debug("SMS reply sending it to android!!!");
SendAndroid_MsgFromMSGbuss(msg.allData);
break;
}
case 131:
{
SM.Debug("Location sending it to android!!!");
SendAndroid_MsgFromMSGbuss(msg.allData);
break;
}
case 231:
{
SM.Debug("Location sending it to android!!!");
SendAndroid_MsgFromMSGbuss(msg.allData);
break;
}
case 124:
{
SM.Debug("Zone and channel-> sending it to android!!!");
string[] tempArr = msg.data.Split("#".ToCharArray());
string andrMSG = "#50#204#" + tempArr[0].Replace('.', '/') + "&" + tempArr[1].Replace('.', '/');
SendAndroid(msg.seqID, andrMSG);
break;
}
case 100:
{
SM.Debug("Radio Gateway on/off broadcast-> sending it to android!!!");
string[] tempArr = msg.data.Split("#".ToCharArray());
string andrMSG = "#50#199#" + tempArr[0].Replace('.', '/') + "&" + tempArr[1] + "#";
SendAndroid(msg.seqID, andrMSG);
break;
}
case 250:
{
SM.Debug("Radio enable/disable status broadcast sending it to android!!!");
string[] tempArr = msg.data.Split("#".ToCharArray());
string andrMSG = "#50#250#" + tempArr[0] + "&" + tempArr[1] + "#";
SendAndroid(msg.seqID, andrMSG);
break;
}
case 135:
case 136:
case 137:
case 138:
case 140:
{
SM.Debug("Send alarm from message bus to android!!!");
SendAndroid_MsgFromMSGbuss(msg.allData);
break;
}
case 125:
{
string[] tempArr = msg.data.Split("#".ToCharArray());
tempArr[0] = tempArr[0].Replace('.','/');
string andrMSG = "#50#125#" + tempArr[0] + "&" + tempArr[1] + "&" + tempArr[2] + "&" + tempArr[3] + "#";
SendAndroid("0.0",andrMSG);
SM.Debug($"Broadcast '{GetCallStatus(tempArr[1])}' call status to android!!!");
//send audio
string identifiers = tempArr[0];
string[] tempIdent = identifiers.Split("/".ToCharArray());
if (tempIdent.Length > 1)
{
int gwID = Convert.ToInt32(tempIdent[0]);
int radiogwID = Convert.ToInt32(tempIdent[1]);
string uniqueIdentif = gwID.ToString() + "." + radiogwID.ToString();
RemoveMultiVoiceFromHT(uniqueIdentif);
//got start call message
if (tempArr[1] == "1") // init call
{
string pattern_voiceip = "224.10.gwID.radioGwID";
//string ip = "224.10." + gwID.ToString() + "." + radiogwID.ToString();
string ip = pattern_voiceip.Replace("gwID", gwID.ToString()).Replace("radioGwID", radiogwID.ToString());
MultiVoice mv = new MultiVoice(ip, gwID, radiogwID);
mv.OnNewDataRecv += new MultiVoice.newData4Send(mv_OnNewDataRecv);
mv.Start();
ht_MultiVoice.Add(uniqueIdentif, mv);
}
}
break;
}
default:
break;
}
}
private string GetCallStatus(string code)
{
switch (code)
{
case "1":
return "Init";
case "2":
return "HangTime";
case "3":
return "CallEnd";
}
return "Unknown";
}
void mv_OnNewDataRecv(byte[] data, int dataLen, int gwid, int rgwid)
{
SendAudio2Android(data, dataLen, gwid, rgwid);
}
private void RemoveMultiVoiceFromHT(string uniqueIdentif)
{
if (ht_MultiVoice.ContainsKey(uniqueIdentif))
{
MultiVoice mv = (MultiVoice)ht_MultiVoice[uniqueIdentif];
if (mv.IsRecording)
mv.Stop();
ht_MultiVoice.Remove(uniqueIdentif);
}
}
//get bytes from raw data
private byte[] getBytesFromRawData(byte[] rawData)
{
Int32 head = 0;
for (int i = 0; i < (rawData.Length - 1); i++)
if (rawData[i] == 35) head = i;
byte[] forDecodeData3 = new byte[rawData.Length - head - 2];
Int32 j = 0;
for (int i = (head + 1); i < (rawData.Length - 1); i++)
{
forDecodeData3[j] = rawData[i];
j++;
}
return forDecodeData3;
}
#endregion
}
}