public async Task StopAsync() { ConnectionState curState; lock (this) { if ((curState = _state) != ConnectionState.Connected) { _setState(ConnectionState.Unbinding); } } try { if (curState == ConnectionState.Unbinding) { SMPPMessage response = await _submitMessage(new SMPPUnbind()); if (response.Status != CommandStatus.ESME_ROK) { throw new SMPPException("Response from server " + response.Status + "."); } _setState(ConnectionState.Stopped); } } catch (Exception err) { throw _setFailed(new SMPPException("Unbind failed.", err)); } Close(); }
private async Task _sendMessage(SMPPMessage message) { using (await _sendLock.Enter()) { if (!_isRunning) { throw new SMPPException("Connection is down."); } PduWriter writer = new PduWriter(); if ((message.Command & CommandSet.Response) == 0) { lock (this) { message.Sequence = _sequence; _sequence = (_sequence < 1000000000) ? _sequence + 1 : 1; } } writer.WriteMessage(message); byte[] pduData = writer.PduData(); #if DEBUG Debug.WriteLine("SMPPConnection: SendMessage size=" + pduData.Length + " id=" + message.Command + " status=" + message.Status + " seq=" + message.Sequence); #endif try { await _stream.WriteAsync(pduData, 0, pduData.Length); } catch (Exception err) { throw _setFailed(new SMPPException("Send data to SMPP server failed", err)); } } }
private async void _cmdEnquire() { try { if (_state == ConnectionState.Connected) { SMPPMessage response = await _submitMessage(new SMPPEnquireLink()); if (response.Status != CommandStatus.ESME_ROK) { throw new SMPPException("Response from server " + response.Status + "."); } _enquirePoll = EnquirePoll; } } catch (Exception err) { lock (this) { if (_state == ConnectionState.Connected) { _setFailed(new SMPPException("EnquireLink failed", err)); if (_tcpClient != null) { _tcpClient.Client.Close(); } } } } }
public Task <SMPPMessage> SubmitMessageAsync(SMPPMessage message) { if (_state != ConnectionState.Connected) { throw new SMPPException("Not connected."); } return(_submitMessage(message)); }
public ActiveRequest AddMessage(SMPPMessage message) { ActiveRequest sendingMessage = new ActiveRequest(message); lock (this) { base.Add(sendingMessage); } return(sendingMessage); }
public void CompleteResp(SMPPMessage message) { ActiveRequest sendingMessage; lock (this) { int idx = _findMessage(message); sendingMessage = base[idx]; base.RemoveAt(idx); } sendingMessage.TaskCompletion.SetResult(message); }
private async void _sendMessageAsync(SMPPMessage message) { try { await _sendMessage(message); } catch (Exception err) { if (_isRunning) { _setFailed(new SMPPException("SendMessage failed.", err)); } } }
private int _findMessage(SMPPMessage message) { for (int i = 0; i < base.Count; ++i) { if (base[i].Message.Sequence == message.Sequence && (base[i].Message.Command == (message.Command & ~CommandSet.Response) || message.Command == CommandSet.GenericNack)) { return(i); } } throw new SMPPException("Received response for a unknown message."); }
private Task <SMPPMessage> _submitMessage(SMPPMessage message) { ActiveRequest sendingMessage = _activeRequests.AddMessage(message); sendingMessage.SendTask = _sendMessage(message); sendingMessage.SendTask.ContinueWith((task) => { if (task.Status != TaskStatus.RanToCompletion) { _activeRequests.CompleteError(sendingMessage, task.Exception); } }); return(sendingMessage.TaskCompletion.Task); }
private async Task _run() { try { _enquirePoll = int.MaxValue; using (new System.Threading.Timer(_poll, null, 1000, 1000)) { while (_isRunning) { SMPPMessage message = await _recvMessage(); switch (message.Command) { case CommandSet.EnquireLink: _recvEnquireLink((SMPPEnquireLink)message); break; case CommandSet.DeliverSm: _recvDeliverSm((SMPPDeliverSm)message); break; case CommandSet.Unbind: await _recvUnbind((SMPPUnbind)message); break; case CommandSet.GenericNack: case CommandSet.BindReceiverResp: case CommandSet.BindTransceiverResp: case CommandSet.BindTransmitterResp: case CommandSet.SubmitSmResp: case CommandSet.EnquireLinkResp: case CommandSet.UnbindResp: _activeRequests.CompleteResp(message); break; default: throw new NotImplementedException("No handler for " + message.Command); } } } } catch (Exception err) { if (_isRunning) { _setFailed(err); } _activeRequests.ConnectionDown(); } }
public ActiveRequest(SMPPMessage message) { Message = message; TimeoutTicks = 15; TaskCompletion = new TaskCompletionSource <SMPPMessage>(); }
public async Task ConnectAsync() { // Init lock (this) { if (_state != ConnectionState.Closed) { throw new SMPPException("SMPPConnection busy."); } _tcpClient = new TcpClient(); _sendLock = new TaskLock(); _error = null; _sequence = 1; } Exception error = null; // Connect to SMPP server try { Stream stream; using (new System.Threading.Timer((object state) => { lock (this) { if (_state == ConnectionState.Connecting || _state == ConnectionState.SslHandshake) { error = new TimeoutException("Timeout"); _tcpClient.Close(); } } }, null, 15 * 1000, System.Threading.Timeout.Infinite)) { _setState(ConnectionState.Connecting); await _tcpClient.ConnectAsync(Hostname, Port); stream = _tcpClient.GetStream(); if (Tls) { _setState(ConnectionState.SslHandshake); SslStream sslStream = new SslStream(stream, true); await sslStream.AuthenticateAsClientAsync(Hostname); stream = sslStream; } } lock (this) { if (error != null) { throw error; } _setState(ConnectionState.StreamConnected); _stream = stream; } } catch (Exception err) { if (err is ObjectDisposedException || err is NullReferenceException) { lock (this) { if (error != null) { err = error; } else if (_state == ConnectionState.Closed) { err = new SMPPException("Connect aborted by close."); } } } err = _setFailed(new SMPPException("Connect failed.", err)); Close(); throw err; } // Start comtask Task _ = _run(); // Bind try { _setState(ConnectionState.Binding); SMPPMessage response = await _submitMessage(Bind); if (response.Status != CommandStatus.ESME_ROK) { throw new SMPPException("Response from server " + response.Status + "."); } _setState(ConnectionState.Connected); _enquirePoll = EnquirePoll; } catch (Exception err) { throw _setFailed(new SMPPException("Bind failed", err)); } }