/// <summary> /// Checks the connection status. /// </summary> /// <param name="data">Data for check (not used).</param> private void CheckConnection(object data) { if (!this.ConnectionIsAlive) { RaiseEvent(SPStatus.ERROR_CONNECTION, "Connection Timer expired"); } this.ConnectionIsAlive = false; AltiLinkPlus.ALPCommand ac = new AltiLinkPlus.ALPCommand(this.ControlLocationID, Convert.ToInt32(ALPCmdID.PING)); ac[0] = new AltiLinkPlus.ALPParameter(1); this.SendALPCommand(ac); TraceOut.Put("[Timer] Checking connection(" + this.ConnectionIsAlive.ToString() + ")..."); }
/// <summary> /// Thread which extracts commands from commandsQueue queue and sends them to SP. /// </summary> private void outThread() { //An object to be sent (command). AltiLinkPlus.ALPCommand cmd = null; Diacom.Cmd.CmdBase spCommand = null; // While outThreadLivingStatus == true we should dequeue commands from outgoing queue and send them. while (outThreadLivingStatus) { try { // Getting next command and processing it. object obj = commandsQueue.Dequeue(); // First try as a raw ALP command cmd = obj as AltiLinkPlus.ALPCommand; // If not ALP command - convert to if (cmd == null) { spCommand = obj as Diacom.Cmd.CmdBase; cmd = ProcessCommand(spCommand); } // If not null then command is valid - sending it. if (cmd != null) { // Creating new packet. AltiLinkPlus.ALPPacket outThreadPacket = new AltiLinkPlus.ALPPacket(); // Putting command into a packet. outThreadPacket.Add(cmd); TraceOut.Put("AltiGenSPCore::ProcessCommand LocId=" + cmd.LocationId + " CmdId=" + ((ALPCmdID)cmd.CommandId).ToString() + " SeqId=" + cmd.SequenceId); // Sending out the packet. outThreadPacket.Write(bw); } } catch (Exception x) { if (outThreadLivingStatus) { TraceOut.Put(x); RaiseEvent(SPStatus.ERROR_CONNECTION, String.Format("Sending command: {0}", x.Message)); } } } }
/// <summary> /// Thread which receives packets from AltiGen Server and /// calls the appropriate procedures - to process event or response. /// </summary> private void inThread() { AltiLinkPlus.ALPPacket inThreadPacket = new AltiLinkPlus.ALPPacket(); // While inThreadLivingStatus == true we should receive incoming packets. while (inThreadLivingStatus) { try { // Reding next packet. inThreadPacket.Read(br); // Loop through every block of data in the received packet. for (int j = 0; j < inThreadPacket.BlockCount; j++) { // Getting block. AltiLinkPlus.ALPDataBlock dataBlock = inThreadPacket.PacketData[j]; if (dataBlock is AltiLinkPlus.ALPEvent) { // Process received event. ProcessEvent((AltiLinkPlus.ALPEvent)dataBlock); } else if (dataBlock is AltiLinkPlus.ALPResponse) { // Process received response. ProcessResponse((AltiLinkPlus.ALPResponse)dataBlock); } } } catch (Exception x) { if (inThreadLivingStatus) { TraceOut.Put(x); RaiseEvent(SPStatus.ERROR_CONNECTION, x.Message); } } } }
/// <summary> /// Process all responses. /// </summary> /// <param name="altiResponse">Block of data to process.</param> /// <returns>An object with the response.</returns> protected override void ProcessResponse(AltiLinkPlus.ALPResponse altiResponse) { TraceOut.Put("AltiGenSP::ProcessResponse SeqId=" + altiResponse.SequenceId + " LocId=" + altiResponse.LocationId + " CmdId=" + ((ALPCmdID)altiResponse.CommandId).ToString() + " code=" + ((ALPRespID)altiResponse.ResponseCode).ToString()); ALPLine _line = GetLineBySequenceId(altiResponse.SequenceId); switch ((ALPCmdID)(altiResponse.CommandId)) { // Answer call. case ALPCmdID.APC_ANSWER_CALL: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.ANSWER_CALL, Ev.CmdStatus.ERROR)); } else { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.ANSWER_CALL, Ev.CmdStatus.OK)); } break; // Reject. case ALPCmdID.APC_REJECT_CALL: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.REJECT_CALL, Ev.CmdStatus.ERROR)); } else { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.REJECT_CALL, Ev.CmdStatus.OK)); } break; // Pass. case ALPCmdID.APC_PASS_CALL: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.PASS_CALL, Ev.CmdStatus.ERROR)); } else { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.PASS_CALL, Ev.CmdStatus.OK)); } break; // Connect. case ALPCmdID.APC_CONNECT_CALL: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.CONNECT_LINES, Ev.CmdStatus.ERROR)); } break; // Disconnect. case ALPCmdID.APC_DROP_CALL: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.DROP_CALL, Ev.CmdStatus.ERROR)); } break; // Dial. case ALPCmdID.APC_MAKE_CALL: { // Searching for a line command to dial was sent on. OutcallCommandStruct odc = ((OutcallCommandStruct)(outcallNumbersDialingCommands[altiResponse.SequenceId])); if (odc != null) { outcallNumbersDialingCommands.Remove(altiResponse.SequenceId); // Have appropriate line. if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(odc.Line, Cmd.CommandID.DIAL, Ev.CmdStatus.ERROR)); } else { this.SendSpEvent(new Ev.CommandStatus(odc.Line, Cmd.CommandID.DIAL, Ev.CmdStatus.OK)); } break; } break; } // Play DTMF. case ALPCmdID.APC_PLAY_DTMF: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.PLAY_DTMF, Ev.CmdStatus.ERROR)); } break; // Play file. case ALPCmdID.APC_PLAY_VOICE: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.PLAY_FILE, Ev.CmdStatus.ERROR)); } break; // Record file. case ALPCmdID.APC_RECORD_VOICE: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.RECORD_FILE, Ev.CmdStatus.ERROR)); } break; // Stop playing and recording. case ALPCmdID.APC_STOP_PLAY_VOICE: case ALPCmdID.APC_STOP_RECORD_VOICE: break; // Ring extension. case ALPCmdID.APC_RING_EXT: { // Find the line command to dial was sent on. OutcallCommandStruct odc = ((OutcallCommandStruct)(outcallNumbersDialingCommands[altiResponse.SequenceId])); if (odc != null) { outcallNumbersDialingCommands.Remove(altiResponse.SequenceId); // Have appropriate line. if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(odc.Line, Cmd.CommandID.RING_EXTENSION, Ev.CmdStatus.ERROR)); } else { this.SendSpEvent(new Ev.CommandStatus(odc.Line, Cmd.CommandID.RING_EXTENSION, Ev.CmdStatus.OK)); } } break; } // Snatch line. case ALPCmdID.APC_SNATCH_LINE: if (_line == null) { return; } int lineConnectedToThisID = altiResponse[0].ReadInt32(); TraceOut.Put("AltiGenSP::SnatchLine. Line1=" + _line.SPLineInfo.ID + " and Line2=" + lineConnectedToThisID); ALPLine _connectedLine = this[lineConnectedToThisID]; if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.DISCONNECT_LINE, Ev.CmdStatus.ERROR)); } else { if (_connectedLine == null) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.DISCONNECT_LINE, Ev.CmdStatus.OK)); } else { _connectedLine.InfoState = ALPLine.CallInfoState.SNATCHED_SLAVE_LINE; _connectedLine.ConnectedLine = _line; _connectedLine.IsUnderAPCControl = true; this.SendSpEvent(new Ev.LineLinked(_line.SPLineInfo.ID, _connectedLine.SPLineInfo.ID)); } } break; // Switch music. case ALPCmdID.APC_SWITCH_MUSIC: if (_line == null) { return; } if (altiResponse.ResponseCode == 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.SWITCH_MUSIC, Ev.CmdStatus.OK)); } else { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.SWITCH_MUSIC, Ev.CmdStatus.ERROR)); } break; // Transfer call. case ALPCmdID.APC_TRANSFER_CALL: if (_line == null) { return; } if (altiResponse.ResponseCode != 0) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.TRANSFER, Ev.CmdStatus.ERROR)); } break; case ALPCmdID.APC_GET_DATA: CallInfo rInfo = (CallInfo)this.StoredRingInfo[altiResponse.SequenceId]; if (rInfo != null) { this.StoredRingInfo.Remove(rInfo); _line = this[rInfo.lineID]; if (_line != null && !_line.IsUnderAPCControl) { // Updating line information. _line.SPLineInfo.CalledNumber = rInfo.callerID; _line.SPLineInfo.CalledName = rInfo.callerName; _line.SPLineInfo.DNISNumber = rInfo.DNISID; _line.SPLineInfo.DNISName = rInfo.DNISName; _line.SPLineInfo.CIDNumber = rInfo.callerID; _line.SPLineInfo.CIDName = rInfo.callerName; _line.SPLineInfo.DIDNumber = rInfo.calleeID; _line.SPLineInfo.DIDName = rInfo.calleeName; _line.SPLineInfo.UserName = rInfo.ANIName; _line.SPLineInfo.UserNumber = rInfo.ANIID; if (altiResponse.ResponseCode == 0) { int _lineID = altiResponse[0].ReadInt32(); int DataType = altiResponse[1].ReadInt32(); switch ((ALPInfoType)DataType) { case ALPInfoType.APC_DATATYPE_USER: _line[USER_DATA] = altiResponse.ReadString(); break; } } this.SendSpEvent(new Ev.Ring(rInfo.lineID, (SPLine)_line.SPLineInfo.Clone())); if (_line.InfoState == ALPLine.CallInfoState.CONNECT_DELAYED) { // Have new connected line. Creating and sending event. TraceOut.Put("AltiGenSP:: Line is APC controlled"); _line.IsUnderAPCControl = true; this.SendSpEvent(new Ev.Connect(rInfo.lineID)); foreach (string _digit in _line.Digits) { this.SendSpEvent(new Ev.Digit(rInfo.lineID, _digit[0])); } } else { _line.InfoState = ALPLine.CallInfoState.CALL_INFO_RECEIVED; } } } break; case ALPCmdID.APC_SET_DATA: break; default: base.ProcessResponse(altiResponse); break; } }
/// <summary> /// Processes all events. /// </summary> /// <param name="altiEvent">Block of data to process.</param> /// <returns>An object whith the event.</returns> protected override void ProcessEvent(AltiLinkPlus.ALPEvent altiEvent) { // Getting information only if event is for our SP control line. TraceOut.Put("AltiGenSP::ProcessEvent LocId=" + altiEvent.LocationId + " EventId=" + ((ALPEvID)altiEvent.CommandId).ToString()); if (altiEvent.LocationId == ControlLocationID) { switch ((ALPEvID)(altiEvent.CommandId)) { // Event Ev.Ring. case ALPEvID.APC_CALLPRESENT: { CallInfo rInfo = new CallInfo(((AltiLinkPlus.ALPParameter)(altiEvent[0]))); ALPLine _line = this[rInfo.lineID]; if (!_line.IsUnderAPCControl) { AltiLinkPlus.ALPCommand ac = new AltiLinkPlus.ALPCommand(ControlLocationID, (int)(ALPCmdID.APC_GET_DATA)); ac[0] = new AltiLinkPlus.ALPParameter(rInfo.lineID); ac[1] = new AltiLinkPlus.ALPParameter((int)Diacom.AltiGen.ALPInfoType.APC_DATATYPE_USER); ac[2] = new AltiLinkPlus.ALPParameter(0); StoredRingInfo.Add(ac.SequenceId, rInfo); base.SendALPCommand(ac); _line.InfoState = ALPLine.CallInfoState.CALL_INFO_REQ_SENT; _line.Digits.Clear(); TraceOut.Put("AltiGenSP::APC_CALLPRESENT from :" + rInfo.callerID + " - requested extra info"); } break; } // Event Ev.RingBack. case ALPEvID.APC_RINGBACK: { CallInfo rbInfo = new CallInfo(((AltiLinkPlus.ALPParameter)(altiEvent[0]))); // Getting current line from hashtable. ALPLine _line = this[rbInfo.lineID]; if (_line != null) { // Updating line information. if (_line.SPLineInfo.Type == "T") { _line.SPLineInfo.CalledNumber = _line.SPLineInfo.AccessCode + rbInfo.calleeID; _line.SPLineInfo.CalledName = rbInfo.calleeName; } else { _line.SPLineInfo.CalledNumber = rbInfo.callerID; _line.SPLineInfo.CalledName = rbInfo.callerName; } _line.SPLineInfo.DNISNumber = rbInfo.DNISID; _line.SPLineInfo.DNISName = rbInfo.DNISName; _line.SPLineInfo.CIDNumber = rbInfo.ANIID; _line.SPLineInfo.CIDName = rbInfo.ANIName; _line.SPLineInfo.DIDNumber = rbInfo.calleeID; _line.SPLineInfo.DIDName = rbInfo.calleeName; TraceOut.Put("AltiGenSP::APC_RINGBACK"); if (!_line.IsUnderAPCControl) { this.SendSpEvent(new Ev.RingBack(rbInfo.lineID, (SPLine)_line.SPLineInfo.Clone())); } } break; } // Event Ev.Connect. case ALPEvID.STCHG: { // Getting parameters. ALPLineState state = ((ALPLineState)(altiEvent[0].ReadInt32())); int lineID = altiEvent[1].ReadInt32(); // Getting current line from hashtable. ALPLine _line = this[lineID]; TraceOut.Put("AltiGenSP::Line State=" + ((ALPLineState)state).ToString()); if ((_line != null) && (state == ALPLineState.APC)) { if (_line.IsUnderAPCControl && (_line.InfoState == ALPLine.CallInfoState.SNATCHED_SLAVE_LINE)) { this.SendSpEvent(new Ev.CommandStatus(_line.ConnectedLine.SPLineInfo.ID, Cmd.CommandID.DISCONNECT_LINE, Diacom.Ev.CmdStatus.OK)); } else if (!_line.IsUnderAPCControl) { if (_line.InfoState == ALPLine.CallInfoState.CALL_INFO_RECEIVED) { // Have new connected line. Creating and sending event. TraceOut.Put("AltiGenSP:: Line is APC controlled now"); _line.IsUnderAPCControl = true; this.SendSpEvent(new Ev.Connect(lineID)); foreach (string _digit in _line.Digits) { this.SendSpEvent(new Ev.Digit(lineID, _digit[0])); } } else { _line.InfoState = ALPLine.CallInfoState.CONNECT_DELAYED; } } } break; } // Event Ev.Digit. case ALPEvID.APC_DIGIT: { // Getting parameters. AltiLinkPlus.ALPParameter param = (AltiLinkPlus.ALPParameter)altiEvent[0]; int lineID = param.ReadInt32(); char digit = Convert.ToChar(param.ReadByte()); // Creating and sending event. ALPLine _line = this[lineID]; if (_line.IsUnderAPCControl) { this.SendSpEvent(new Ev.Digit(lineID, digit)); } else { _line.Digits.Add(digit.ToString()); } break; } // Event Ev.Disconnect. case ALPEvID.APC_CALLDROP: { // Getting parameters. int lineID = altiEvent[0].ReadInt32(); ALPLine _line = this[lineID]; break; } // Event Ev.CommandStatus. case ALPEvID.APC_STATUS: { // Creating new StateInfo object. LineStateInfo sInfo = new LineStateInfo((AltiLinkPlus.ALPParameter)(altiEvent[0])); ALPCmdStatus lastCmdStatus = (ALPCmdStatus)sInfo.cmdStatus; TraceOut.Put("AltiGenSP::APC Status Line=" + sInfo.lineID + " CmdId=" + ((ALPCmdID)sInfo.commandID).ToString() + " Status=" + lastCmdStatus.ToString()); // Getting current line from hashtable. ALPLine _line = this[sInfo.lineID]; if (_line == null) { break; } // Save the last status _line.LastCommand.Status = lastCmdStatus; // What was the command issued? switch ((ALPCmdID)(sInfo.commandID)) { // Status of APC_PLAY_DTMF command. case ALPCmdID.APC_PLAY_DTMF: if (lastCmdStatus == ALPCmdStatus.FAILED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.PLAY_DTMF, Ev.CmdStatus.ERROR)); } else { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.PLAY_DTMF, Ev.CmdStatus.OK)); } break; // Status of APC_PLAY_VOICE command. case ALPCmdID.APC_PLAY_VOICE: if (lastCmdStatus == ALPCmdStatus.FINISHED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.PLAY_FILE, Ev.CmdStatus.OK)); } else if (lastCmdStatus == ALPCmdStatus.FAILED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.PLAY_FILE, Ev.CmdStatus.ERROR)); } break; // Status of APC_RECORD_VOICE command. case ALPCmdID.APC_RECORD_VOICE: if (lastCmdStatus == ALPCmdStatus.FINISHED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.RECORD_FILE, Ev.CmdStatus.OK)); } else if (lastCmdStatus == ALPCmdStatus.FAILED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.RECORD_FILE, Ev.CmdStatus.ERROR)); } break; // Status of APC_CONNECT_CALL command. case ALPCmdID.APC_CONNECT_CALL: if (lastCmdStatus == ALPCmdStatus.SUCCEED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.CONNECT_LINES, Ev.CmdStatus.OK)); } else { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.CONNECT_LINES, Ev.CmdStatus.ERROR)); } break; // Status of APC_TRANSFER_CALL command. case ALPCmdID.APC_TRANSFER_CALL: if (lastCmdStatus != ALPCmdStatus.SUCCEED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.TRANSFER, Ev.CmdStatus.ERROR)); } break; // Status of APC_DROP_CALL command. case ALPCmdID.APC_DROP_CALL: if (lastCmdStatus == ALPCmdStatus.SUCCEED) { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.DROP_CALL, Ev.CmdStatus.OK)); } else { this.SendSpEvent(new Ev.CommandStatus(sInfo.lineID, Cmd.CommandID.DROP_CALL, Ev.CmdStatus.ERROR)); } break; } break; } default: { base.ProcessEvent(altiEvent); break; } } } // Getting information for ALL line PADs - just want to know that is going on. switch ((ALPEvID)(altiEvent.CommandId)) { case ALPEvID.STCHG: { if (altiEvent.LocationId == ControlLocationID) { break; // We already processed this above } // Saving line state. ALPLineState state = (ALPLineState)(altiEvent[0].ReadInt32()); ALPLine _line = this[altiEvent.LocationId]; TraceOut.Put("AltiGenSP::Line State=" + ((SPLineState)state).ToString()); if (_line != null) { // Rasing event the line is disconnected if status is DISCONNECT. if (state == ALPLineState.IDLE) { if (_line.IsUnderAPCControl) { TraceOut.Put("AltiGenSP:: Line is not APC controlled"); _line.IsUnderAPCControl = false; _line.InfoState = ALPLine.CallInfoState.INITIAL; this.SendSpEvent(new Ev.Disconnect(_line.SPLineInfo.ID)); } } else if ((state == ALPLineState.CONNECTED) && (_line.LastCommand.ID == ALPCmdID.APC_TRANSFER_CALL)) { this.SendSpEvent(new Ev.CommandStatus(_line.SPLineInfo.ID, Cmd.CommandID.TRANSFER, Ev.CmdStatus.OK)); } _line.SPLineInfo.State = (SPLineState)state; // Rasing event state of the line changed. this.SendSpEvent(new Ev.LineStateChanged(_line.SPLineInfo.ID, (SPLineState)state)); } break; } // Event Ev.Tone. case ALPEvID.TONE: { // Getting parameters. AltiLinkPlus.ALPParameter param = (AltiLinkPlus.ALPParameter)altiEvent[0]; int lineID = param.ReadInt32(); param = (AltiLinkPlus.ALPParameter)altiEvent[1]; int tone = Convert.ToChar(param.ReadInt32()); // Creating and sending event. this.SendSpEvent(new Ev.Tone(lineID, ((Ev.ToneType)(tone)))); break; } // Line information changed. case ALPEvID.CONFIG_CHG: { const int CONFIG_CHANGED_TYPE_LINEINFO = 0x8000; AltiLinkPlus.ALPParameter param = (AltiLinkPlus.ALPParameter)altiEvent[0]; int type = param.ReadInt32(); if (type == CONFIG_CHANGED_TYPE_LINEINFO) { // Command to Get Lines Information. this.SendALPCommand(new Diacom.AltiGen.AltiLinkPlus.ALPCommand(altiEvent.LocationId, Convert.ToInt32(ALPCmdID.GET_LINEINFO))); } break; } // System configuration changed. case ALPEvID.SYSCONFIG_CHG: { AltiLinkPlus.ALPParameter param = (AltiLinkPlus.ALPParameter)altiEvent[0]; SystemConfigChangeCodes type = ((SystemConfigChangeCodes)(param.ReadInt32())); switch (type) { // Line added. case SystemConfigChangeCodes.LINEADD: { // Issue command to Get Line Information. When we get the response - then the code there will send an event. this.SendALPCommand(new Diacom.AltiGen.AltiLinkPlus.ALPCommand(altiEvent.LocationId, Convert.ToInt32(ALPCmdID.GET_LINEINFO))); break; } // Line removed. case SystemConfigChangeCodes.LINEREMOVE: { this.SendSpEvent(new Ev.LineStateChanged(altiEvent.LocationId, SPLineState.LINE_REMOVE)); break; } } break; } default: { if (altiEvent.LocationId != ControlLocationID) { base.ProcessEvent(altiEvent); } break; } } }
/// <summary> /// Process all responses. /// </summary> /// <param name="altiResponse">Block of data to process.</param> /// <returns>An object with the response.</returns> protected virtual void ProcessResponse(AltiLinkPlus.ALPResponse altiResponse) { TraceOut.Put("AltiGenSPCore::ProcessResponse SeqId=" + altiResponse.SequenceId + " LocId=" + altiResponse.LocationId + " CmdId=" + ((ALPCmdID)altiResponse.CommandId).ToString() + " code=" + ((ALPRespID)altiResponse.ResponseCode).ToString()); WaitingCommandInfo wci; lock (this.waitingCommands) { wci = this.waitingCommands[altiResponse.SequenceId]; } switch ((ALPCmdID)(altiResponse.CommandId)) { case ALPCmdID.REGISTER_APPID: if (wci != null) { wci.respCode = altiResponse.ResponseCode; wci.errorOccured = (altiResponse.ResponseCode == 0) ? false : true; wci.cmdReady.Set(); } break; // Logon. case ALPCmdID.LOGON: { if (altiResponse.ResponseCode == 0) { TraceOut.Put("Logon saccessfull..."); // Getting our control line PAD. if (this.logonType == SPLogonType.ADMINISTRATOR) { this.ControlLocationID = altiResponse.LocationId; } } if (wci != null) { wci.respCode = altiResponse.ResponseCode; wci.errorOccured = (altiResponse.ResponseCode == 0) ? false : true; wci.cmdReady.Set(); } break; } case ALPCmdID.GET_VERSION: if (altiResponse.ResponseCode == 0) { this.VersionID = altiResponse[0].ReadInt32(); TraceOut.Put("GetVersion successful. Version = " + VersionID.ToString("X")); bool enableOptionPack = Convert.ToBoolean(altiResponse[1].ReadByte()); } if (wci != null) { wci.errorOccured = (altiResponse.ResponseCode == 0) ? false : true; wci.respCode = altiResponse.ResponseCode; wci.cmdReady.Set(); } break; // Get lines info. case ALPCmdID.GET_LINEINFO: if (altiResponse.ResponseCode == 0) { // First parameter in response is number of entries. int linesCount = altiResponse[0].ReadInt32(); // Second parameter holds lines information. AltiLinkPlus.ALPParameter param = altiResponse[1]; // Filling lines hashtable. for (int i = 0; i < linesCount; i++) { LineInfo _li = new LineInfo(param, this.VersionID); this[_li.lineHandle] = new ALPLine(_li); // If there is no command waiting - send the event that new line was added if (wci == null) { this.SendSpEvent(new Ev.LineStateChanged(_li.lineHandle, SPLineState.LINE_ADD)); } } TraceOut.Put(linesCount.ToString() + " lines added..."); } else if (altiResponse.ResponseCode == (int)Diacom.AltiGen.ALPRespID.LIST_END) { // We received "No more Data" response TraceOut.Put("All lines received."); if (wci != null) { wci.errorOccured = false; wci.cmdReady.Set(); } } else { TraceOut.Put("Failed to get lines info : " + ((ALPRespID)(altiResponse.ResponseCode)).ToString()); if (wci != null) { wci.errorOccured = true; wci.respCode = altiResponse.ResponseCode; wci.cmdReady.Set(); } } break; case ALPCmdID.PING: TraceOut.Put("PING response received."); this.ConnectionIsAlive = true; break; } }
/// <summary> /// Connects to server with given parameters. /// </summary> /// <param name="serverIP">IP address of server.</param> /// <param name="serverPort">Port to connect.</param> /// <param name="logonType">Type of logon.</param> /// <param name="account">Account.</param> /// <param name="password">Password.</param> /// <param name="timeout">Timeout interval.</param> /// <remarks> /// <para>Creates new TCP socket, connects to server with given IP address and port, /// tries to logon as "logonType" to "account" with given "password".</para> /// <para>Blocks the current thread until initialization is finished. /// Waits for connection "timeout" miliseconds.</para> /// </remarks> public void Connect(string serverIP, int serverPort, SPLogonType logonType, string account, string password, int timeout) { try { // Connect to the AltiWare server. this.tcpc.Connect(serverIP, serverPort); this.ConnectionIsAlive = true; // Assign network stream. this.st = tcpc.GetStream(); // To Binaryreader. this.bw = new BinaryWriter(st); // To BinaryWriter. this.br = new BinaryReader(st); this.lines = new Hashtable(); // Starting threads. this.outALPThreadHandle.Start(); this.outThreadHandle.Start(); this.inThreadHandle.Start(); if (timeout == 0) { timeout = System.Threading.Timeout.Infinite; } else if (timeout < 1000) { timeout *= 1000; } // Command to Register Application. AltiLinkPlus.ALPCommand ac = new AltiLinkPlus.ALPCommand(0, Convert.ToInt32(ALPCmdID.REGISTER_APPID)); // AltiGen SDK application. ac[0] = new AltiLinkPlus.ALPParameter("GATORS11"); this.SendALPCommandAndWait(ac, timeout); // Command to Logon ac = new AltiLinkPlus.ALPCommand(0, Convert.ToInt32(ALPCmdID.LOGON)); ac[0] = new AltiLinkPlus.ALPParameter((int)logonType); ac[1] = new AltiLinkPlus.ALPParameter(account); ac[2] = new AltiLinkPlus.ALPParameter(password); ac[3] = new AltiLinkPlus.ALPParameter(0); ac[4] = new AltiLinkPlus.ALPParameter(0); ac[5] = new AltiLinkPlus.ALPParameter(0); ac[6] = new AltiLinkPlus.ALPParameter(0); this.SendALPCommandAndWait(ac, timeout); // Get version this.SendALPCommandAndWait(new AltiLinkPlus.ALPCommand(0, Convert.ToInt32(ALPCmdID.GET_VERSION)), timeout); // Issue command to Get Lines Information. this.SendALPCommandAndWait(new Diacom.AltiGen.AltiLinkPlus.ALPCommand(0, Convert.ToInt32(ALPCmdID.GET_LINEINFO)), timeout); // Have a bad response on REGISTER_APPID, LOGON or GET_LINES command. if ((lines == null) || (ControlLocationID == 0)) { TraceOut.Put("Logon unsuccessful"); RaiseEvent(SPStatus.ERROR_LOGON, "Logon Error"); return; } this.ConnectionChecker = new System.Threading.Timer(new System.Threading.TimerCallback(this.CheckConnection), null, 30000, 30000); spStatus = SPStatus.OK; RaiseEvent(SPStatus.OK, "Logon Success"); } catch (Exception _x) { TraceOut.Put("Connect Exception"); TraceOut.Put("_x.Message"); RaiseEvent(SPStatus.ERROR_LOGON, _x.Message); } }
/// <summary> /// Prints <see cref="AltiLinkPlus.ALPDataBlock"/> to standard error stream of application. /// </summary> /// <param name="time">Current time the data is putting into stream.</param> /// <param name="aData">Data block to print.</param> public static void Put(DateTime time, AltiLinkPlus.ALPDataBlock aData) { if (aData == null) { return; } string str = String.Empty; string HTMLStr = time.ToString("[HH:mm:ss:fff]") + " "; // The command. if (aData is AltiLinkPlus.ALPCommand) { AltiLinkPlus.ALPCommand cmd = ((AltiLinkPlus.ALPCommand)(aData)); str = "Command:" + Environment.NewLine; HTMLStr += HTML.GHF("Command:") + Environment.NewLine; str += String.Format("ID: {0} [{1}], location ID: {2}, sequence ID: {3}, number of parameters: {4}{5}", ((ALPCmdID)(cmd.CommandId)), cmd.CommandId, cmd.LocationId, cmd.SequenceId, cmd.Count, Environment.NewLine); HTMLStr += HTML.GPF("ID: ") + HTML.GCF(((ALPCmdID)(cmd.CommandId)).ToString()) + HTML.GPF(" [") + cmd.CommandId.ToString() + HTML.GPF("], location ID: ") + cmd.LocationId.ToString() + HTML.GPF(", sequence ID: ") + cmd.SequenceId.ToString() + HTML.GPF(", number of parameters: ") + cmd.Count.ToString() + Environment.NewLine; for (int i = 0; i < cmd.Count; i++) { str += String.Format("param#{0}: {1}{2}", i, BitConverter.ToString(cmd[i].GetBytes()), Environment.NewLine); } for (int i = 0; i < cmd.Count; i++) { HTMLStr += String.Format("{0}{1}{2} {3}{4}", HTML.GPF("param#"), i, HTML.GPF(":"), BitConverter.ToString(cmd[i].GetBytes()), Environment.NewLine); } } else if (aData is AltiLinkPlus.ALPEvent) { AltiLinkPlus.ALPEvent ev = ((AltiLinkPlus.ALPEvent)(aData)); str = "Event:" + Environment.NewLine; HTMLStr += HTML.GHF("Event:") + Environment.NewLine; str += String.Format("ID: {0} [{1}], location ID: {2}, sequence ID: {3}, number of parameters: {4}{5}", ((ALPEvID)(ev.CommandId)), ev.CommandId, ev.LocationId, ev.SequenceId, ev.Count, Environment.NewLine); HTMLStr += HTML.GPF("ID: ") + HTML.GCF(((ALPEvID)(ev.CommandId)).ToString()) + HTML.GPF(" [") + ev.CommandId.ToString() + HTML.GPF("], location ID: ") + ev.LocationId.ToString() + HTML.GPF(", sequence ID: ") + ev.SequenceId.ToString() + HTML.GPF(", number of parameters: ") + ev.Count.ToString() + Environment.NewLine; for (int i = 0; i < ev.Count; i++) { str += String.Format("param#{0}: {1}{2}", i, BitConverter.ToString(ev[i].GetBytes()), Environment.NewLine); } for (int i = 0; i < ev.Count; i++) { HTMLStr += String.Format("{0}{1}{2} {3}{4}", HTML.GPF("param#"), i, HTML.GPF(":"), BitConverter.ToString(ev[i].GetBytes()), Environment.NewLine); } } else if (aData is AltiLinkPlus.ALPResponse) { AltiLinkPlus.ALPResponse rsp = ((AltiLinkPlus.ALPResponse)(aData)); str = "Responce:" + Environment.NewLine; HTMLStr += HTML.GHF("Responce:") + Environment.NewLine; str += String.Format("ID: {0} [{1}], location ID: {2}, sequence ID: {3}, responce code: {4} [{5}], number of parameters: {6}{7}", ((ALPCmdID)(rsp.CommandId)), rsp.CommandId, rsp.LocationId, rsp.SequenceId, ((ALPRespID)(rsp.ResponseCode)), rsp.ResponseCode, rsp.Count, Environment.NewLine); HTMLStr += HTML.GPF("ID: ") + HTML.GCF(((ALPCmdID)(rsp.CommandId)).ToString()) + HTML.GPF(" [") + rsp.CommandId.ToString() + HTML.GPF("], location ID: ") + rsp.LocationId.ToString() + HTML.GPF(", sequence ID: ") + rsp.SequenceId.ToString() + HTML.GPF(", responce code: ") + HTML.GCF(((ALPRespID)(rsp.ResponseCode)).ToString()) + HTML.GPF(" [") + rsp.ResponseCode.ToString() + HTML.GPF("], number of parameters: ") + rsp.Count.ToString() + Environment.NewLine; for (int i = 0; i < rsp.Count; i++) { str += String.Format("param#{0}: {1}{2}", i, BitConverter.ToString(rsp[i].GetBytes()), Environment.NewLine); } for (int i = 0; i < rsp.Count; i++) { HTMLStr += String.Format("{0}{1}{2} {3}{4}", HTML.GPF("param#"), i, HTML.GPF(":"), BitConverter.ToString(rsp[i].GetBytes()), Environment.NewLine); } if (rsp.CommandId.Equals(1021)) { // GET_LINE_INFO responce. /* StreamWriter sw = new StreamWriter(DateTime.Now.ToFileTime().ToString()+".html", false, Encoding.Unicode); * sw.WriteLine(""); * sw.WriteLine("<html>{0}<head>{0}<meta http-equiv=\"Content-Type\" content=\"text/html; charset=unicode\">{0}</head>{0}<body>{0}<pre>{0}", Environment.NewLine); * sw.WriteLine(DateTime.Now.ToString("yyyy.MM.dd, HH:mm:ss:fff")); * for(int i = 0; i < 80; i++) sw.Write("*"); * sw.WriteLine(""); * for(int i = 0; i < rsp.Count; i++) * { * sw.WriteLine("param #{0}", i); * Diacom.AltiGen.AltiLinkPlus.ALPParameter par = ((Diacom.AltiGen.AltiLinkPlus.ALPParameter)(rsp[i])); * sw.WriteLine("ID: {0}, length: {1}, size: {2}, type: {3}", par.ParameterID, par.Length, par.ParameterSize, par.ParameterType); * int l = par.Length; * char [] c = new char[l]; * byte [] b = par.GetBytes(); * for(int j = 0; j < l; j++) * { * if(j%10 == 0) sw.Write("|"); * else sw.Write(" "); * c[j] = Convert.ToChar(b[j]); * } * sw.WriteLine(""); * sw.WriteLine(c); * sw.WriteLine(""); * } * sw.WriteLine("</pre>{0}</body>{0}</html>{0}", Environment.NewLine); * sw.Close(); */ } } else { str = "Unrecognized:" + Environment.NewLine; HTMLStr += HTML.GHF("Unrecognized:") + Environment.NewLine; str += String.Format("ID: ... [{0}], location ID: {1}, sequence ID: {2}, number of parameters: {3}{4}", aData.CommandId, aData.LocationId, aData.SequenceId, aData.Count, Environment.NewLine); HTMLStr += HTML.GPF("ID: ... [") + aData.CommandId.ToString() + HTML.GPF("], location ID: ") + aData.LocationId.ToString() + HTML.GPF(", sequence ID: ") + aData.SequenceId.ToString() + HTML.GPF(", number of parameters: ") + aData.Count.ToString() + Environment.NewLine; for (int i = 0; i < aData.Count; i++) { str += String.Format("param#{0}: {1}{2}", i, BitConverter.ToString(aData[i].GetBytes()), Environment.NewLine); } for (int i = 0; i < aData.Count; i++) { HTMLStr += String.Format("{0}{1}{2} {3}{4}", HTML.GPF("param#"), i, HTML.GPF(":"), BitConverter.ToString(aData[i].GetBytes()), Environment.NewLine); } } // Saving string to a storage and putting it to trace output. TraceOut.Put(str); Storage.Append(HTMLStr + Environment.NewLine + "<hr>" + Environment.NewLine); }