@Override
  public void start() throws SmppChannelException {
    if (isDestroyed()) {
      throw new SmppChannelException("Unable to start: server is destroyed");
    }
    try {
      ChannelFuture f = this.serverBootstrap.bind(new InetSocketAddress(configuration.getPort()));

      // wait until the connection is made successfully
      boolean timeout = !f.await(configuration.getBindTimeout());

      if (timeout || !f.isSuccess())
        throw new SmppChannelException(
            "Can't bind to port "
                + configuration.getPort()
                + " after "
                + configuration.getBindTimeout()
                + " milliseconds");

      logger.info("{} started on SMPP port [{}]", configuration.getName(), configuration.getPort());
      serverChannel = f.channel();
    } catch (ChannelException e) {
      throw new SmppChannelException(e.getMessage(), e);
    } catch (InterruptedException e) {
      throw new SmppChannelException(e.getMessage(), e);
    }
  }
 @Override
 public void stop() {
   if (this.channels.size() > 0) {
     logger.info(
         "{} currently has [{}] open child channel(s) that will be closed as part of stop()",
         configuration.getName(),
         this.channels.size());
   }
   // close all channels still open within this session "bootstrap"
   this.channels.close().awaitUninterruptibly();
   // clean up all external resources
   if (this.serverChannel != null) {
     this.serverChannel.close().awaitUninterruptibly();
     this.serverChannel = null;
   }
   logger.info("{} stopped on SMPP port [{}]", configuration.getName(), configuration.getPort());
 }
  @Override
  public void destroy() {
    this.bindTimer.cancel();
    stop();

    // Shut down all event loops to terminate all threads.
    bossGroup.shutdownGracefully();
    workerGroup.shutdownGracefully();

    try {
      // Wait until all threads are terminated.
      bossGroup.terminationFuture().sync();
      workerGroup.terminationFuture().sync();
    } catch (InterruptedException e) {
      // is ok
    }

    this.serverBootstrap = null;
    unregisterMBean();
    logger.info("{} destroyed on SMPP port [{}]", configuration.getName(), configuration.getPort());
  }