package ippbx.eventserver;

import java.net.*; 
import java.io.*; 
import java.sql.*; 
import java.util.*; 
import java.nio.channels.*;
import java.nio.charset.*;

import ippbx.database.*; 
import common.*; 

import org.asteriskjava.live.AsteriskChannel;
import org.asteriskjava.live.CallDetailRecord;
import org.asteriskjava.live.ChannelState;
import org.asteriskjava.live.AsteriskQueue;
import org.asteriskjava.live.*;
import org.asteriskjava.manager.ManagerConnection;
import org.asteriskjava.live.AsteriskServer;
import org.asteriskjava.manager.action.*;
import org.asteriskjava.live.DefaultAsteriskServer;
import org.asteriskjava.manager.ManagerEventListener;
import org.asteriskjava.manager.event.*;
import org.asteriskjava.manager.response.*;
 
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MsgServer implements ManagerEventListener
{         
ServerSocket serverSocket; 
int port = 8085;
ManagerConnection clientevent_manager = null;
ManagerConnection userevent_manager = null;
ManagerConnection send_manager = null;
private DefaultAsteriskServer clientevent_ast;
private DefaultAsteriskServer userevent_ast;
private DefaultAsteriskServer send_ast;

Hashtable <String, Hashtable>event_hash = new Hashtable<String, Hashtable>();
Hashtable <String, ClientServiceThread>cli_hash = new Hashtable<String, ClientServiceThread>();
Hashtable <String, String>part_hash = new Hashtable<String, String>();
Hashtable <String, String>peer_uid_hash = new Hashtable<String, String>();
Util util=new Util();
Connection conn = null;
int isleep = 10000;
boolean DEBUG = false;
boolean view_monit = false;
boolean auto_rest = true;
String domain = "";
     
public MsgServer(String d)  throws IOException
{ 
	//////////MANAGER 연결
	domain = d;

	try{

		//peer ini start
		Class.forName("org.gjt.mm.mysql.Driver");
		conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eicn","eicn","eicnrw");
		if(conn == null)
		{
			System.out.println("DB ERROR!!");
			return;
		}
                Connection conn_web = null;
                if(domain != null && !domain.equals("localhost"))
                {
                        conn_web = DriverManager.getConnection("jdbc:mysql://WEB_VIP:3306/eicn","eicn","eicnrw");
                        if(conn_web == null)
                        {
                                System.out.println("WEB_VIP DB ERROR!!");
                                return;
                        }
                }
 
                PersonListDB pldb = new PersonListDB(conn);
                PersonListDB pldb_web = null;
                if(conn_web != null)
                {
                        pldb_web = new PersonListDB(conn_web);
                }
                PersonListDM[] pldm = pldb.getByWhere("");
                if(pldm != null && pldm.length>0)
                {
                        for(int i=0; i<pldm.length ; i++)
                        {
                                pldm[i].setIsLoginMsg("");
                                pldb.updateLoginMsg(pldm[i]);
                                if(pldb_web != null)
                                {
                                        pldb_web.updateLoginMsg(pldm[i]);
                                }
                        }
                }
                if(conn_web != null)
                {
                        conn_web.close();
                }

		//파트 정보
		PhoneInfoDB pidb = new PhoneInfoDB(conn);
		PhoneInfoDM[] pidm = pidb.getByWhere("where part_group!=0 ");
		if(pidm != null && pidm.length>0)
		{
			for(int i=0; i<pidm.length ; i++)
			{
				String extension = pidm[i].getExtension();
				int part = pidm[i].getPartGroup();
				part_hash.put(extension,String.valueOf(part));
			}
		}

try{

		//EventServer로 부터 받을
                clientevent_ast = new DefaultAsteriskServer("127.0.0.1","clientevent_manager","ippbx@IX");
                clientevent_ast.initialize();
                clientevent_manager = clientevent_ast.getManagerConnection();
                clientevent_manager.registerUserEventClass(EICNClientEvent.class);
                clientevent_ast.getManagerConnection().addEventListener(this);
}catch(Exception ae){
	System.out.println("1."+ae.getMessage());
}

try{
		//어드민에게 보낼....
                userevent_ast = new DefaultAsteriskServer("127.0.0.1","userevent_manager","ippbx@IX");
                userevent_ast.initialize();
                userevent_manager = userevent_ast.getManagerConnection();
		userevent_manager.registerUserEventClass(EICNClientEvent.class);
}catch(Exception ae){
	System.out.println("2."+ae.getMessage());
}

try{
		//ASTERRISK 한테 보낼...
                send_ast = new DefaultAsteriskServer("127.0.0.1","send_manager","ippbx@IX");
                send_ast.initialize();
                send_manager = send_ast.getManagerConnection();
}catch(Exception ae){
	System.out.println("3."+ae.getMessage());
}

 
try{
                Runtime.getRuntime().addShutdownHook(new Thread()
                {
                        public void run()
                        {
                                clientevent_ast.shutdown();
                        }
                }
                );
}catch(Exception ae){
	System.out.println("4."+ae.getMessage());
}

		MasterLoop loopThread = new MasterLoop(this);
		loopThread.start();


	} catch(Exception e) {
		System.out.println("7"+e.getMessage());
	}



	//////////소켓 연결
	try 
	{ 
		serverSocket = new ServerSocket(port, 100); 
	} 
	catch(IOException ioe) 
	{ 
		System.out.println("MAIN> Could not create server socket at "+port+". Quitting."); 
		System.exit(-1); 
	} 
         
	System.out.println("MAIN> Listening for clients on "+port+"..."); 
         
	int id = 0; 
	while(true) 
	{                         
		try 
		{ 
			Socket clientSocket = serverSocket.accept(); 
			System.out.println("ADDRESS:"+clientSocket.getInetAddress());
            
			ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++, this); 
			cliThread.start(); 
		} 
		catch(IOException ioe) 
		{ 
			System.out.println("MAIN> Exception encountered on accept. Ignoring. Stack Trace :"); 
			ioe.printStackTrace(); 
		} 
	} 
} 

public void CheckConn()
{
        //System.out.println("CheckConn111");
        try{
        if(conn.isClosed() == true)
        {
        System.out.println("CheckConn222");
                Class.forName("org.gjt.mm.mysql.Driver");
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eicn","eicn","eicnrw");
        System.out.println("CheckConn333");
        }
        }catch (Exception e) {
                System.out.println("CheckConn:"+e.getMessage());
        }
}

//로그아웃을 위한 작업들
public void SetLogout(String userid, String phoneid)
{
        Connection connection = null;
        try{
                Class.forName("org.gjt.mm.mysql.Driver");
                if(domain != null && domain.equals("localhost"))
                {
                        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/eicn","eicn","eicnrw");
                } else {
                        connection = DriverManager.getConnection("jdbc:mysql://WEB_VIP:3306/eicn","eicn","eicnrw");
                }
        }catch (Exception e) {
                System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):SetLogout:"+e.getMessage());
                return;
        }
        try{
                CheckConn();
                PersonListDB pldb = new PersonListDB(conn);
                PersonListDB pldb_web = new PersonListDB(connection);
                PersonListDM[] pldm = null;
                try{
                        pldm = pldb.getByWhere("where id='"+userid+"'");
                } catch(Exception e20){
                        pldm = pldb.getByWhere("where id='"+userid+"'");
                        System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_20 "+e20.getMessage());
                }
                if(pldm != null && pldm.length>0)
                {
                        pldm[0].setIsLoginMsg("");
                        try{
                                pldb.updateLoginMsg(pldm[0]);
                        } catch(Exception e21){
                                System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_21 "+e21.getMessage());
                        }
                        try{
                        pldb_web.updateLoginMsg(pldm[0]);
                        } catch(Exception e22){
                                System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_22 "+e22.getMessage());
                        }
                        System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):setIsLogin of person_list");
                }
        }
        catch(Exception e2)
        {
                System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_2 "+e2.getMessage());
        }
        if(connection != null)
        {
                try{
                connection.close();
                }
                catch(Exception e3)
                {
                        System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_3 "+e3.getMessage());
                }
        }
}


public void onManagerEvent(ManagerEvent event)
{
	//System.out.println("event------------------------------------");
	//System.out.println(">>> " + event);
	String[] properties = getPropertyNames(event);
	Hashtable values = null;
	if(properties != null && properties.length>0)
	{
		values = getPropertyValues(event, properties);
		if(values != null && values.size()>1)
		{
	//System.out.println("event------------------------------------");
	//System.out.println(">>> " + event);
			executeAction(values);
		}
	}
}
 
protected Hashtable getPropertyValues(Object obj, String[] property)
{
	Hashtable<String, String> values = new Hashtable<String, String>(property.length+1);
	values.put("EVENTNAME",obj.getClass().getSimpleName());
	//System.out.println("\tEVENTNAME:"+obj.getClass().getSimpleName());
	try
	{
	for(int i=0 ; i<property.length ; i++)
	{
		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
		for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
		{
		//System.out.println("\t**"+propertyDescriptor.getName());
			if(propertyDescriptor.getName() == null || (propertyDescriptor.getName() != null && !(propertyDescriptor.getName()).toLowerCase().equals(property[i])))
			{
				continue;
			}
			if(propertyDescriptor.getReadMethod() == null)
			{
				break;
			}
			if(propertyDescriptor.getReadMethod().invoke(obj) == null)
			{
				break;
			}
			String vv = (propertyDescriptor.getReadMethod().invoke(obj).toString()).toLowerCase();
				//System.out.println("\t\t"+property[i]+":"+vv);
			values.put(property[i], vv);
			break;
		}
	}
	return values;
	}
	catch (Exception e)
	{
		System.err.println("Unable to read property '" + property + "' from object " + obj + ": " + e.getMessage());
		return null;
	}
}
 
protected String[] getPropertyNames(ManagerEvent event)
{
	String[] properties = null;

//System.out.println(event);
try{
        if (event instanceof EICNClientEvent)
        {
                properties = new String[]{"optionname1", "optionname2", "phonename", "eventstr"};
        }
} catch(Exception e) {
	System.out.println("ERROR:"+e.getMessage());
	return null;
}
	return properties;
}
 
public void executeAction(Hashtable hash)
{
try{
	if(hash == null || hash.size()<2)
		return;
	String eventname = (String)hash.get("EVENTNAME");
        if(eventname.equals("EICNClientEvent")) {
                String option1 = (String)hash.get("optionname1");
                String option2 = (String)hash.get("optionname2");
                String eve = (String)hash.get("eventstr");
                String phoneid = (String)hash.get("phonename");
 
                if(option1 != null && eve != null )
                {
                        if(option2 == null)
                        {
                                option2 = "";
                        }
                        eve = eve.toUpperCase();
                        option1 = option1.toUpperCase();
                        option2 = option2.toUpperCase();
 
                        if(option1.equals("PER"))
                        {
				if(option2.equals("SET_MEMBERSTATUS"))
				{
				} else {
				}
                        } else {
				if(eve.startsWith("MEMBERSTATUS") && option2.startsWith("P_"))
				{
					MulticastBranchPeer(option2.replace("P_",""),eve);
				}
			}
                }
        }
} catch(Exception e) {
	System.out.println("ERROR:"+e.getMessage());
}
}
public boolean SendMessage(String mypeer, String outstr) 
{
/*
	if(peer_uid_hash == null || peer_uid_hash.size()==0)
	{
		return false;
	}
	String uid = (String)peer_hash.get(mypeer);
*/
	if(mypeer == null || mypeer.equals(""))
	{
		return false;
	}
	ClientServiceThread cli_thread = null;
	cli_thread = (ClientServiceThread)cli_hash.get(mypeer);
	if(cli_thread != null)
	{
		cli_thread.writeMessage(outstr);
	} else {
		System.out.println("RETURN_FALSE:NO_LOGIN_"+mypeer);
		return false;
	}
	return true;
}
public void MulticastBranchPeer(String peer, String outstr)
{
        //for (Enumeration e = cli_hash.keys() ; e.hasMoreElements() ;)
        //{
		try{
                //String peer = (String)e.nextElement();
                ClientServiceThread cli_thread = (ClientServiceThread)cli_hash.get(peer);
                if(cli_thread != null)
                {
			//if(peer.equals(cli_thread.getPeer()))
			//{
                        	MulticastBranch(cli_thread.getCompanyId(), cli_thread.getAreaCode(), cli_thread.getBranchCode(), peer, outstr);	
			//	break;
			//} 
                 }
		}catch(Exception ex){
                	System.out.println("["+UtilDate.getDateTime()+"] ERROR MulticastBranch");
			System.out.println(ex.getMessage());
		}
        //}
}
public void MulticastBranch(String company_id, String area,  String branch, String mypeer, String outstr)
{
        for (Enumeration e = cli_hash.keys() ; e.hasMoreElements() ;)
        {
		try{
                String peer = (String)e.nextElement();
/*OJKIM 20120612 자기것도 보이게 처리
		if(peer != null && peer.equals(mypeer))
		{
			continue;
		}
*/
                if(peer == null)
                {
                        continue;
                }
                ClientServiceThread cli_thread = (ClientServiceThread)cli_hash.get(peer);
                if(cli_thread != null)
                {
			if(company_id.equals(cli_thread.getCompanyId()))
			{
System.out.println("MulticastBranch:"+cli_thread.getUserId()+":"+outstr);
                         cli_thread.writeMessage(outstr);
			} 
                 }
		}catch(Exception ex){
                	System.out.println("["+UtilDate.getDateTime()+"] ERROR MulticastBranch");
			System.out.println(ex.getMessage());
		}
        }
}
public void AdminSendMessage(String op1, String op2, String outstr) 
{
	//System.out.println("EICNClientEvent:"+outstr);
	EICNClientEvent eicnevent = new EICNClientEvent("EICNClient|optionName1: "+op1);
	eicnevent.setOptionName1(op1);
	eicnevent.setOptionName2(op2);
	eicnevent.setEventStr(outstr);
	eicnevent.setPhoneName("ADM");
	UserEventAction ue_act = new UserEventAction(eicnevent);
	try{
               	ManagerResponse response = userevent_manager.sendAction(ue_act);
		//System.out.println("RES:"+response.getResponse());      
	} catch(Exception e) {
		//System.out.println("EICNClientEvent:"+e.getMessage());
	}
}
public void AddMember(ClientServiceThread cli) 
{
if(DEBUG)
{
	System.out.println("-----------------AddThread:"+cli.phoneid);
}
	String peer = cli.getPeer();
	String pid = cli.getPhoneId();
	String uid = cli.getUserId();
	int paused = cli.getPaused();
	String uname = cli.getUserName();
	String company_id = cli.getCompanyId();
	String area = cli.getAreaCode();
	String branch = cli.getBranchCode();

	ClientServiceThread cli_thread = (ClientServiceThread)cli_hash.get(peer);
	if(cli_thread != null)
	{
System.out.println("["+UtilDate.getDateTime()+"] 다른사람이 밀고 들어옴:"+uid);
		String outstr="Bye";
		cli_thread.writeMessage(outstr);
                cli_thread.setRunThread(false);
		cli_hash.remove(peer);
	}
	
	//String rm_uid = (String)peer_uid_hash.get(pid);
	if(peer != null)
	{
		ClientServiceThread rm_thread = (ClientServiceThread)cli_hash.get(peer);
		if(rm_thread != null)
		{
			String outstr="Bye";
			rm_thread.writeMessage(outstr);
	                rm_thread.setRunThread(false);
			cli_hash.remove(peer);
		}
		peer_uid_hash.remove(peer);
	}
	cli_hash.put(peer, cli);
	peer_uid_hash.put(peer, uid);

	//Branch 구성원에게 알림
	String outstr="MSGLOGIN|KIND:LOGIN|DATA1:"+uid+"|DATA2:"+pid+"|DATA3:"+peer+"|DATA4:"+uname+"|DATA5:"+paused;
	MulticastBranch(company_id,area, branch, peer, outstr);
}
public static void main (String[] args) 
{ 
        String tmp_domain="PBX1";
        if(args.length == 1)
        {
                tmp_domain = args[0];
        }
	try{
	new MsgServer(tmp_domain);     
	} catch (Exception e) {
	}
} 
     
/*****************************************/
/*       ClientServiceThread CLASS       */
/*****************************************/
class ClientServiceThread extends Thread 
{ 
	Socket clientSocket;         
	int clientID = -1; 
	boolean bRunThread = false; 
	MsgServer server;
	int paused=0;
	String phoneid="";
	String peer="";
	String userid="";
	String user_name="";
	String company_id="";
	String area_code="";
	String branch_code="";
	String part_code="";
	int logout_status=9;
	int dial_status=2;
	boolean fEnc = false;
	boolean fLogin = false;
	BufferedReader in = null;  
	PrintWriter out = null; 
	Hashtable <String, String>branch_peer_hash = null;
	Connection conn_cli = null;
	Connection conn_web = null;
         
	ClientServiceThread(Socket s, int clientID, MsgServer server) 
	{ 
		System.out.println("MAIN> ClientServiceThread "+ clientID);
		this.clientSocket = s; 
		this.clientID = clientID; 
		this.server = server; 
	} 

	public String getUserName() 
	{             
		return user_name;
	}
	public int getPaused() 
	{             
		return paused;
	}
	public String getPeer() 
	{             
		return peer;
	}
	public String getUserId() 
	{             
		return userid;
	}
	public String getCompanyId() 
	{             
		return company_id;
	}
	public String getAreaCode() 
	{             
		return area_code;
	}
	public String getBranchCode() 
	{             
		return branch_code;
	}
	public String getPartCode() 
	{             
		return part_code;
	}
	public String getPhoneId() 
	{             
		return phoneid;
	}
	public boolean getEnc() 
	{             
		return fEnc;
	}
	public PrintWriter getWriter() 
	{             
		return out;
	}

        public void writeMessage(String outstr)
        {
		try{
                if(clientSocket.isConnected() == false)
                {
                	System.out.println("["+UtilDate.getDateTime()+"]"+"SOCKET_ERROR("+phoneid+"-"+userid+"):clientSocket.isConnected=false");
			setRunThread(false);
                        //bRunThread = false;
                        return;
                }

                if(fEnc == false)
                {
                        out.println(outstr);
                } else {
                        out.println(util.EncodeStr(outstr));
                }
                out.flush();

                System.out.println("["+UtilDate.getDateTime()+"]"+"***WRITEMESSAGE("+phoneid+"-"+userid+"):"+outstr);
		} catch (Exception e) {
                System.out.println("["+UtilDate.getDateTime()+"] ERROR WRITEMESSAGE");
                System.out.println(e.getMessage());
		}
        }
        public void writeMessagePart(String outstr)
        {
		try{
                if(clientSocket.isConnected() == false)
                {
                        //bRunThread = false;
			setRunThread(false);
                        return;
                }

                if(fEnc == false)
                {
                        out.println(outstr);
                } else {
                        out.println(util.EncodeStr(outstr));
                }
                out.flush();
		} catch (Exception e) {
                System.out.println("["+UtilDate.getDateTime()+"] ERROR WRITEMESSAGE1");
                System.out.println(e.getMessage());
		}
        }
        
        public void getDBConnCliOnlyPBX(boolean fSel, String fromtag)
        {
                try{
                if(conn_cli == null || conn_cli.isClosed() == true)
                {
                        Class.forName("org.gjt.mm.mysql.Driver");
                        conn_cli = DriverManager.getConnection("jdbc:mysql://localhost:3306/eicn?autoReconnect=true","eicn","eicnrw");
                } else {
			if(fSel)
			{
				PersonListDB pldb = new PersonListDB(conn_cli);
				PersonListDM[] pldm = pldb.getByWhere("where id='"+userid+"'");
			}
		}
                }catch (Exception e) {
	                System.out.println("["+UtilDate.getDateTime()+"]getDBConnCliOnlyPBX("+fromtag+"):"+e.getMessage());
                }
	}
        public void getDBConnCliOnlyWEB(boolean fSel, String fromtag)
        {
                try{
                if(conn_web == null || conn_web.isClosed() == true)
                {
                        Class.forName("org.gjt.mm.mysql.Driver");
			if(domain != null && domain.equals("localhost"))
			{
                		conn_web = DriverManager.getConnection("jdbc:mysql://localhost:3306/eicn","eicn","eicnrw");
			} else {
                		conn_web = DriverManager.getConnection("jdbc:mysql://WEB_VIP:3306/eicn","eicn","eicnrw");
			}
                } else {
			if(fSel)
			{
				PersonListDB pldb = new PersonListDB(conn_web);
				PersonListDM[] pldm = pldb.getByWhere("where id='"+userid+"'");
			}
		}
                }catch (Exception e) {
			PrintLog("getDBConnCliOnlyWEB("+fromtag+")",e.toString()); 
                }
	}
        public void PrintLog(String from, String str)
        {
		System.out.println("["+UtilDate.getDateTime()+"]["+userid+"("+phoneid+")]["+from+"] "+str);
	}
        public void setRunThread(boolean flag)
        {
		bRunThread = flag; 
		if(flag == false)
		{
			try{
			clientSocket.close();
			}catch(Exception e){
			}
		}
        }
/*
	public boolean isYourBranch(String p) 
	{             
		if(branch_peer_hash == null || branch_peer_hash.size() == 0)
		{
			return false;
		}
		String tmp_peer = (String)branch_peer_hash.get(p);
		if(tmp_peer != null)
		{
			return true;
		}
		return false;
	}
*/
	public void run() 
	{             
		String response ="";
             
		System.out.println("MAIN> Accepted Client : ID - " + clientID + " : Address - " + clientSocket.getInetAddress().getHostName()); 
                 
		try 
		{                                 
			in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
			out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream())); 
                
			String clientCommand = in.readLine(); 
System.out.println("****ENC> "+clientCommand);

			fEnc = false;
			//String cmd = util.DecodeStr(clientCommand);
			String cmd = clientCommand;
System.out.println("****CMD> " + cmd);

			System.out.println("["+UtilDate.getDateTime()+"]"+"CLIENT> " + cmd); 
			CheckLogin(cmd, out, fEnc);
			
			while ((clientCommand = in.readLine()) != null && bRunThread == true) 
			{
System.out.println("****ENC> "+clientCommand);
				//cmd = util.DecodeStr(clientCommand);
				cmd = clientCommand;

				System.out.println("["+UtilDate.getDateTime()+"]"+"CLIENT> " + cmd); 
				if (cmd.equals("Bye."))
				{
					System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):BYE.... "); 
					break;
				}
				String [] arg=null;
				String inputs[]=cmd.split("\\|");                                
				int s=inputs.length;
				if(s > 2 && null != inputs[2] && !inputs[2].equals(""))
				{
					arg=inputs[2].split(",");                                    
				}

				if(inputs[0].equals("CMD") && null != inputs[1] && !inputs[1].equals(""))
				{
					if( inputs[1].equals("CLICKDIAL"))
					{
						if(phoneid == null || phoneid.equals(""))
						{
							continue;
						}
						String cid_num = arg[0];
						String custom_num = arg[1];
						CmdClickdial(cid_num, custom_num);
					}
					else if(inputs[1].equals("HANGUP"))
					{
						if(phoneid == null || phoneid.equals(""))
						{
							continue;
						}
                                                if(arg == null || arg[0] == null)
                                                {
							System.out.println("HANGUP RETURN1");
                                                        continue;
                                                }
						CmdHangup();

					}
					else if(inputs[1].equals("SENDMSG"))
					{
						if(arg == null || arg[0] == null)
						{
							continue;
						}
						String target_id = arg[0];
						String target_peer = arg[1];
						String msg = "MSG|KIND:RCV|DATA1:"+userid+"|DATA2:"+peer+"|DATA3:";
						for(int i=2 ; i<arg.length ; i++)
						{
							msg = msg+arg[i];
						}
						System.out.println(msg);
						
						boolean fSend = server.SendMessage(target_peer, msg);
						if(fSend == false)
						{
							String outstr = "MSG|KIND:SNDERR|DATA1:"+userid+"|DATA2:"+phoneid;
							writeMessage(outstr);
						}
					}
                                        else if(inputs[1].equals("PLAY_REC"))
                                        {
                                                if(arg.length != 1)
                                                {
                                                        continue;
                                                }
						CmdPlayrec(arg[0]);
					}
                                        else if(inputs[1].equals("ATTENDED"))
                                        {
                                                if(arg.length != 1)
                                                {
                                                        continue;
                                                }
						CmdAttended(arg[0]);
                                        }
                                        else if(inputs[1].equals("ATTENDED_SVC"))
                                        {
                                                if(arg.length != 1)
                                                {
                                                        continue;
                                                }
                                                CmdAttendedSVC(arg[0]);
                                        }
                                        else if(inputs[1].equals("PICKUP"))
                                        {
						CmdPickup();
                                        }
					else if(inputs[1].equals("REDIRECT_MEMBER"))
					{
						CmdRedirectmember();
					}
					else if(inputs[1].equals("REDIRECT"))
					{
System.out.println(inputs[1]+","+arg.length);
						if(phoneid == null || phoneid.equals(""))
						{
							continue;
						}
						if(arg == null || arg.length !=3)
						{
							continue;
						}
						try{
						EventListDB eldb = new EventListDB(conn_cli);
						EventListDM[] eldm = eldb.getByWhere("where myid='"+phoneid+"' or callee='"+phoneid+"'");
System.out.println("REDIRECT1:"+"where myid='"+phoneid+"' or callee='"+phoneid+"'");
						if(eldm == null|| eldm.length ==0)
						{
							writeMessage("CALLSTATUS|KIND:REDIRECT|DATA1:"+arg[2]+"|DATA2:NOCHAN");
							continue;
						}
						EventListDM[] eldm1 = eldb.getByWhere("where myid='"+arg[2]+"' or callee='"+arg[2]+"'");
System.out.println("REDIRECT2:"+"where myid='"+arg[2]+"' or callee='"+arg[2]+"'");
                                                if(eldm1 != null && eldm1.length>0)
                                                {
                                                        writeMessage("CALLSTATUS|KIND:REDIRECT|DATA1:"+arg[2]+"|DATA2:BUSY");
                                                        continue;
                                                }
						String chann = eldm[0].getChannel();
						String kind = eldm[0].getKind();
						String callee = eldm[0].getCallee();
						if(chann != null && !chann.equals(""))
						{
System.out.println("REDIRECT3:"+chann);
							chann = chann.replace("sip","SIP");
							AsteriskChannel aschann = send_ast.getChannelByName(chann);
System.out.println("REDIRECT4:"+aschann);
							if(aschann != null)
							{
								if(kind.equals("I") || callee.equals(phoneid))
								{
									aschann.redirect("xfercontext","*"+phoneid+arg[2],1);
								} else {
									AsteriskChannel dst_chan= aschann.getDialedChannel();
//System.out.println(dst_chan);
									if(dst_chan != null)
									{
										dst_chan.redirect("xfercontext","*"+phoneid+arg[2],1);
									}
								}
							} else {
								//writeMessage("CALLSTATUS|KIND:REDIRECT|DATA1:"+dest+"|DATA2:NOCHAN");
							}
						} else {
							//writeMessage("CALLSTATUS|KIND:REDIRECT|DATA1:"+dest+"|DATA2:NOCHAN");
						}
						} catch(Exception e){
							System.out.println(e.getMessage());
							continue;
						}
					}
                                        else if( inputs[1].equals("MEMBERQUEUE_INI"))
                                        {
                                                try{
                                                QueueNameDB qndb = new QueueNameDB(conn_cli);
                                                QueueNameDM[] qndm = qndb.getByWhere(" order by han_name asc");
                                                if(qndm != null && qndm.length>0)
                                                {
                                                        QueueMemberDB qmdb = new QueueMemberDB(conn_cli);
                                                        for(int i=0; i<qndm.length ; i++)
                                                        {
                                                                int cnt = qndm[i].getCnt();
                                                                String number = qndm[i].getNumber();
                                                                String han_name = qndm[i].getHanName();
                                                                String q_name = qndm[i].getName();
                                                                QueueMemberDM[] qmdm = qmdb.getByWhere("where queue_name='"+q_name+"'");
                                                                if(qmdm != null && qmdm.length>0)
                                                                {
 
                                                                String outstr="MEMBERQUEUEINI|KIND:QUEUE|DATA1:"+q_name+"|DATA2:"+han_name+"|DATA3:"+qmdm.length+"|DATA4:"+cnt;
                                                                writeMessage(outstr);
                                                                }
                                                        }
                                                }
 
                                                } catch (Exception e){
                                                        System.out.println(e.getMessage());
                                                }
                                        }
					else if( inputs[1].equals("PART_INI"))
                                        {
						PersonListDM[] pldm = null;
						PersonListDB pldb = null;
						try{

							pldb = new PersonListDB(conn_cli);
							pldm = pldb.getByWhere(" where id!='"+userid+"' and part_group="+part_code );
							for(int i=0; i<pldm.length ; i++)
							{
                                                        	String outstr="PART_MEMBER|KIND:"+pldm.length+"|DATA1:"+pldm[i].getExtension()+"|DATA2:"+pldm[i].getIdName();
                                                        	writeMessage(outstr);
							}
						} catch (Exception e) {
							continue;
						}
					}
                                        else if( inputs[1].equals("MEMBERSTATUS_INI"))
                                        {
						PersonListDM[] pldm = null;
						PersonListDB pldb = null;
						try{
							pldb = new PersonListDB(conn_cli);
							pldm = pldb.getByWhere(" where id!='"+userid+"' and part_group="+part_code);
						} catch (Exception e) {
							continue;
						}
						if(pldm == null || pldm.length == 0)
						{
							continue;
						}
						QueueMemberDB qmdb = new QueueMemberDB(conn_cli);
						for(int i=0 ; i<pldm.length ; i++)
						{
							String member = pldm[i].getExtension();
							QueueMemberDM[] qmdm = qmdb.getByWhere("where membername='"+member+"' and queue_name=''");
							if(qmdm != null && qmdm.length > 0)
							{
                						String a_outstr = "ADMMEMBERSTATUS|KIND:MEMBERSTATUS|DATA1:"+member+"|DATA2:"+qmdm[0].getPaused();
								writeMessage(a_outstr);
							}
						}
					}
					else if( inputs[1].equals("EVENT_INI"))
                                        {
						EventListDM[] eldm = null;
						EventListDB eldb = null;
						try{
							eldb = new EventListDB(conn_cli);
							eldm = eldb.getByWhere("");
						} catch (Exception e) {
							continue;
						}
						if(eldm == null || eldm.length == 0)
						{
							continue;
						}
						for(int i=0 ; i<eldm.length ; i++)
						{
							String myid = eldm[i].getMyId();
							String kind = eldm[i].getKind();
							String type = eldm[i].getType();
							String callee = eldm[i].getCallee();
							String caller = eldm[i].getCaller();
							String send = eldm[i].getSend();
							String ini_num = eldm[i].getIniNum();
							String ivr_key = eldm[i].getIvrKey();
							String timestr = eldm[i].getUpdateDate();
							timestr = timestr.substring(11,19);
	
							String option = kind+type;

							String outstr="";
							if(type != null && type.equals("P"))
							{
								outstr="ADMCALLEVENT|KIND:ID|DATA1:"+caller+"|DATA2:"+callee+"|DATA3:"+ini_num+"|DATA4:"+ivr_key+"|DATA5:|DATA6:"+timestr;
							} else {
								outstr="ADMCALLEVENT|KIND:"+option+"|DATA1:"+caller+"|DATA2:"+callee+"|DATA3:"+ini_num+"|DATA4:"+ivr_key+"|DATA5:|DATA6:"+timestr;
							}

							//파트원들의 정보보냄
							String partstr = "";
							if(part_hash != null && part_hash.size()>0)
							{
								partstr = (String)part_hash.get(myid);
								if(partstr != null && partstr.equals(part_code))
								{
                                                			writeMessage(outstr);
								}
							}
						}

                                        }
                                        else if( inputs[1].equals("DTMFCONTROL"))
                                        {
System.out.println("["+UtilDate.getDateTime()+"] DTMFCONTROL("+phoneid+")"+cmd);
						if(arg[0] == null || arg[0].equals(""))
						{
							continue;
						}
						EventListDM[] eldm = null;
						EventListDB eldb = null;
						try{
							eldb = new EventListDB(conn_cli);
							eldm = eldb.getByWhere("where myid='"+phoneid+"' and type='D' limit 1");
							if(eldm == null || eldm.length == 0)
							{
								continue;
							}
							eldm[0].setDtmfStart(arg[0]);
							eldb.update(eldm[0]);
						} catch (Exception e) {
							continue;
						}
                                        }
                                        else if( inputs[1].equals("GET_RECORD_URL"))
                                        {
						if(arg[0] == null || arg[0].equals(""))
						{
							writeMessage("RECORD_URL|KIND:WRONG_ARG|DATA1:");
							continue;
						}
						String uniq = arg[0];
						String domain = "";
						String domain_ip = "";
						String uniqueid = "";
						EicnCDRDM[] cdrdm=null;
						UtilDate ud = new UtilDate();
						String today = ud.getDateStr(0);
						String rec_ip = "61.34.203.46";
						if(uniq.startsWith("PBX"))
						{
							String infos[]=uniq.split("_");
							if(infos.length == 2)
							{
							        domain = infos[0];
							        uniqueid = infos[1];
							
							        EicnCDRDB cdrdb = new EicnCDRDB(conn_web);
							        cdrdm = cdrdb.getByWhere("where domain='"+domain+"' and uniqueid='"+uniqueid+"'");
							
							        PbxInfoDB pidb = new PbxInfoDB(conn_web);
							        PbxInfoDM[] pidm = pidb.getByWhere("where domain='"+domain+"'");
							        if(pidm != null && pidm.length>0)
							        {
							                domain_ip = pidm[0].getIp();
							        }
							}
						} else {
							domain = "OLD_REC";
							String domain1 = "PBX2";

							EicnCDRDB cdrdb = new EicnCDRDB(conn_web);
							cdrdm = cdrdb.getByWhere("where domain='OLD_REC' and uniqueid='"+uniq+"'");
System.out.println("where domain='OLD_REC' and uniqueid='"+uniq+"'");
 
							PbxInfoDB pidb = new PbxInfoDB(conn_web);
							PbxInfoDM[] pidm = pidb.getByWhere("where domain='"+domain1+"'");
							if(pidm != null && pidm.length>0)
							{
								domain_ip = pidm[0].getIp();
							}
						}
						if(cdrdm != null && cdrdm.length>0)
					        {
					                for(int i=0; i<cdrdm.length ; i++)
					                {
						                String ippbx = "";
						                String doc_path = "";
						                String file_name = "";
						                boolean is_today = false;
						                String userid = cdrdm[i].getUserId();
						                String userfield = cdrdm[i].getRecordFile();
						                String l_domain = cdrdm[i].getHost();
						                String ring_date = cdrdm[i].getRingDate();
						                String t_date = cdrdm[i].getRingDate();
						                if(t_date.startsWith(today))
						                {
						                        is_today = true;
						                }
						                if(userfield != null && !userfield.equals(""))
						                {
						                        String userf[]=userfield.split("/");
						                        if(userf.length>3)
						                        {
						                                ippbx = userf[2];
						                                for(int m=1 ; m < userf.length-1 ; m++)
						                                {
						                                        if(m ==0)
						                                        {
						                                                doc_path = "/"+userf[m];
						                                        } else {
						                                                doc_path = doc_path+"/"+userf[m];
						                                        }
						                                }
						                                file_name=userf[userf.length-1];
						                                if(is_today)
						                                {
						                                        userfield = "http://"+domain_ip+"/"+userfield;
						                                } else {
						                                        userfield = "http://"+rec_ip+"/"+domain+userfield;
						                                }
										System.out.println(userfield);
										writeMessage("RECORD_URL|KIND:REC_OK|DATA1:"+uniq+"|DATA2:"+userfield);
						                        }
						                } else {
								writeMessage("RECORD_URL|KIND:NO_REC_INFO|DATA1:"+uniq);
								}

							}
						
                                        	} else {
						writeMessage("RECORD_URL|KIND:NO_RECORD|DATA1:"+uniq);
						}
                                        }//GET_RECORD_URL
                                        else if(inputs[1].equals("GET_BILLSEC"))
                                        {
System.out.println("GET_BILLSEC-->"+arg[0]);
						if(arg[0] == null || arg[0].equals(""))
						{
							continue;
						}
						String uniq = arg[0];
						String domain = "";
						if(uniq.startsWith("PBX"))
						{
							String uniqueid = "";
							String infos[]=uniq.split("_");
							if(infos != null && infos.length == 2)
							{
							        domain = infos[0];
							        uniqueid = infos[1];
							
							        CurrentEicnCDRDB c_cdrdb = new CurrentEicnCDRDB(conn_cli);
							        EicnCDRDM[] c_cdrdm = c_cdrdb.getByWhere("where domain='"+domain+"' and uniqueid='"+uniqueid+"'");
								if(c_cdrdm != null && c_cdrdm.length>0)
								{
									writeMessage("GET_BILLSEC|KIND:"+uniq+"|DATA1:"+c_cdrdm[0].getBillSec());
								} else {
							        	EicnCDRDB cdrdb = new EicnCDRDB(conn_web);
							        	EicnCDRDM[] cdrdm = cdrdb.getByWhere("where domain='"+domain+"' and uniqueid='"+uniqueid+"'");
									if(cdrdm != null && cdrdm.length>0)
									{
										writeMessage("GET_BILLSEC|KIND:"+uniq+"|DATA1:"+cdrdm[0].getBillSec());
									} else {
										writeMessage("GET_BILLSEC|KIND:"+uniq+"|DATA1:0");
									}
							
							        }
							} else {
								writeMessage("GET_BILLSEC|KIND:"+uniq+"|DATA1:0");
							}
						} else {
							domain = "OLD_REC";

							EicnCDRDB cdrdb = new EicnCDRDB(conn_web);
							EicnCDRDM[] cdrdm = cdrdb.getByWhere("where domain='OLD_REC' and uniqueid='"+uniq+"'");
							if(cdrdm != null && cdrdm.length>0)
							{
								writeMessage("GET_BILLSEC|KIND:"+uniq+"|DATA1:"+cdrdm[0].getBillSec());
							} else {
								writeMessage("GET_BILLSEC|KIND:"+uniq+"|DATA1:0");
							}
						}
                                        }
				}
			}
		} 
		catch(Exception e) 
		{ 
			System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION111 "+e.toString()); 
			System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):IS_CONNECTED "+clientSocket.isConnected()); 
		} 
		finally 
		{ 
System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):CONNECTION CLOSED"); 
			try 
			{  
				try 
				{ 
					in.close(); 
					out.close(); 
				} catch (Exception e0) {
					System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_0 "+e0.getMessage()); 
				}
				server.SetLogout(userid, phoneid);
				String outstr="MSGLOGIN|KIND:LOGOUT|DATA1:"+userid+"|DATA2:"+phoneid+"|DATA3:"+peer+"|DATA4:"+user_name+"|DATA5:"+paused;
				MulticastBranch(company_id,area_code, branch_code, peer, outstr);
				//해쉬에서 쓰레드를 리무브함
				ClientServiceThread cli_thread = (ClientServiceThread)cli_hash.get(peer);
				if(cli_thread == this)
				{
                                       	cli_hash.remove(peer);
					System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):Remove Thread from hash..."); 
				}
				conn_cli.close(); 
				conn_web.close(); 
				clientSocket.close(); 
System.out.println("["+UtilDate.getDateTime()+"]***WRITEMESSAGE("+phoneid+"-"+userid+"):LOGIN|LOGOUT|"+phoneid); 
			} 
			catch(Exception ioe) 
			{ 
				System.out.println("["+UtilDate.getDateTime()+"]("+phoneid+"-"+userid+"):EXCEPTION_FINAL "+ioe.getMessage()); 
			} 
		} 
	} 

//******************************
//CLIENT 에서 전달되는 CMD 처리
//******************************

//--CMD|CLICKDIAL|${CID},${CUSTOM_NUM},${CONTEXT}
//--전화걸기 
public void CmdClickdial(String cid_num, String custom_num) 
{
	if(cid_num != null && !cid_num.equals(""))
	{
		cid_num = cid_num.replace("-","");
		cid_num = cid_num.replace(")","");
		cid_num = cid_num.replace("(","");
		cid_num = cid_num.replace(" ","");
		cid_num = cid_num.replace("null","");
	}
	if(custom_num != null && !custom_num.equals(""))
	{
		custom_num = custom_num.replace("-","");
		custom_num = custom_num.replace(")","");
		custom_num = custom_num.replace(" ","");
	}
	OriginateAction ori_act=new OriginateAction();
	String myid=phoneid;
	ori_act.setAccount(phoneid);
	ori_act.setCallerId("\""+phoneid+"\" <0000>");
	ori_act.setChannel("SIP/"+phoneid);
	ori_act.setVariable("CUSTOM_CID", cid_num);
	ori_act.setExten(custom_num);
	ori_act.setContext("outbound");
	ori_act.setPriority(1);
	ori_act.setAsync(true);
	try{
		send_manager.sendAction(ori_act);
	}catch(Exception ae){
		PrintLog("CmdClickdial_1", ae.toString());
	}
}

//--CMD|HANGUP|${내선}
//--내선의 채널을 행업시킴
public void CmdHangup() 
{
	EventListDM[] eldm = null;
	EventListDB eldb = null;
	String wherestr = "where myid='"+phoneid+"' or callee='"+phoneid+"' or ini_num='"+phoneid+"' order by update_date asc ";
	try{
		eldb = new EventListDB(conn_cli);
		eldm = eldb.getByWhere(wherestr);
	} catch (SQLException se) {
		getDBConnCliOnlyPBX(true,"CmdHangup");
		try{
              		eldb = new EventListDB(conn_cli);
			eldm = eldb.getByWhere(wherestr);
		} catch(SQLException se1) {
			PrintLog("CmdHangup_1", se1.toString());
		}
	}
	if(eldm == null || eldm.length ==0)
	{
		PrintLog("CmdHangup_2", "HANGUP RETURN2");
		return;
	}
	try{
		String chann = eldm[0].getChannel();
		String dst_chann = eldm[0].getDstChannel();
		if(eldm.length == 2)//돌려주기
		{
			chann = dst_chann;
		}
		if(chann != null && !chann.equals(""))
		{
			chann = chann.replace("sip","SIP");
			AsteriskChannel aschann = send_ast.getChannelByName(chann);
			if(aschann != null)
			{
				System.out.println("HANGUP OK");
				aschann.hangup();
			} else {
				System.out.println("HANGUP NOK");
				eldb.deleteByWhere("where seq="+eldm[0].getSeq());
			}
		}
	} catch (Exception e) {
		PrintLog("CmdHangup_3", e.toString());
	}
}

//--CMD|RECEIVE|${내선}
//--전화 받기
public void CmdRecieve() 
{
	EventListDM[] eldm = null;
	EventListDB eldb = null;
	String wherestr = "where type='R' and (myid='"+phoneid+"' or callee='"+phoneid+"')";
	try{
		eldb = new EventListDB(conn_cli);
		eldm = eldb.getByWhere(wherestr);
	} catch(SQLException se){
		getDBConnCliOnlyPBX(true,"CmdRecieve");
		try{
              		eldb = new EventListDB(conn_cli);
			eldm = eldb.getByWhere(wherestr);
		} catch(SQLException se1) {
			PrintLog("CmdRecieve_1", "EXCEPTION:"+se1.toString());
		}
	}

	if(eldm == null|| eldm.length ==0)
	{
		PrintLog("CmdRecieve_2", "RECEIVE RETURN");
		return;
	}

	String chann = eldm[0].getChannel();
	if(chann != null && !chann.equals(""))
	{
		try{
			if(chann.startsWith("sip"))
			{
				chann = chann.replace("sip","SIP");
			} else {
				chann = chann.replace("local","Local");
			}
			AsteriskChannel aschann = send_ast.getChannelByName(chann);
			if(aschann != null)
			{
				aschann.redirect("receive_context",phoneid,1);
			} else {
				PrintLog("CmdRecieve_3", "NOCHAN_2");
			}
		} catch(Exception ae) {
			PrintLog("CmdRecieve_4", "EXCEPTION:"+ae.toString());
		}
	} else {
		PrintLog("CmdRecieve_5", "NOCHAN");
	}
}

//--CMD|PLAY_REC|${UNIQUEID}
//--
public void CmdPlayrec(String uniqueid) 
{
	EventListDM[] eldm = null;
	EventListDB eldb = null;
	String wherestr = "where myid='"+phoneid+"' or callee='"+phoneid+"'";
	try{
		eldb = new EventListDB(conn_cli);
		eldm = eldb.getByWhere(wherestr);
	} catch(SQLException se){
		getDBConnCliOnlyPBX(true,"CmdPlayrec");
		try{
              		eldb = new EventListDB(conn_cli);
			eldm = eldb.getByWhere(wherestr);
		} catch(SQLException se1) {
			PrintLog("CmdPlayrec_1", "EXCEPTION:"+se1.toString());
		}
	}
	if(eldm == null || eldm.length == 0)
	{
	        writeMessage("CALLSTATUS|KIND:PLAY_REC|DATA1:"+phoneid+"|DATA2:NOCHAN");
	        return;
	}

	EicnCDRDB ecdb = null;
	EicnCDRDM[] ecdm = null;
	String wherestr1 = "where uniqueid='"+uniqueid+"'";
	try{
		ecdb = new EicnCDRDB(conn_web);
		ecdm = ecdb.getByWhere("where uniqueid='"+uniqueid+"'");
	} catch(SQLException se){
		getDBConnCliOnlyWEB(true,"CmdPlayrec");
		try{
			ecdb = new EicnCDRDB(conn_web);
			ecdm = ecdb.getByWhere("where uniqueid='"+uniqueid+"'");
		} catch(SQLException se1) {
			PrintLog("CmdPlayrec_2", "EXCEPTION:"+se1.toString());
		}
	}
	if(ecdm == null || ecdm.length == 0)
	{
	        writeMessage("CALLSTATUS|KIND:PLAY_REC|DATA1:"+phoneid+"|DATA2:NORECFILE1");
	        return;
	}
	String record_file = ecdm[0].getRecordFile();
	if(record_file == null || record_file.equals("") || record_file.length()<5)
	{
	        writeMessage("CALLSTATUS|KIND:PLAY_REC|DATA1:"+phoneid+"|DATA2:NORECFILE2");
	        return;
	}
	String kind = eldm[0].getKind();
	String chann = eldm[0].getDstChannel();
	String dstchann = eldm[0].getChannel();
	String caller = eldm[0].getCallee();
	String uniq = eldm[0].getUniqueId();
	if(kind != null && kind.equals("O"))
	{
	        chann = eldm[0].getChannel();
	        dstchann = eldm[0].getDstChannel();
	        caller = eldm[0].getCaller();
	        uniq = eldm[0].getDstUniqueId();
	}
	uniq= uniq.replace(".","_");

	String file_type = record_file.substring(record_file.length()-3);
	File sourceFile = new File( record_file );
	String filename = "";
	String userf[]=record_file.split("/");
	if(userf != null && userf.length>3)
	{
		filename = userf[userf.length-1];
	}
	if(!sourceFile.exists())
	{
		//로컬에 없을경우 녹취서버에서 가지고 온다
		String domain = ecdm[0].getHost();
		String remote = "";
		if(domain != null && domain.equals("OLD_REC"))
		{
			remote = "/PBX2/OLD_REC"+record_file;
		} else {
			remote = "/"+domain+record_file;
		}
		try{
			Process process = Runtime.getRuntime().exec("/home/ippbxmng/lib/wget_recfile.sh wget "+remote+" "+filename+" "+uniq+"."+file_type);
		} catch(Exception e) {
        		writeMessage("CALLSTATUS|KIND:PLAY_REC|DATA1:"+phoneid+"|DATA2:NOFILE");
			PrintLog("CmdPlayrec_4", "EXCEPTION:"+e.toString());
			return;
		}
	} else {
		try{
			Process process = Runtime.getRuntime().exec("/home/ippbxmng/lib/wget_recfile.sh cp "+record_file+" "+filename+" "+uniq+"."+file_type);
		} catch(Exception e) {
        		writeMessage("CALLSTATUS|KIND:PLAY_REC|DATA1:"+phoneid+"|DATA2:NOFILE");
			PrintLog("CmdPlayrec_5", "EXCEPTION:"+e.toString());
			return;
		}
	}
	
	
	if(chann != null && !chann.equals(""))
	{
	        try{
	        	chann = chann.replace("sip","SIP");
	        	dstchann = dstchann.replace("sip","SIP");
	        	AtxferAction act=new AtxferAction(chann,"","*1",1);
	        	ManagerResponse res= send_manager.sendAction(act,30000);
		}catch(Exception ae){
			PrintLog("CmdPlayrec_4", "EXCEPTION:"+ae.toString());
        	}
	} else {
        	writeMessage("CALLSTATUS|KIND:PLAY_REC|DATA1:"+phoneid+"|DATA2:NOCHAN");
	}
}

//--CMD|ATTENDED|${내선}
//--내선으로 돌려주기
public void CmdAttended(String target) 
{
        String target_peer = "";
 
        PhoneInfoDM[] pidm = null;
        PhoneInfoDB pidb = null;
        EicnCDRDM[] cdrdm = null;
        CurrentEicnCDRDB cdrdb = null;
        String wherestr = "";
        try{
                pidb = new PhoneInfoDB(conn_cli);
                pidm = pidb.getByWhere("where company_id='"+company_id+"' and extension='"+target+"'");
                if(pidm == null || pidm.length==0)
                {
                        writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+phoneid+"|DATA2:NOEXTEN");
                        return;
                }
                target_peer= pidm[0].getPeer();
 
                wherestr = "where callstatus='D' and (peer='"+peer+"' or (company_id='"+company_id+"' and (src='"+phoneid+"' or dst='"+phoneid+"')))";
System.out.println(wherestr);
                cdrdb = new CurrentEicnCDRDB(conn_cli);
                cdrdm = cdrdb.getByWhere(wherestr);
        } catch(SQLException se){
                getDBConnCliOnlyPBX(true,"CmdPlayrec");
                try{
                        cdrdb = new CurrentEicnCDRDB(conn_cli);
                        cdrdm = cdrdb.getByWhere(wherestr);
                } catch(SQLException se1) {
                        PrintLog("CmdAttended_1", "EXCEPTION:"+se1.toString());
                }
        }
        if(cdrdm == null || cdrdm.length == 0)
        {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+phoneid+"|DATA2:NOCHAN");
                return;
        }
        EicnCDRDM[] cdrdm1 = null;
        try{
                cdrdm1 = cdrdb.getByWhere("where company_id='"+company_id+"' and (src='"+target+"' or dst='"+target+"')");
        } catch(SQLException se){
                PrintLog("CmdAttended_1", "EXCEPTION:"+se.toString());
                return;
        }
        if(cdrdm1 != null && cdrdm1.length>0)
        {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+target+"|DATA2:BUSY");
                return;
        }
        String in_out = cdrdm[0].getInout();
        String chann = cdrdm[0].getDstChannel();
        String caller = cdrdm[0].getSrc();
        String in_out1 = "1";
        if(in_out != null && in_out.equals("O"))
        {
                chann = cdrdm[0].getChannel();
                caller = cdrdm[0].getDst();
                in_out1 = "0";
        }
        if(chann != null && !chann.equals(""))
        {
                try{
                        chann = chann.replace("sip","SIP");
                        String attended_xfer = "*2"+in_out1+target_peer+peer+caller+"#";
                        AtxferAction act=new AtxferAction(chann,"atxfercontext",attended_xfer,1);
                        send_manager.sendAction(act);
                }catch(Exception ae){
                        PrintLog("CmdAttended_2", "EXCEPTION:"+ae.toString());
                }
 
        } else {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1::"+phoneid+"|DATA2:NOCHAN");
        }
}
/*
//--CMD|ATTENDED|${내선}
//--내선으로 돌려주기
public void CmdAttended(String target) 
{
        String target_peer = "";
 
        PhoneInfoDM[] pidm = null;
        PhoneInfoDB pidb = null;
        EicnCDRDM[] cdrdm = null;
        CurrentEicnCDRDB cdrdb = null;
        String wherestr = "";
        try{
                pidb = new PhoneInfoDB(conn_cli);
                pidm = pidb.getByWhere("where company_id='"+company_id+"' and extension='"+target+"'");
                if(pidm == null || pidm.length==0)
                {
                        writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+phoneid+"|DATA2:NOEXTEN");
                        return;
                }
                target_peer= pidm[0].getPeer();
 
                wherestr = "where callstatus='D' and (peer='"+peer+"' or (company_id='"+company_id+"' and (src='"+phoneid+"' or dst='"+phoneid+"')))";
System.out.println(wherestr);
                cdrdb = new CurrentEicnCDRDB(conn_cli);
                cdrdm = cdrdb.getByWhere(wherestr);
        } catch(SQLException se){
                getDBConnCliOnlyPBX(true,"CmdPlayrec");
                try{
                        cdrdb = new CurrentEicnCDRDB(conn_cli);
                        cdrdm = cdrdb.getByWhere(wherestr);
                } catch(SQLException se1) {
                        PrintLog("CmdAttended_1", "EXCEPTION:"+se1.toString());
                }
        }
        if(cdrdm == null || cdrdm.length == 0)
        {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+phoneid+"|DATA2:NOCHAN");
                return;
        }
        EicnCDRDM[] cdrdm1 = null;
        try{
                cdrdm1 = cdrdb.getByWhere("where company_id='"+company_id+"' and (src='"+target+"' or dst='"+target+"')");
        } catch(SQLException se){
                PrintLog("CmdAttended_1", "EXCEPTION:"+se.toString());
                return;
        }
        if(cdrdm1 != null && cdrdm1.length>0)
        {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+target+"|DATA2:BUSY");
                return;
        }
        String in_out = cdrdm[0].getInout();
        String chann = cdrdm[0].getDstChannel();
        String caller = cdrdm[0].getSrc();
        String in_out1 = "1";
        if(in_out != null && in_out.equals("O"))
        {
                chann = cdrdm[0].getChannel();
                caller = cdrdm[0].getDst();
                in_out1 = "0";
        }
        if(chann != null && !chann.equals(""))
        {
                try{
                        chann = chann.replace("sip","SIP");
                        String attended_xfer = "*2"+in_out1+target_peer+peer+caller+"#";
                        //String attended_xfer = in_out1+target_peer+peer+caller;
System.out.println(attended_xfer);
                        AtxferAction act=new AtxferAction(chann,"atxfercontext",attended_xfer,1);
                        //AtxferAction act=new AtxferAction(chann,"outbound",target,1);
                        send_manager.sendAction(act);
                }catch(Exception ae){
                        PrintLog("CmdAttended_2", "EXCEPTION:"+ae.toString());
                }
 
        } else {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1::"+phoneid+"|DATA2:NOCHAN");
        }
}
*/

//--CMD|ATTENDED_SVC|${내선}
//--내선으로 돌려주기
public void CmdAttendedSVC(String target)
{
        String target_peer = "";
 
        PhoneInfoDM[] pidm = null;
        PhoneInfoDB pidb = null;
        EicnCDRDM[] cdrdm = null;
        CurrentEicnCDRDB cdrdb = null;
        String wherestr = "";
        try{
                wherestr = "where callstatus='D' and (peer='"+peer+"' or (company_id='"+company_id+"' and (src='"+phoneid+"' or dst='"+phoneid+"')))";
                cdrdb = new CurrentEicnCDRDB(conn_cli);
                cdrdm = cdrdb.getByWhere(wherestr);
        } catch(SQLException se){
                getDBConnCliOnlyPBX(true,"CmdAttendedSVC");
                try{
                        cdrdb = new CurrentEicnCDRDB(conn_cli);
                        cdrdm = cdrdb.getByWhere(wherestr);
                } catch(SQLException se1) {
                        PrintLog("CmdAttended_1", "EXCEPTION:"+se1.toString());
                }
        }
        if(cdrdm == null || cdrdm.length == 0)
        {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1:"+phoneid+"|DATA2:NOCHAN");
                return;
        }
        String in_out = cdrdm[0].getInout();
        String chann = cdrdm[0].getChannel();
        String caller = cdrdm[0].getSrc();
        if(in_out != null && in_out.equals("O"))
        {
                chann = cdrdm[0].getDstChannel();
                caller = cdrdm[0].getDst();
        }
        if(chann != null && !chann.equals(""))
        {
                try{
System.out.println("CmdAttendedSVC:"+target+","+caller);
                        chann = chann.replace("sip","SIP");
                        RedirectAction act=new RedirectAction(chann,"redirect_context",target,1);
                        send_manager.sendAction(act);
                }catch(Exception ae){
                        PrintLog("CmdAttended_2", "EXCEPTION:"+ae.toString());
                }
 
        } else {
                writeMessage("CALLSTATUS|KIND:ATTENDED|DATA1::"+phoneid+"|DATA2:NOCHAN");
        }
}

//--CMD|PICKUP|${내선}
//--당겨받기 
public void CmdPickup() 
{
	OriginateAction ori_act=new OriginateAction();
	String myid=phoneid;
	ori_act.setAccount(phoneid);
	ori_act.setCallerId("\""+phoneid+"\" <0000>");
	ori_act.setChannel("SIP/"+phoneid);
	ori_act.setExten(phoneid);
	ori_act.setContext("pickup_context");
	ori_act.setPriority(1);
	ori_act.setAsync(true);
	try{
		send_manager.sendAction(ori_act);
	}catch(Exception ae){
		System.out.println("Origination Exception"+ae.toString());
		PrintLog("CmdPickup_1", "EXCEPTION:"+ae.toString());
	}
}


//--CMD|PICKUP|${내선}
//--당겨받기 
public void CmdRedirectmember() 
{
	PersonListDB pldb = new PersonListDB(conn);
	PersonListDM[] pldm = null;
	String wherestr = "where extension!='"+phoneid+"' and part_group="+part_code+" order by id_name asc";
	try{
		pldb = new PersonListDB(conn_cli);
		pldm = pldb.getByWhere(wherestr);
	} catch(SQLException se){
		getDBConnCliOnlyPBX(true,"CmdRedirectmember");
		try{
              		pldb = new PersonListDB(conn_cli);
			pldm = pldb.getByWhere(wherestr);
		} catch(SQLException se1) {
			PrintLog("CmdRedirectmember_1", "EXCEPTION:"+se1.toString());
		}
	}
	if(pldm !=null && pldm.length>0)
	{
		for(int i=0; i<pldm.length ; i++)
		{
			String outstr = "REDIRECT_MEMBER|KIND:REDIRECT_MEMBER|DATA1:"+pldm[i].getExtension()+"|DATA2:"+pldm[i].getIdName();
			writeMessage(outstr);
		}
	}
}
//--로긴
public void CheckLogin(String cmdstr, PrintWriter out, boolean flag) 
{
	PrintLog("CheckLogin_1", cmdstr);
	String[] args = new String[20];
	int cnt = DeliHandle.ps_parseCap(cmdstr,5,args);
	String res = "";
	if(cnt != 7)
	{
		res = "LOGIN|KIND:LOGIN_ERROR|DATA1:FORMAT_ERROR";
		writeMessage(res);
		return;
	}

	//로긴 데이타:CMD_user301_IR_OR_1234
	userid = args[1];//extension
	company_id = args[2];
	area_code = args[3];
	branch_code = args[4];
	part_code = args[5];
	String pass = args[6];
	if(userid == null || pass == null || company_id == null ||
		userid.equals("") || pass.equals("") || company_id.equals(""))
	{
		res = "LOGIN|KIND:LOGIN_ERROR|DATA1:FORMAT_ERROR";
		writeMessage(res);
		return;
	}
	String phone_status = "";
	try{
		//////////DB 연결
		getDBConnCliOnlyPBX(false,"CheckLogin");
		getDBConnCliOnlyWEB(false,"CheckLogin");

		PersonListDB wmdb = new PersonListDB(conn_cli);
		PersonListDB wmdb_web = new PersonListDB(conn_web);
		
		PersonListDM[] wmdm = wmdb.getByWhere("where id='"+userid+"' and passwd='"+pass+"' and company_id='"+company_id+"' ");
		if(wmdm == null || wmdm.length==0)
		{
			res = "LOGIN|KIND:LOGIN_ERROR|DATA1:ID_PASS_ERROR";
			writeMessage(res);
			return;
		} else {
			phoneid = wmdm[0].getExtension();
			PhoneInfoDB pidb = new PhoneInfoDB(conn_cli);
			PhoneInfoDM[] pidm = pidb.getByWhere("where company_id='"+company_id+"' and extension='"+phoneid+"' ");
			if(pidm == null || pidm.length==0)
			{
				res = "LOGIN|KIND:LOGIN_ERROR|DATA1:NO_EXTEN_ERROR";
				writeMessage(res);
				return;
			}
			peer = pidm[0].getPeer();
			user_name = wmdm[0].getIdName();
 
                        //로긴표시
System.out.println("setIsLoginMsg");
                        wmdm[0].setIsLoginMsg("L");
                        wmdb.updateLoginMsg(wmdm[0]);
			if(domain != null && !domain.equals("localhost"))
			{
                        	wmdb_web.updateLoginMsg(wmdm[0]);
			}

		}
		//HAHA
	} catch (Exception e){
		System.out.println(e.getMessage());
		return;
	}

	//로긴성공
	bRunThread = true; 
	fLogin = true; 
	res = "LOGIN|KIND:LOGIN_OK|DATA1:"+phoneid+"|DATA2:"+user_name;
	try{
		//후처리상태달기
		QueueMemberDB qmdb = new QueueMemberDB(conn_cli);
		QueueMemberDM[] qmdm = qmdb.getByWhere("where membername='"+peer+"' and queue_name=''");
		if(qmdm !=null && qmdm.length>0)
		{
			res = res+"|DATA3:0";
			paused = qmdm[0].getPaused();
		} else {
			res = res+"|DATA3:X";
		}

		//전화기상태보내기
		if(phone_status !=null && (phone_status.equals("registered") || phone_status.equals("reachable") ||phone_status.equals("ok")))
		{
			res = res+"|DATA4:OK|DATA5:"+peer;
		} else {
			res = res+"|DATA4:OK|DATA5:"+peer;
		}

	} catch (Exception e) {}

	writeMessage(res);
	server.AddMember(this);

}

} 
/****************************/
/*     MasterLoop class     */
/****************************/
class MasterLoop extends Thread
{
        PrintWriter tmpout=null;
        MasterLoop(MsgServer server){
        }
        public void run()
        {
 
		while(true) 
		{
			try{
				sleep(30000);
				System.out.println("PING------------------------");

                                System.out.println("LOGIN_CLI_SIZE:"+cli_hash.size());
                                for (Enumeration e = cli_hash.keys() ; e.hasMoreElements() ;)
                                {
                                        String peer = (String)e.nextElement();
                                        System.out.println("LOGIN_CLI:"+peer);
                                        ClientServiceThread th = (ClientServiceThread) cli_hash.get(peer);
 
					if(th != null)
					{
                                        	th.writeMessage("PING");
					}
 
                                }
			} catch (Exception e) {
				System.out.println("Loop ERROR:"+e.getMessage());
			}
		}
	}
}
} 
