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 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); } /// /// Format and send vehicule list request /// /// /// private void VehiculeListRequest(string userID, string sourceIP) { SM.Debug("Android RX: Vehicle_list_req"); AddUserIDtoNS(sourceIP, userID); //======================= // get vehicule list //======================= List 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 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); } } /// /// Format and send GPS history request /// /// /// /// private void GPSHistoryRequest(int his_sc_id, int his_startGMT, int his_stopGMT) { SM.Debug("Android RX: GPShistory_req"); List 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 commandList = new List(); // 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 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 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); } /// /// Format and send AlarmHistoory request /// /// private void AlarmHistoryRequest(int userID) { SM.Debug("Android RX: Alarm_List_req"); //======================= // get alert list //======================= List 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); } /// /// Format and send the recording request /// /// /// /// private void RecordingRequest(int user_id, int gw_id) { SM.Debug("Android RX: Recording_req"); List recList = new List(); 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 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 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 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 zoneList = DB.GetAllRadioZones(rgw.Id); int lastZ = 0; // loop through zones foreach (RadioZones zone in zoneList) { //==================================== // get channel list for current zone //==================================== List 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 } }