anchor.diff:          {error, Error} -> {error, Error}
       end.
   
  -check_lost(0, DevAddr) ->
  +retransmit_downlink(DevAddr) ->
       case mnesia:dirty_read(pending, DevAddr) of
  -        [] -> {false, undefined};
  -        [Msg] -> {true, Msg#pending.phypayload}
  -    end;
  -check_lost(1, DevAddr) ->
  -    ok = mnesia:dirty_delete(pending, DevAddr),
  -    {false, undefined}.
  +        [] ->
  +            {false, undefined};
  +        [Msg] ->
  +            {true, Msg#pending.phypayload}
  +    end.
  +
  +repeat_downlink(DevAddr, ACK) ->
  +    case mnesia:dirty_read(pending, DevAddr) of
  +        [] ->
  +            {false, undefined};
  +        [#pending{confirmed=true} = Msg] when ACK == 0 ->
  +            {true, Msg#pending.phypayload};
  +        [_Msg] ->
  +            ok = mnesia:dirty_delete(pending, DevAddr),
  +            {false, undefined}
  +    end.
   
   inc_fcntdown(DevAddr) ->
       mnesia:transaction(fun() ->
  
positive.code: 
  store_adr(Link, ADR) -> Link#link{adr_flag_use=ADR}.
  
  store_rxpk(Gateway, Link, RxQ, FCnt, _Data) ->
      % store #rxframe{frid, mac, rssi, lsnr, region, freq, datr, codr, devaddr, fcnt, devstat}
      mnesia:dirty_write(rxframes, #rxframe{frid= <<(erlang:system_time()):64>>,
          mac=Gateway#gateway.mac, rssi=RxQ#rxq.rssi, lsnr=RxQ#rxq.lsnr,
          region=Link#link.region, freq=RxQ#rxq.freq, datr=RxQ#rxq.datr, codr=RxQ#rxq.codr,
          devaddr=Link#link.devaddr, fcnt=FCnt, devstat=Link#link.devstat}),
      ok.
  
  handle_rxpk(Gateway, RxQ, MType, Link, ADRACKReq, ACK, FOptsOut, Port, Data)
          when MType == 2#010; MType == 2#100 ->
      <<Confirm:1, _:2>> = <<MType:3>>,
      handle_uplink(Gateway, RxQ, Confirm, Link, ADRACKReq, ACK, FOptsOut, Port, Data).
  
  handle_uplink(Gateway, RxQ, Confirm, Link, ADRACKReq, ACK, FOptsOut, Port, Data) ->
      % will transmit in the RX2 window
      TxQ = lorawan_mac_region:rx2_rf(Link#link.region, RxQ),
      % check whether last transmission was lost
      {LastLost, LostFrame} = check_lost(ACK, Link#link.devaddr),
      % check whether the response is required
      ShallReply = if
          Confirm == 1 ->
  
negative.code:             % strict 16-bit (default)
              case fcnt_gap16(L#link.fcntup, FCnt) of
                  N when N < ?MAX_FCNT_GAP ->
                      {ok, new, L#link{fcntup = FCnt}};
                  _BigN ->
                      {error, {fcnt_gap_too_large, DevAddr, FCnt}}
              end
  