func handleCollectedUplink(ctx context.Context, uplinkFrame gw.UplinkFrame, rxPacket models.RXPacket) error {
	var uplinkIDs []uuid.UUID
	for _, p := range rxPacket.RXInfoSet {
		uplinkIDs = append(uplinkIDs, helpers.GetUplinkID(p))
	}

	log.WithFields(log.Fields{
		"uplink_ids": uplinkIDs,
		"mtype":      rxPacket.PHYPayload.MHDR.MType,
		"ctx_id":     ctx.Value(logging.ContextIDKey),
	}).Info("uplink: frame(s) collected")

	// update the gateway meta-data
	if err := gateway.UpdateMetaDataInRxInfoSet(ctx, storage.DB(), rxPacket.RXInfoSet); err != nil {
		log.WithError(err).Error("uplink: update gateway meta-data in rx-info set error")
	}

	// log the frame for each receiving gateway.
	if err := framelog.LogUplinkFrameForGateways(ctx, ns.UplinkFrameLog{
		PhyPayload: uplinkFrame.PhyPayload,
		TxInfo:     rxPacket.TXInfo,
		RxInfo:     rxPacket.RXInfoSet,
	}); err != nil {
		log.WithFields(log.Fields{
			"ctx_id": ctx.Value(logging.ContextIDKey),
		}).WithError(err).Error("uplink: log uplink frames for gateways error")
	}

	// handle the frame based on message-type
	switch rxPacket.PHYPayload.MHDR.MType {
	case lorawan.JoinRequest:
		return join.Handle(ctx, rxPacket)
	case lorawan.RejoinRequest:
		return rejoin.Handle(ctx, rxPacket)
	case lorawan.UnconfirmedDataUp, lorawan.ConfirmedDataUp:
		return data.Handle(ctx, rxPacket)
	case lorawan.Proprietary:
		return proprietary.Handle(ctx, rxPacket)
	default:
		return nil
	}
}
The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.