anchor.diff:          [{host, HostName},
           {port, Port},
           {logger, warning},
  -        {reconnect, {4, 60, 3}},
           {keepalive, 0}],
           auth_args(ConnUri, Conn),
           ssl_args(ConnUri, Conn)
       ]),
       % initially use MQTT 3.1.1
  -    {ok, C} = emqttc:start_link([{proto_ver, 4} | CArgs]),
  -    {ok, #state{cargs=CArgs, phase=connect311, mqttc=C, subscribe=Sub,
  -        published=prepare_filling(Pub), consumed=prepare_matching(Cons)}}.
  +    {ok, connect(attempt311, #state{cargs=CArgs, connect_count=0, subscribe=Sub,
  +        published=prepare_filling(Pub), consumed=prepare_matching(Cons)})}.
   
   % Microsoft Shared Access Signature
   auth_args({_Scheme, _UserInfo, HostName, _Port, _Path, _Query},
  
positive.code: 
  -include("lorawan.hrl").
  
  -record(state, {cargs, phase, mqttc, ping_timer, subscribe, published, consumed}).
  
  start_link(ConnUri, Conn) ->
      gen_server:start_link(?MODULE, [ConnUri, Conn], []).
  
negative.code: code_change(_OldVsn, State, _Extra) ->
      {ok, State}.
  
  handle_reconnect(Error, Phase, #state{ping_timer=Timer} = State) ->
      maybe_cancel_timer(Timer),
      handle_reconnect0(Error, Phase, State#state{mqttc=undefined, ping_timer=undefined}).
  
  handle_reconnect0(Error, Phase, #state{phase=OldPhase, last_connect=Last, connect_count=Count} = State) ->
      lager:debug("Connector ~w ~w reconnect ~B", [OldPhase, Error, Count]),
      case calendar:datetime_to_gregorian_seconds(calendar:universal_time())
              - calendar:datetime_to_gregorian_seconds(Last) of
          Diff when Diff < 30, Count > 120 ->
              % give up after 2 hours
              {stop, Error, State};
          Diff when Diff < 30, Count > 0 ->
              % wait, then wait even longer, but no longer than 30 sec
              timer:send_after(erlang:min(Count*5000, 30000), {connect, Phase}),
              {noreply, State#state{connect_count=Count+1}};
          Diff when Diff < 30, Count == 0 ->
              % initially try to reconnect immediately
              {noreply, connect(Phase, State#state{connect_count=1})};
          true ->
              {noreply, connect(Phase, State#state{connect_count=0})}
      end.
  
  connect(Phase, #state{cargs=CArgs} = State) ->
      {ok, C} = connect0(Phase, CArgs),
      State#state{phase=Phase, mqttc=C, last_connect=calendar:universal_time()}.
  
  connect0(attempt31, CArgs) ->
      emqttc:start_link([{proto_ver, 3} | CArgs]);
  connect0(attempt311, CArgs) ->
      emqttc:start_link([{proto_ver, 4} | CArgs]).
  
  handle_connect(#state{subscribe=undefined}=State) ->
      {noreply, State#state{phase=connected}};
  