SafeDispatch/AppServerMobile/AndroidHandler.cs
2024-02-22 18:43:59 +02:00

1367 lines
47 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}